




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
任务3.3独立按键的实现任务3.3独立按键3.3.1任务介绍在数字钟中有四个独立按键,功能分别是调整、加、减、确定,用以调整系统的时间。在单片机系统中,键盘是基本和常用的接口,它是构成人机对话通话的一种常用方式,实现向单片机系统输入数据、传送命令等功能,是人工干预、设置和控制系统运行的主要手段。本节的任务要求:利用开发板上的四个按键,配合任务3.2数码管显示程序,实现数字钟的调时,为了简化程序,用3个LED的亮灭来代替对应数码管的闪烁(数码管的闪烁在这里有些难)。正常走时,3个LED都不点亮,当按下“调整”键时,“小时”对应的LED点亮,再次按下“调整”键,则“分”对应的LED点亮,然后再按下“调整”键,则“秒”对应的LED点亮,依次循环,直到按下“确定”键,三个LED返回到不点亮的状态。当按下“调整”键后,按下“加”或者“键”按键,则对应的数码管的显示值每次加1或者减1。3.3.2知识准备1、轻触按键的认识键盘分为编程键盘和非编程键盘。键盘上闭合键的识别由专用的硬件编码器来实现的为编程键盘,如计算机键盘;闭合键的识别由软件来实现的为非编程键盘,轻触按键属于非编程键盘。轻触按键具有结构简单,使用灵活等特点,因此被广泛应用于单片机系统中。图3.3.1所示的是市面常见的轻触按键,从封装来区分,有贴片的,也有直插的;从引脚的数量来区分,有2个引脚的,也有4个引脚的。开发板上使用的按键时4引脚直插按键,尺寸为6×6×5,如图3.3.2所示。图3.3.3各种形状的按键图3.3.2开发板使用的按键2、按键的硬件电路和识别方法图3.3.3是轻触按键的内部结构图,按键的4个引脚两两连通(可以用万用表测量),不连通的引脚,当按键被按下时,在金属弹片和反作用弹簧的作用下也会连通,当按键释放后,弹簧不起作用,引脚不连通。图3.3.3轻触按键内部结构图3.3.4轻触按键的接口电路图3.3.4是轻触按键的单片机接口电路,按键一端接地,另外一端接I/O口,同时通过上拉电阻接电源(上拉电阻大小5K~10K)。简单分析一下按键检测的原理:当按键没有按下的时候,单片机I/O通过上拉电阻R接到VCC,我们在程序中读取该I/O的电平的时候,其值为1(高电平);当按键按下的时候,该I/O被短接到GND,在程序中读取该I/O的电平的时候,其值为0(低电平)。这样,按键的按下与否,就和与该按键相连的I/O的电平的变化相对应起来。结论:我们在程序中通过检测到该I/O口电平的变化与否,即可以知道按键是否被按下,从而做出相应的响应。3、检测按键按下按键的检测原理看起来比较简单,我们按照上述的原理先试着写一段任务中的程序看看运行效果怎么样。程序实现的内容为:百位数内的计数器,,按键每按下一次,计数器加1,将计数器的值显示在开发板的两位数码管上。程序如下:#incldue<reg52.h>#incldue<reg52.h>#defineucharunsignedchar#defineuintunsignedintsbitKeyInput=P1^0;//按键接口//段码ucharcodeSeg7Code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};ucharcodeSeg7Posit[]={0xfe,0xfd};//位码ucharDispBuffer[2]; //缓冲区////voidDelayMs(uintxms)ms级延时函数,省略//voidSeg7Display()2位数码管显示函数,省略voidmain(void){ ucharDispCnt=0;//按键加1计数器 while(1) {Seg7Display(); //动态扫描 if(KeyInput==0)//检测到按键按下 { DispBuffer[0]=DispCnt/10;DispBuffer[1]=DispCnt%10;//计数值的个位和十位的分解 if(++DispCnt>=100)//每按一次,计数器加1,超过99,归0 DispCnt=0; } }}程序编译好后烧录到单片机中,看一下运行效果。上电后,数码管显示“00”,按一下按键,数码管向上加数,但是每按一下,向上加好几个数,如果按键不弹起,会连续加1,程序中没有实现我们想要的按一下加1的效果。我们回到刚才编写的程序中,在大循环while(1)中,不停的监测按键是否按下,如果按下则加1,逻辑是正确的。按键按下到按键释放大约需要0.2秒到0.5秒,而程序扫描的速度非常快,按键每按下一次,程序中已经扫描多次了,所以才会出现上述的现象。怎样才能实现按键每按一次加1的效果呢?4、等待按键释放我们在之前按键检测程序上结尾加这样一条语句:While(!key_value);编译后烧录到单片机中,就可以实现按一次按键加1的效果了。if(if(KeyInput==0)//检测到按键按下{DispBuffer[0]=DispCnt/10;DispBuffer[1]=DispCnt%10; if(++DispCnt>=100)//每按一次,计数器加1,超过99,归零 DispCnt=0; While(!KeyInput);//如果按键没有弹起,程序指针就会停在这里,} //直到按键释放}While(!key_value);这个语句是怎么消除了按一下加多个数的问题呢?程序中初次检测到了按键按下,则执行数值分解语句和加1语句,最后执行While(!key_value);按键按下后,key_value的值为0,取反后,为1,则while语句的条件为真,程序指针会停在这里,不停的检测按键是否释放,按键释放后,key_value的值变为1,取反后变为0,条件为假,程序指针向下执行。这样实现了按下一次加1的效果了。如果不停的按下按键,我们会发现,大多数按下的时候会加1,但有的时候还是会出现按一下加几个数的现象,这又是什么原因造成的呢?5、按键消抖动按键的开关为机械弹性触点开关,它是利用机械点接触和分离实现电路的通断。由于机械点的弹性作用,加上人们按键时的力度、方向的不同以,按键开关从按下到接触稳定要经过数毫秒的弹跳抖动,即在按下的几十毫秒里会连续产生多个脉冲。释放按键时,电路也不会一下断开,同样会产生抖动。这两次抖动的时间分别为10-20ms左右,而按键的稳定闭合通常大于0.3-0.5秒。因此,为了确保MCU对一次按键动作只确认一次,按键闭合时,必须要进行消抖处理。否则由于MCU执行的速度较快,会将抖动的多个脉冲误认为为多次的按键。图3.3.5是按键按下抖动示意图。
图3.3.5按键按下抖动示意图按键的消抖动既可以采用硬件方法,也可以采用软件的方法。使用硬件消抖的方式,需要在按键连接的硬件设计上增加硬件消抖电路,如RS触发器或者RC积分电路等。采用硬件消抖方式增加了系统的成本,而利用软件方式消抖则是比较经济的做法,但增加了软件设计的复杂性。软件方式消抖的基本原理是在软件中对按键进行两次确认,既在第一次检测到按键按下后,间隔10ms左右再次检测该按键是否按下,只有两次都检测到按键按下时才最终确认有键按下,从而跳过了按键的抖动,消除了抖动的影响。程序如下:if(if(KeyInput==0)//检测到按键按下{DelayMs(10); //延时消抖 if(KeyInput==0) //再次检测按键是否按下 { DispBuffer[0]=DispCnt/10;DispBuffer[1]=DispCnt%10; if(++DispCnt>=100)//每按一次,计数器加1,超过 DispCnt=0; while(!KeyInput);//等待按键释放 }} } 检测按键按下,10ms消抖,等待按键弹起,称之为按键检测三部曲,但本节教程的程序仅能作为功能演示用,在实际项目中有很大的弊端,第4单元任务1给出了按键高效扫描方法。3.3.2任务实施 本节的任务实现程序如下:include<reg52.h>include<reg52.h>#defineucharunsignedchar#defineuintunsignedint//按键接口sbitKeyInput1=P2^0;//“调整”键sbitKeyInput2=P2^1;//“增减”键sbitKeyInput3=P2^2;//“减少”键sbitKeyInput4=P2^3;//“确定”键//状态灯sbitLedHour=P3^0;sbitLedMinute=P3^1;sbitLedSecond=P3^2;//段码ucharcodeSeg7Code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};ucharcodeSeg7Posit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位码ucharDispBuffer[6];//缓冲区///ms级延时函数voidDelayMs(uintxms){ uinti,j; for(i=0;i<xms;i++) for(j=0;j<122;j++);}//6位数码管显示子函数,在第二位和第四位上显示小数点voidSeg7Display(){ uchari; for(i=0;i<6;i++) { P1=0xff; //消隐 P0=Seg_7[DispBuffer[i]];//送段码 if((i==1)||(i==3))P0&=~0x80; //在第二位和第四位数码管上加小数点 P1=Posit[i]; //送位选 DelayMs(1); //延时 }}//主函数voidmain(void){ucharCnt;//时间计数器 ucharHour=9; //“小时”初值ucharMinute=23; //“分”初值 ucharSecond=37; //“秒”初值ucharKeyValue=0;//按键值 ucharAdjustNum=0;//按下“调整”按键时对应的调整值LedHour=LedMinute=LedSecond=1;//三个状态灯初始时都不点亮while(1) {KeyValue=GetKeyValue();//检测按键是否按下,并返回键值if(KeyValue==0x01)//按下确定键,进入到调整界面{if(++AdjustNum>=4)//AdjustNum的取值为1、2、3AdjustNum=1;//分别对应"小时"、"分"、"秒"//把时间送入缓冲区//把时间送入缓冲区voidTimeToBuff(ucharnhour,nminute,nsecond){ DispBuffer[0]=nhour/10; DispBuffer[1]=nhour%10;//小时的个位和十位的分解 DispBuffer[2]=nsecond/10; DispBuffer[3]=nsecond%10;//分的个位和十位的分解DispBuffer[4]=nminute/10; DispBuffer[5]=nminute%10;//秒的个位和十位的分解}//检测是否有按键按下ucharKeyScan(){uchartemp;if(KeyInput1==0)temp=0x01;//"调整"键按下elseif(KeyInput2==0)temp=0x02;//“加1”键按下elseif(KeyInput3==0)temp=0x03;//"减1"键按下elseif(KeyInput4==0)temp=0x04;//“确定”键按下elsetemp=0xff;//没有按键按下,返回0xffreturntemp;}//依照“按键三部曲”编写的按键检测程序ucharGetKeyValue(){ucharKeyReturn=0x00;//返回值初值为0if(KeyScan()!=0xff)//检测到有按键按下{//延时消抖DelayMs(10);if(KeyScan()!=0xff)//再次检测到有按键按下{KeyReturn=KeyScan();//取键值while(KeyScan()!=0xff);//等待按键弹起}}returnKeyReturn;}if(AdjustNum==1)//点亮"小时"对应的LED{LedHour=0;LedMinute=LedSecond=1;}if(AdjustNum==2)//点亮"分"对应的LED{LedMinute=0;LedHour=LedSecond=1;}if(AdjustNum==3)//点亮"秒"对应的LED{LedSecond=0;LedHour=LedMinute=1;}}if(KeyValue==0x02)//按下“增加”按键{if(AdjustNum==1)//小时加1{if(++Hour>=24) Hour=0;}if(AdjustNum==2){//分加1if(++Minute>=60)Minute=0;}if(AdjustNum==3)//秒加1{if(++Second>=60)Second=0;}}if(KeyValue==0x04)//返回正常界面{AdjustNum=0;//状态灯熄灭,把AdjustNum赋值为0LedHour=LedMinute=LedSecond=0;}TimeToBuff(Hour,Second,Minute);//把待显示的值送入缓冲区 Seg7Display(); //动态扫描,1ms×6=6ms if(++Cnt>=166) //Cnt计数83次×12=996ms { Cnt=0; if(++Second>=60) //1秒计数60次,为1分钟 { Second=0; if(++Minute>=60)//1分钟计数60次,为1小时 { Minute=0; if(++Hour>=24) //24小时后清零 Hour=0; } } } }}程序解释如下:程序中加粗的是有关于本节按键程序的,其余部分是上一节中的内容,在这里我们只解释和按键相关的程序。按键的程序分两部分,一部分是按键检测函数,另外一部分是主程序中的键值处理程序。按键检测由两个子函数来完成。KeyScan()和GetKeyValue()。KeyScan()函数完成按键状态的扫描,并返回状态值(temp),temp取值为0x01、0x02、0x03、0x04分别对应4个按键的按下,如果没有按键按下,则temp为0xff。在GetK
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025四川省社会科学院考核招聘专业技术人员9人(第二批次)考试参考题库附答案解析
- 2025辽宁省农业科学院招聘工作人员25人考试参考题库附答案解析
- 吉安市新庐陵投资发展有限公司2025年人才引进“绿色通道”招聘考试参考题库附答案解析
- 2025浙江丽水松阳县“乡村运营师”人才引进1人考试参考题库附答案解析
- 2025上海大学附属嘉定实验学校实习教师招聘笔试备考试题及答案解析
- 2025年烟台长岛综合试验区教育和卫生健康局直属学校公开招聘教师笔试模拟试题及答案解析
- 2025浙江嘉兴市中医医院招聘编外合同制人员9人(第二批)笔试备考试题及答案解析
- 2025浙江大学药学院专职研究员招聘5人考试参考题库附答案解析
- 2025云南玉溪国润建筑有限责任公司招聘工作人员10人笔试模拟试题及答案解析
- 2025浙江杭州市建德市三江生态管理有限公司招聘13人考试参考题库附答案解析
- 2025年四川高校大学《辅导员》招聘考试题库及答案
- 2025-2026学年统编版(2024)初中语文七年级上册教学计划及进度表
- 标准化产品需求文档编写方法
- 办公室文秘岗试题带答案
- 2025年河南疾控中心考试题库
- 2025年高考【数学】真题及答案(新高考Ⅱ卷)
- 养老护理员竞赛理论试卷答案(含答案)
- 2025年广东省广州市中考历史试卷(含解析)
- 2025年四川省能源投资集团有限责任公司人员招聘笔试备考题库及答案详解(新)
- 广东省公路服务区管理系统升级及运维项目
- 2025版《中国系统性红斑狼疮诊疗指南》解读 4
评论
0/150
提交评论