按键的基础编程
FMC编程基础·常用控件

MFC编程基础————常用控件一、编辑框增加响应,在编辑框输入文字,点确定,有反应1.关联编辑框的成员变量2.添加按钮的响应函数(双击按钮)void CEx040105aDlg::OnOK(){CDialog::OnOK();CString strMess ;strMess.Format("你输入的数是%d\n",m_iIntvalue);AfxMessageBox(strMess);}二、数字滚选按钮在包含数字的变量控件旁边添加可以控制数字仅仅勾选即可,需勾选样式属性栏1、自动结伴(auto buddy)2、设置结伴整数(set buddy integer)三、按钮按键双击按钮,添加函数四、列表框1、增加一个ClistBox关联,变量名m_nameListBox2、在初始化函数中初始ListBox。
{……// TODO: Add extra initialization hereint nItem = m_nameListBox.AddString("张三");m_nameListBox.SetItemData(nItem,3);//3 is IDnItem = m_nameListBox.AddString("张三1");m_nameListBox.SetItemData(nItem,5);nItem = m_nameListBox.AddString("张三2");m_nameListBox.SetItemData(nItem,7);return TRUE;// return TRUE unless you set the focus to a control }3、为ListBox 增加LBN_SELCHANGE消息的响应函数:void CEx040105aDlg::OnSelchangeList1(){// TODO: Add your control notification handler code hereint nSel = m_nameListBox.GetCurSel();if(-1!= nSel){CString strName;m_nameListBox.GetText(nSel,strName);UINT uID = m_nameListBox.GetItemData(nSel);CString strMess;strMess.Format("你选了%s, ID是%u",strName, uID);AfxMessageBox(strMess);}}五、复选框和单选框1、单选框属性,勾选群组(group),关联第一个单选框如:m_iSel。
可编程按键设定

示教器可编程按键的设定在示教器上可编程按键实物图如图4-5所示。
可编程按键的作用示教器可编程操作按键,给可编程按键分配控制的I/O 信号,以方便对I/O 信号进行强制与仿真操作。
将数字输入信号与系统的控制信号关联起来,就可以对系统进行控制(例如电机开启、程序启动等)。
系统的状态信号也可以与数字输出信号关联起来,将系统的状态输出给外围设备,以作控制之用。
系统输入/输出与I/O 信号关联的操作步骤可编程操作按键1配置数字输出信号DO1 的操作步骤如表4-20所示。
表4-20可编程操作按键1配置数字输出信号DO1 的操作步骤操作界面选择“配置可编程按键”图4-5 示教器可编程操作按键可编程按键1可编程按键2可编程按键3可编程按键4①②在类型中,选择“输出”完成以上设置后,此时通过可编程按键1在手动状态下对“motoron ”进行强制操作。
当按下可编程按键1,电机开启;当再次按下可编程按键1,电机关闭。
知识拓展在实训平台上,可编程按键分别与气源控制的数字输出信号相关联,可编程按键的配置如表4-21所示。
当按下可编程按键1时,变位机气缸处于夹紧状态,再次按下可编程按键1时,变位机气缸处于松开状态。
当按下可编程按键2时,夹爪处于夹紧状态,再次按下可编程按键2时,夹爪处于松开状态。
当按下可编程按键3时,吸取工装。
当按下可编程按键4时,吸盘吸取物料,再次按下可编程按键4时,吸盘释放物料。
③④⑤⑥表4-21可编程按键的配置操作界面可编程按键的可编程按键可编程按键的可编程按键。
矩阵键盘的编程方法——读取键值

矩阵键盘的编程⽅法——读取键值矩阵键盘的使⽤在单品机的学习当中⼗分⼴泛,可是对于许多新⼿,包括本⼈有时也是搞不明⽩,昨天晚上和今天早上的思考和同⾏们的讨论,终于有了点头绪,所以想记录下读取键盘的思路。
在单⽚机的学习版中,矩阵键盘通常如下图设计:下⾯就以按下S16键来讲解其思路:⾸先:P3的⾼位P3.4~P3.7输出为0,低位P3.0~P3.3输出为1;即P3=0x0F,当按下S16键后(有消抖动过程),P3.3的值为0,则P3的值更新为0x07;其次:P3的⾼位P3.4~P3.7输出为1,低位P3.0~P3.3输出为0;即P3=0xF0,当按下S16键后(有消抖动过程),P3.4的值为0,则P3的值更新为0xE0;最后将两个值相加得P3=0xE7;在keyscan()函数(假设我们的键盘扫描程序为unsigned char keyscan())返回其键盘的值供后续的程序调⽤,通常会有⼀个switch块根据其返回值来确定输出的是哪⼀个数值。
下⾯提供⼀段KeilC51语⾔的代码来解释⼀下:1. /*------------------------------------------------2. 键盘扫描程序3. ------------------------------------------------*/4. uchar keyscan( void ) //键盘扫描函数,使⽤⾏列反转扫描法5. {6. uchar cord_h,cord_l;//⾏列值中间变量7. P3 = 0x0f; //⾏线输出全为08. cord_h = P3 & 0x0f; //读⼊列线值9. if( cord_h != 0x0f ) //先检测有⽆按键按下10. {11. delay( 100 ); //去抖12. if( cord_h != 0x0f )13. {14. cord_h = P3 & 0x0f; //读⼊列线值15. P3 = cord_h | 0xf0; //输出当前列线值16. cord_l = P3 & 0xf0; //读⼊⾏线值17. return( cord_h + cord_l );//键盘最后组合码值18. }19. }20. return( 0xff ); //返回该值21. }22.⾸先把P3的⼝赋值为0x0f,同时把P3和0x0f赋值给cord_h(⾏的数值),倘若有按键按下,那么P3的值就会改变,随后cord_h的只也会随之变化,经过消抖之后记录cord_h的值,即cord_h = P3 & 0x0f;(若以S16为例,那么P3.3的值变为0,所以cord_h的值就会变为0x07;)接下来:P3 = cord_h | 0xf0;意在不改变P3的第四位,把P3的⾼四位赋为⾼电平,那么P3=0x0f7;到了关键的⼀步:cord_l = P3 & 0xf0;我当初以为cord_l=0xf0呢,结果就和程序运⾏的不⼀样喽,最后还是问了我的同⾏(⾮常感谢刘伟同志!指点迷津!),其实在第⼆个if语⾔内,S16已经被按下了的,所以P3的值⽴刻就变为0x0e的了,以⾄于cord_l=0x0e,最后返回⾏和列的和return( cord_h + cord_l );(0xe7)。
可编程键盘使用方法

可编程键盘使用方法当使用可编程键盘时,有许多方法和技巧可以帮助您更高效地利用它的功能。
以下是50条关于可编程键盘使用方法并展开详细描述:1. 定义自定义快捷键:使用可编程键盘的软件,您可以定义自己的快捷键,例如触发特定应用程序或执行特定功能。
2. 创建宏:通过可编程键盘软件,您可以创建宏,以便一键执行复杂的操作序列,例如输入一段代码、执行一系列操作或者发送一封预定义的电子邮件。
3. 分层编程:一些可编程键盘支持分层编程,即在不同的层次设置不同的功能,可以根据需要进行切换,从而提高按键的多功能性。
4. 键位调整:通过可编程键盘软件,您可以重新映射键位,使得您习惯的键位布局可以在不同键盘上使用。
5. 多设备切换:如果您使用多台电脑或设备,一些可编程键盘可以支持快速切换不同设备,方便您在不同工作环境间进行移动。
6. 文本扩展:通过可编程键盘软件,您可以定义文本缩写和扩展,方便您快速输入常用的短语和段落。
7. 游戏模式:一些可编程键盘有专门的游戏模式,可以通过一键切换来禁用Windows 键或其他会干扰游戏操作的按键。
8. 设置多重触发:一些高级的可编程键盘支持多重触发,即在一个键上设置多种功能,通过单击、双击、长按或其他方式进行不同的响应。
9. 配置LED灯光效果:一些可编程键盘配备了LED灯,可以通过软件对其进行配置,达到个性化的灯光效果。
10. 自定义屏幕显示:一些可编程键盘上配备了OLED屏幕,您可以自定义显示内容,实时显示信息,如CPU温度、系统负载等。
11. 设备管理:在使用多个可编程键盘时,一些软件可以帮助您管理多个设备的配置和设置。
12. 定义特定应用程序的功能:针对特定的软件应用程序,您可以通过可编程键盘软件为其定义特定的快捷功能,提高工作效率。
13. 脚本编程:通过可编程键盘软件支持脚本编程,您可以更加强大地定制键盘功能,并且支持更多复杂的操作。
14. 切换不同的配置文件:对于不同的工作场景,您可以在可编程键盘软件中创建不同的配置文件,并进行快速切换,以应对不同的工作需求。
按键输入程序设计

按键输入程序设计按键输入程序设计是指通过键盘输入数据并在计算机程序中进行相关处理的一种编程设计。
按键输入程序设计广泛应用于各类计算机软件和应用领域,如文字处理、游戏设计、数据输入和处理等。
本文将从按键输入的基本实现原理、常用的按键输入处理方法以及在实际程序设计中的应用三个方面进行详细介绍。
首先,我们来了解按键输入的基本实现原理。
键盘是一种常见的输入设备,在计算机中通过扫描码的方式将按键输入映射为相应的字符或指令。
计算机根据键盘的按键扫描码来判断用户输入的按键,并进行相应的处理。
在现代计算机系统中,按键输入一般由操作系统或应用程序进行处理,通过监听键盘事件来获取按键输入。
在按键输入程序设计中,常用的按键输入处理方法包括轮询、事件驱动和图形用户界面(GUI)等。
1.轮询方式:轮询是一种常用的按键输入处理方式。
程序通过循环不断地检测键盘状态,判断是否有按键按下。
当程序检测到按键按下时,就可以执行相应的操作。
这种方式实现简单,适用于简单的程序,但会占用大量的CPU资源。
2.事件驱动方式:事件驱动是一种高效的按键输入处理方式。
程序通过监听键盘事件,当按键按下时触发相应的事件处理函数。
这种方式相比轮询方式更加高效,可以实现实时响应和并发处理。
3.图形用户界面(GUI)方式:GUI方式是一种基于图形界面的按键输入处理方式。
GUI提供了直观的界面和用户交互方式,通过鼠标和键盘输入实现各种操作。
在GUI方式下,按键输入通过监听相应的事件实现,既可以实现轮询方式,也可以实现事件驱动方式。
在实际的程序设计中,按键输入常常与其他功能和模块相结合,用于实现特定的功能和交互。
下面以一个简单的文字处理程序为例介绍按键输入程序设计的应用。
程序设计的关键步骤如下:1.初始化程序,包括创建图形界面、设置监听键盘事件等准备工作。
3.监听特殊按键事件,如删除键、回车键等。
根据用户的按键输入执行相应的操作,如删除光标前的字符、换行等。
5.程序运行结束时,释放资源、关闭文件等。
机械键盘的按键交换及Macro编程

机械键盘的按键交换及Macro编程机械键盘作为一种高性能输入设备,因其优越的手感和按键稳定性而被广泛用户喜爱。
而在日常使用过程中,通过按键交换和Macro编程,用户可以个性化定制键盘布局和功能,提升使用效率。
本文将为大家介绍机械键盘的按键交换以及Macro编程技术。
一、按键交换1. 为什么需要按键交换在默认的键盘布局中,不同的键位功能可能无法满足个人习惯或特定应用场景的需求。
比如,一些用户可能习惯于使用Mac键盘布局,而某些机械键盘则采用Windows键盘布局。
此时,按键交换就能提供便利,让用户根据自己的习惯重新分配键位功能。
2. 按键交换的方法按键交换可以通过软件或硬件两种方式实现。
在软件层面,一些键盘驱动程序提供了按键映射的功能,用户只需打开驱动软件,调整键位功能即可。
有些键盘甚至配备了自带的软件,提供更加灵活和便捷的按键交换设置。
在硬件层面,某些机械键盘设计了热插拔的按键结构,用户可以自行更换按键的位置,实现按键交换。
这种方式通常需要较高的操作技巧和键盘知识,并且只适用于特定型号的键盘。
二、Macro编程1. Macro编程的作用Macro编程允许用户将一系列操作通过按下一个按键或组合按键的方式来触发,从而提高工作效率。
比如,在文本编辑中,可以通过Macro编程快速插入常用的短语或命令,减少重复输入的操作。
2. Macro编程的方法Macro编程可以通过键盘驱动软件来实现。
首先,用户需要在驱动软件中选择需要录制的按键序列,并设置触发按钮。
然后,在实际操作过程中,用户按下设定的按键触发按钮,驱动软件会记录下键盘输入的序列。
最后,用户可以通过预设的触发按钮重新执行该按键序列,达到快速执行的目的。
需要注意的是,在Macro编程中,用户需要谨慎设置触发按钮,避免与常用操作冲突。
同时,过度依赖Macro编程可能会导致用户的按键记忆力下降,对日常工作产生负面影响。
三、机械键盘的个性化设置除了按键交换和Macro编程,机械键盘还提供了更多的个性化设置,以满足用户的不同需求。
全部模拟104键盘的编程方式

全部模拟104键盘的编程方式
以下方案来实现所有101键盘的按键,同时还包括18个Windows 多媒体键盘的按键。
现在将如何向COM口写入进行说明:
首先设置计算机串口的属性,波特率为9600B/S,数据位8位,停止位1位,无校验位,无硬件握手。
我们设计的时候就要采用通断码的方式,即按下按键发一个码,抬起按键发一个码的方式来实现模拟按键的实现。
如果只是实现按一个按键的时候,只要先向这个串口发这个键的通码,再发断码就可以,比如A键,实际键盘操作是先按下A键再释放A键。
我们先定义如下:A键的通码“1ch”(十六进制)A键的断码“F0h”和“1ch”(两个码)。
因此发送到你的计算机的串口十六进制的数据应该是1ch F0h 1ch 。
考虑到要完全实现键盘的功能,就要涉及到组合键的问题,比如Shift+G,实际键盘操作是先按下Shift键再按下G键,然后释放G键,再释放Shift键。
我们先定义如下:Shift 键的通码“12h”(十六进制)G键的通码“34h” G 键的断码“F0h”和“34h”(两个码)Shift 键的断码“F0h”和“12h” 因此发送到你的计算机的串口十六进制的数据应该是12h 34h F0h 34h F0h 12h 。
所以说向串口发数据的先后顺序和正常操作键盘是一样的。
通码断码要成对,否则就出现常按下一个键不抬起,一直机打的现象。
我们定义所有101及多媒体按键通断码如下(十六进制):
对于~!@#$%^&*()_+|{}:”<>?等键,和键盘一样需要和Shift键组合发送`1234567890-=、[];‘,。
/来实现。
C语言编程与按钮开关的各种用法

软件的作用在于发挥硬件的特性,这是软件编程的宗旨;编程的魅力在于把逻辑问题表达出来,或者牵强的说是把逻辑问题转化为空间问题。
在做C编程的时候,我们考虑的都是逻辑问题,而解决问题的落脚点确实在程序的某个位置加个什么语句,这个“位置”一次应该是属于空间的范畴,逻辑问题的本身是复杂的,语言的魅力就在于不仅能把逻辑问题表达出来,还能给我们提供一个思考讨论的平台。
本文主要讨论的是C语言编程中按键和开关的问题,或者隐身为输入检测。
按键和开关是我们生活中很常见的东西,例如我们的电脑就有键盘,家电都有电源按钮等等。
根据用途、领域、介质等的不同,就有不同的名字,诸如:按键、按钮、键盘、触摸屏、开关等等。
首先是格物致知,在纷繁复杂的实物中,找到他们的本质和规律。
我们可以统归为按键和开关这两类。
按键的本质特性就是按下去就有反映,松开就回复原样,也就是在我们按下去的时间段里有效,在我们看来就像是个脉冲,脉冲的长度就是我们按下去的时间,例如我们的电脑键盘,手机按键等。
开关的本质就是动作之后一直有效,与是否松手无关,直到我们再去操作为止。
看上去更像是一个电平变化,例如我们的自锁开关、闸刀等。
以上都是按键和开关的硬件特性,与具体系统的功能不能一一对应,例如:电脑的键盘的本质应该是按键,打字的时候我们按下一个键,屏幕就会出现相应字符,我们松开时就没有了反映,其有效的时间段是我们按下去的时间。
而当我们用qq播放器看电影的时候,按一下空格键,就会暂停电影的播放,直到我们再去操作才能继续电影的播放。
前者很好理解,而后者就好像是按键实现了开关的功能。
一个系统最后所呈现的功能是有软件和硬件共同决定的,不能以偏概全。
按键和开关的介绍就到这里,总结就是:根据其本质统分为按键和开关,其范畴属于硬件,还没有涉及到软件部分,这和系统的功能没有确定的对应关系,下面介绍相关的软件部分。
在软件范畴来说,就是输入检测问题,检测的最本质就是查看输入是高电平还是低电平,就是去读相关的寄存器,这是软件中距离硬件最近的部分了,也就是硬件在软件中的映射。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
按键程序编写的基础从这一章开始,我们步入按键程序设计的殿堂。
在基于单片机为核心构成的应用系统中,用户输入是必不可少的一部分。
输入可以分很多种情况,譬如有的系统支持PS2键盘的接口,有的系统输入是基于编码器,有的系统输入是基于串口或者USB或者其它输入通道等等。
在各种输入途径中,更常见的是,基于单个按键或者由单个键盘按照一定排列构成的矩阵键盘(行列键盘)。
我们这一篇章主要讨论的对象就是基于单个按键的程序设计,以及矩阵键盘的程序编写。
◎按键检测的原理常见的独立按键的外观如下,相信大家并不陌生,各种常见的开发板学习板上随处可以看到他们的身影。
(原文件名:1.jpg)总共有四个引脚,一般情况下,处于同一边的两个引脚内部是连接在一起的,如何分辨两个引脚是否处在同一边呢?可以将按键翻转过来,处于同一边的两个引脚,有一条突起的线将他们连接一起,以标示它们俩是相连的。
如果无法观察得到,用数字万用表的二极管挡位检测一下即可。
搞清楚这点非常重要,对于我们画PCB的时候的封装很有益。
它们和我们的单片机系统的I/O口连接一般如下:(原文件名:2.jpg)对于单片机I/O内部有上拉电阻的微控制器而言,还可以省掉外部的那个上拉电阻。
简单分析一下按键检测的原理。
当按键没有按下的时候,单片机I/O通过上拉电阻R接到VCC,我们在程序中读取该I/O的电平的时候,其值为1(高电平); 当按键S按下的时候,该I/O被短接到GND,在程序中读取该I/O的电平的时候,其值为0(低电平) 。
这样,按键的按下与否,就和与该按键相连的I/O的电平的变化相对应起来。
结论:我们在程序中通过检测到该I/O口电平的变化与否,即可以知道按键是否被按下,从而做出相应的响应。
一切看起来很美好,是这样的吗?◎现实并非理想在我们通过上面的按键检测原理得出上述的结论的时候,其实忽略了一个重要的问题,那就是现实中按键按下时候的电平变化状态。
我们的结论是基于理想的情况得出来的,就如同下面这幅按键按下时候对应电平变化的波形图一样:(原文件名:3.jpg)而实际中,由于按键的弹片接触的时候,并不是一接触就紧紧的闭合,它还存在一定的抖动,尽管这个时间非常的短暂,但是对于我们执行时间以us为计算单位的微控制器来说,它太漫长了。
因而,实际的波形图应该如下面这幅示意图一样。
(原文件名:4.jpg)这样便存在这样一个问题。
假设我们的系统有这样功能需求:在检测到按键按下的时候,将某个I/O的状态取反。
由于这种抖动的存在,使得我们的微控制器误以为是多次按键的按下,从而将某个I/O的状态不断取反,这并不是我们想要的效果,假如该I/O控制着系统中某个重要的执行的部件,那结果更不是我们所期待的。
于是乎有人便提出了软件消除抖动的思想,道理很简单:抖动的时间长度是一定的,只要我们避开这段抖动时期,检测稳定的时候的电平不久可以了吗?听起来确实不错,而且实际应用起来效果也还可以。
于是,各种各样的书籍中,在提到按键检测的时候,总也不忘说道软件消抖。
就像下面的伪代码所描述的一样。
(假设按键按下时候,低电平有效)If(0 == io_KeyEnter) //如果有键按下了{Delayms(20) ; //先延时20ms避开抖动时期If(0 == io_KeyEnter) //然后再检测,如果还是检测到有键按下{return KeyValue ; //是真的按下了,返回键值}else{return KEY_NULL //是抖动,返回空的键值}while(0 == io_KeyEnter) ; //等待按键释放}乍看上去,确实挺不错,实际中呢?在实际的系统中,一般是不允许这么样做的。
为什么呢?首先,这里的Delayms(20) , 让微控制器在这里白白等待了20 ms 的时间,啥也没干,考虑我在《学会释放CPU》一章中所提及的几点,这是不可取的。
其次while(0 == io_KeyEnter) ;更是程序设计中的大忌(极少的特殊情况例外)。
任何非极端情况下,都不要使用这样语句来堵塞微控制器的执行进程。
原本是等待按键释放,结果CPU就一直死死的盯住该按键,其它事情都不管了,那其它事情不干了吗?你同意别人可不会同意 所以合理的分配好微控制的处理时间,是编写按键程序的基础。
◎消除抖动有必要吗?的确,软件上的消抖确实可以保证按键的有效检测。
但是,这种消抖确实有必要吗?有人提出了这样的疑问。
抖动是按键按下的过程中产生的,如果按键没有按下,抖动会产生吗?如果没有按键按下,抖动也会在I/O上出现,我会立刻把这个微控制器锤了,永远不用这样一款微控制器。
所以抖动的出现即意味着按键已经按下,尽管这个电平还没有稳定。
所以只要我们检测到按键按下,即可以返回键值,问题的关键是,在你执行完其它任务的时候,再次执行我们的按键任务的时候,抖动过程还没有结束,这样便有可能造成重复检测。
所以,如何在返回键值后,避免重复检测,或者在按键一按下就执行功能函数,当功能函数的执行时间小于抖动时间时候,如何避免再次执行功能函数,就成为我们要考虑的问题了。
这是一个仁者见仁,智者见智的问题,就留给大家去思考吧。
所以消除抖动的目的是:防止按键一次按下,多次响应。
“从单片机初学者迈向单片机工程师”之KEY主题讨论基于状态转移的独立按键程序设计本章所描述的按键程序要达到的目的:检测按键按下,短按,长按,释放。
即通过按键的返回值我们可以获取到如下的信息:按键按下(短按),按键长按,按键连_发,按键释放。
不知道大家还记得小时候玩过的电子钟没有,就是外形类似于CALL 机(CALL 机,好像是很古老的东西了 )的那种,有一个小液晶屏,还有四个按键,功能是时钟,闹钟以及秒表。
在调整时间的时候,短按+键每次调整值加一,长按的时候调整值连续增加。
小的时候很好奇,这样的功能到底是如何实现的呢,今天就让我们来剖析它的原理吧。
状态在生活中随处可见。
譬如早上的时候,闹钟把你叫醒了,这个时候,你便处于清醒的状态,马上你就穿衣起床洗漱吃早餐,这一系列事情就是你在这个状态做的事情。
做完这些后你会去等车或者开车去上班,这个时候你就处在上班途中的状态…..中午下班时间到了,你就处于中午下班的状态,诸如此类等等,在每一个状态我们都会做一些不同的事情,而总会有外界条件促使我们转换到另外一种状态,譬如闹钟叫醒我们了,下班时间到了等等。
对于状态的定义出发点不同,考虑的方向不同,或者会有些许细节上面的差异,但是大的状态总是相同的。
生活中的事物同样遵循同样的规律,譬如,用一个智能充电器给你的手机电池充电,刚开始,它是处于快速充电状态,随着电量的增加,电压的升高,当达到规定的电压时候,它会转换到恒压充电。
总而言之,细心观察,你会发现生活中的总总都可以归结为一个个的状态,而状态的变换或者转移总是由某些条件引起同时伴随着一些动作的发生。
我们的按键亦遵循同样的规律,下面让我们来简单的描绘一下它的状态流程转移图。
(原文件名:1.jpg)下面对上面的流程图进行简要的分析。
首先按键程序进入初始状态S1,在这个状态下,检测按键是否按下,如果有按下,则进入按键消抖状态2,在下一次执行按键程序时候,直接由按键消抖状态进入按键按下状态3,在此状态下检测按键是否按下,如果没有按键按下,则返回初始状态S1,如果有则可以返回键值,同时进入长按状态S4,在长按状态下每次进入按键程序时候对按键时间计数,当计数值超过设定阈值时候,则表明长按事件发生,同时进入按键连_发状态S5。
如果按键键值为空键,则返回按键释放状态S6,否则继续停留在本状态。
在按键连_发状态下,如果按键键值为空键则返回按键释放状态S6,如果按键时间计数超过连_发阈值,则返回连_发按键值,清零时间计数后继续停留在本状态。
看了这么多,也许你已经有一个模糊的概念了,下面让我们趁热打铁,一起来动手编写按键驱动程序吧。
下面是我使用的硬件的连接图。
(原文件名:2.jpg)硬件连接很简单,四个独立按键分别接在P3^0------P3^3四个I/O上面。
因为51单片机I/O口内部结构的限制,在读取外部引脚状态的时候,需要向端口写1.在51单片机复位后,不需要进行此操作也可以进行读取外部引脚的操作。
因此,在按键的端口没有复用的情况下,可以省略此步骤。
而对于其它一些真正双向I/O口的单片机来说,将引脚设置成输入状态,是必不可少的一个步骤。
下面的程序代码初始化引脚为输入。
void KeyInit(void){io_key_1 = 1 ;io_key_2 = 1 ;io_key_3 = 1 ;io_key_4 = 1 ;}根据按键硬件连接定义按键键值#define KEY_VALUE_1 0x0e #define KEY_VALUE_2 0x0d #defineKEY_VALUE_3 0x0b#defineKEY_VALUE_4 0x07#defineKEY_NULL 0x0f下面我们来编写按键的硬件驱动程序。
根据第一章所描述的按键检测原理,我们可以很容易的得出如下的代码:static uint8 KeyScan(void){if(io_key_1 == 0)return KEY_VALUE_1 ;if(io_key_2 == 0)return KEY_VALUE_2 ;if(io_key_3 == 0)return KEY_VALUE_3 ;if(io_key_4 == 0)return KEY_VALUE_4 ;return KEY_NULL ;}其中io_key_1等是我们按键端口的定义,如下所示:sbit io_key_1 = P3^0 ;sbit io_key_2 = P3^1 ;sbit io_key_3 = P3^2 ;sbit io_key_4 = P3^3 ;KeyScan()作为底层按键的驱动程序,为上层按键扫描提供一个接口,这样我们编写的上层按键扫描函数可以几乎不用修改就可以拿到我们的其它程序中去使用,使得程序复用性大大提高。
同时,通过有意识的将与底层硬件连接紧密的程序和与硬件无关的代码分开写,使得程序结构层次清晰,可移植性也更好。
对于单片机类的程序而言,能够做到函数级别的代码重用已经足够了。
在编写我们的上层按键扫描函数之前,需要先完成一些宏定义。
//定义长按键的TICK数,以及连_发间隔的TICK数#define KEY_LONG_PERIOD 100 #defineKEY_CONTINUE_PERIOD 25//定义按键返回值状态(按下,长按,连_发,释放)#define KEY_DOWN 0x80 #defineKEY_LONG 0x40#defineKEY_CONTINUE 0x20#define KEY_UP 0x10//定义按键状态#define KEY_STATE_INIT 0 #defineKEY_STATE_WOBBLE 1#define KEY_STATE_PRESS 2 #define KEY_STATE_LONG 3 #define KEY_STATE_CONTINUE 4 #define KEY_STATE_RELEASE 5接着我们开始编写完整的上层按键扫描函数,按键的短按,长按,连按,释放等等状态的判断均是在此函数中完成。