独立按键原理是这样的:按键没按下的时候,相应端口是高电平状态,而当按键按下的时候,相应的端口则是低电平。所以可以根据这个现象,实现相应的功能。
还有一点应该注意的是:按键在闭合和断开时,触点会存在抖动现象。
在实际情况下,我们需要的是稳定闭合的那部分状态。所以可以采用延时的方法来解决这个问题,具体的过程就是先看看有没有键按下,有键按下了,再延迟一段时间,再看看有没有键按下,
这时候如果还是有键按下的话那就真的是有键按下了。
而这个抖动的时间大概是10ms,所以只要用一个延时10ms的子函数就行。
上面代码的第66行那个判断按键是否松开也是必要的,虽然在这个程序中有和没有区别不大,但是在有的程序中加入要求按键松开之后才出现什么现象之类的东西的话,那这部分就显得必要了。
/*******************************************************************************
实验名称: 8个独立按键控制8盏LED灯(按下哪个键,那个键对应的LED亮)
实验时间:
*******************************************************************************/
#include #define LED_KEY P0 //LED灯用P0口 #define IO_KEY P1 //独立按键用P1口 void Delay(); //延时函数 unsigned char Key_Scan(); //获取按键值 void main() { unsigned char Key_Value, LED_Value; while(1) { Key_Value = Key_Scan(); switch(Key_Value) { case(0xFE): //K1按下 LED_Value = 0x01; break; case(0xFD): //K2按下 LED_Value = 0x02; break; case(0xFB): //K3按下 LED_Value = 0x04; break; case(0xF7): //K4按下 LED_Value = 0x08; break; case(0xEF): //K5按下 LED_Value = 0x10; break; case(0xDF): //K6按下 LED_Value = 0x20; break; case(0xBF): //K7按下 LED_Value = 0x40; break; case(0x7F): //K8按下 LED_Value = 0x80; break; default: break; } LED_KEY = LED_Value; //点亮相应LED } } unsigned char Key_Scan() { unsigned char Key_Value,i; if(IO_KEY != 0) { Delay(); //消除抖动 if(IO_KEY != 0xFF) { Key_Value = IO_KEY; i = 0; if((i<50)&&(IO_KEY != 0xFF)) //判断按键是否松开 { Delay(); i++; } } } return Key_Value; } void Delay() //延迟10ms { unsigned char a,b,c; for(c=1;c>0;c--) { for(b=38;b>0;b--) { for(a=130;a>0;a--) {}; } } } /******************************************************************************* *实验名称 :按键控制LED左右移 *实验时间 *******************************************************************************/ #include #include //--定义要使用的IO口--// sbit K1 = P1^0; //对应按钮K1 sbit K2 = P1^1; //对应按钮K2 #define LED_KEY P0 //LED使用P0口 //--定义全局函数--// void Delay10ms(unsigned int c); //延时10ms unsigned char Key_Scan(); /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 *******************************************************************************/ void main(void) { unsigned char ledValue, keyNum; ledValue = 0x01; while (1) { keyNum = Key_Scan(); //扫描键盘 if (keyNum == 1) //如果键值返回1 { ledValue = _crol_(ledValue, 1); //左循环 } else if (keyNum == 2) { ledValue = _cror_(ledValue, 1); //右循环 } LED_KEY = ledValue; //点亮LED灯 } } /******************************************************************************* * 函 数 名 : Key_Scan() * 函数功能 : 扫描键盘 *******************************************************************************/ unsigned char Key_Scan() { unsigned char keyValue = 0 , i; //保存键值 //--检测按键1--// if (K1==0) //检测按键K1是否按下 { Delay10ms(1); //消除抖动 if (K1==0) //再次检测按键是否按下 { keyValue = 1; i = 0; while ((i<50) && (K1==0)) //检测按键是否松开 { Delay10ms(1); i++; } } } //--检测按键2--// if (K2==0) //检测按键K1是否按下 { Delay10ms(1); //消除抖动 if (K2==0) //再次检测按键是否按下 { keyValue = 2; i = 0; while ((i<50) && (K2==0)) //检测按键是否松开 { Delay10ms(1); i++; } } } return keyValue; //将读取到键值的值返回 } /******************************************************************************* * 函 数 名 : Delay10ms * 函数功能 : 延时函数,延时10ms *******************************************************************************/ void Delay10ms(unsigned int c) //误差 0us { unsigned char a, b; //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--// for (;c>0;c--) { for (b=38;b>0;b--) { for (a=130;a>0;a--); } } }
上一篇:单片机入门 - 模电、数电与单片机
下一篇:51单片机入门 - 学习笔记
推荐阅读最新更新时间:2024-11-12 06:58
推荐帖子
- [好书]像500强一样经营自己
- 像500强一样经营自己------一本很好的书像500强一样经营自己坐沙发看书喽,呵呵回复:像500强一样经营自己好书!谢谢楼主!!对当代大学生很有帮助啊回复:像500强一样经营自己下载了,正在看,谢谢喽回复:像500强一样经营自己谢谢,看看回复:像500强一样经营自己谢谢.楼主咯!回复:像500强一样经营自己好书!谢谢!回复:像500强一样经营自己好书.看看回复:像500强一样经营自己很有用哦回复:像500强一样经
- SuperStar515 嵌入式系统
- EP9315GPIO驱动在镜像中无法被加载!
- 为什么我写的驱动编译通过了,做成镜像后,在wince启动时,DWORDGIO_Init(DWORDdwcontext)无法被加载,反而只有DllEntry()些函数在超级终端上看得到办出输出信息!EP9315GPIO驱动在镜像中无法被加载!一般应该是你的驱动已经退出造成的,在你的dllentry函数退出部分添加打印信息验证一下!造成这种结果的可能原因是你的init函数返回值或者参数有问题那我把源码贴出,请帮忙看看啊,各位高手!#includewindows.h#in
- lvtian2 嵌入式系统
- 5G 手机的发射功率,到底能有多大?
- 随着5G网络的建设,5G基站成本高,尤其是能耗大的问题已广为人知。以中国移动为例,为了下行支持高速率,其2.6GHz的射频模块就要求64通道,最大320瓦发射功率。而与基站通信的5G手机,由于和人体的接触过于密切,「辐射危害」的底线必须严防死守,因此只能戴着镣铐起舞,发射功率严格受限。4G手机的发射功率,就被协议限制为最大23dBm(0.2瓦),这个功率虽说不大,但4G的主流频段(FDD1800MHz)频率较低,传播损耗相对较小,用起来倒也问题不大
- zqy1111 RF/无线
- 关于无线通信不同应用中,通信层协议的问题求助!
- 各位大神,本人主要是做应用层设计开发的。暂时没有打算直接对无线低层芯片进行开发。计划采购现成的无线模块(UHF、Zigbee、Lora等),配合自家的采集模块,构成无线传感网的不同应用。现在的问题就是,有线传感网的软件层协议通常有的选择,如标准的(485-ModbusRTU协议)、SDI-12协议,属于应答模式。当实现无线传感网应用时,如果沿用上面两种协议有个缺点就是传感端必须保持常供电,实时等待主站端发过来的命令,这在户外应用要求低功耗的情况下显然不行。如果考虑到低功耗问题,比较好的方式
- yunyinliu RF/无线
- Zynq-7000应用处理单元(转)
- 转自http://www.ituring.com.cn/tupubarticle/3348Zynq-7000应用处理单元是该器件最重要的功能单元。只有掌握了应用处理单元的结构原理,才能高效地实现基于Zynq-7000的嵌入式系统设计。3.1 应用处理单元应用处理单元(ApplicationProcessingUnit,APU)存在于PS内,包含带有NEON协处理器的两个Cortex-A9处理器。在多处理器配置中,将两个处理器连接起来共享一个512KBL2高速缓存。每个处理器是
- 白丁 FPGA/CPLD
- Altium Designer 24.9.1 版
- 新功能说明 版本发布说明AltiumDesigner24.9.1版哈哈,还没有用,我打算先用一下,感觉AD还是蛮简单的,但是也就是小厂用用 使用AD的工程师很多 看一下千古更新帝啊,更新频率真快!不知改善了什么,又带出什么新BUG看看版本发布说明的是什么发的是什么?看看学习学习更新的好快呀。。。。。。。。。。。。。。。。是干事业的样子。更新的好快呀。。。。。。。。。。。。软件能下载吗?
- dcexpert PCB设计
设计资源 培训 开发板 精华推荐
- LTC3718 的典型应用 - 用于 DDR/QDR 存储器终端的低输入电压、DC/DC 控制器
- 黄淮学院创客空间立创杯电子设计大赛-尹本行-1002434A
- LT1110CS8 闪存 VPP 发生器的典型应用电路
- AKD4104-A,AK4104 数字音频接口发射器评估板 - DIT
- TOF激光测距仪
- 【牡丹江师范学院】乌龟的贴心小管家
- AM2G-1218SH30Z 18V 2瓦直流/直流转换器的典型应用
- A5974AD 的典型应用 适用于汽车应用的高达 2 A 的降压开关稳压器
- 【立创开发板】梁山派RoboMaster扩展板
- RP503N 应用电路,采用 SOT23 封装的 DC-DC 降压转换器