简单友好的按键处理程序设计

合集下载

按键处理程序C语言单片机

按键处理程序C语言单片机

按键处理程序C语言单片机分享一种按键处理程序(用C)//头文件定义:Ustruct KEY{Uchar Val;#define Key_Model_C 0 //按键1值#define Key_AddVal_C 1 //按键2值Uint ScanOnTime;Uchar LongKeyState;Uchar LongKeyRestState;Uchar SetInRn;Uchar Model; //按键状态(模式)#define Off_C 0 //之前未按下#define On_C 1 //现按下#define Delay_C 2 //按键处理后标志}Key;//----------------定义两个IO输入口为按键入口--------------------//#define KeyMo_Bin (GPIOB->IDR.Bit.B5)#define KeyAdd_Bin (GPIOB->IDR.Bit.B6)/*===================================== ==========================*/GPIO_Init(GPIO_Pin_5|GPIO_Pin_6,GPIO_Mode_In_PU_No_IT); //初始化为上拉输入无中断/*===================================== ==========================*///主程序大循环中每1毫秒扫描1次void KeyScan(void){if(Key.LongKeyRestState == 1) //长按键标志(复位处理长按键){if((KeyMo_Bin == 1) && (KeyAdd_Bin == 1)) //当两按键均抬起{if(++Key.ScanOnTime >= 130) //延时后复位{Key.LongKeyRestState=0;Key.Model=Delay_C;}}elseKey.ScanOnTime=0;return;}if(Key.Model == Off_C) //如果当前按键状态为未按下“Off_C”{if((KeyMo_Bin == 0) || (KeyAdd_Bin == 0))//按键1或按键2已按下(低有效){if(++Key.ScanOnTime >= 10) //当按下后自加1,加够10次即1ms*10=10ms去抖动{Key.ScanOnTime=0;if(KeyMo_Bin == 0) //如果按键1为0即按下{Key.Val=Key_Model_C; //付当键1值(看头文件定义)Key.Model=On_C; //置按键已按下标志}else if(KeyAdd_Bin == 0) //如果按键2为0即按下{Key.Val=Key_AddVal_C; //付当键2值(看头文件定义)Key.Model=On_C; //置按键已按下标志}BellOn(200); //蜂鸣器响}}elseKey.ScanOnTime=0; //清去抖延时计数值}else if(Key.Model == Delay_C) //如果当前按键状态为已按下且已处理“Delay_C”{if((KeyMo_Bin == 1) && (KeyAdd_Bin == 1))//如果两按键均抬起{if(++Key.ScanOnTime >= 100) //延时100ms后复位按键状态为“Off_C”{Key.SetInRn=0;Key.ScanOnTime=0;Key.Model=Off_C;}}else //如果按键没有被抬起,对应上面if{if(++Key.ScanOnTime >= 1000) //延时1000ms后再复位按键状态为“Off_C”(为长按处理){Key.ScanOnTime=0;Key.Model=Off_C;}}}}//===================================== ========================================= ========void LoadCheckKeyRest(void){Key.LongKeyRestState=1;Key.ScanOnTime=0;}//===================================== ========================================= ========//处理相应按键(可250ms才调用一次)长按if(Key.Model == On_C) //按键状态为已按下{if(Key.Val == Key_Model_C) //是键1按下(看头文件定义){if(++Key.SetInRn >= 3) //连计3次数3秒后为长按键(对应上面,如果按下未抬起的话会延时1000ms){Key.SetInRn=0;LoadCheckKeyRest(); //调清长按处理BellOn(600); //蜂鸣器响//-----------长按需处理的内容-----下-----------//WorkStateBit.Bit.SettingMo=1;SetOverTime=0;SetMoRn=0;SetBak[0]=Rtc_InitDate.RTC_Year;SetBak[1]=Rtc_InitDate.RTC_Month;SetBak[2]=Rtc_InitDate.RTC_Date;SetBak[3]=Rtc_InitDate.RTC_WeekDay;SetBak[4]=Rtc_InitTime.RTC_Hours;SetBak[5]=Rtc_InitTime.RTC_Minutes;//-----------长按需处理的内容------上----------//Key.Model=Delay_C; //置按键模式为:已处理按键(看头文件定义)return;}}elseKey.SetInRn=0;Key.Model=Delay_C;}。

单片机按键课程设计

单片机按键课程设计

单片机按键课程设计一、课程目标知识目标:1. 让学生掌握单片机基础知识和按键的工作原理;2. 帮助学生了解按键在单片机系统中的应用和编程方法;3. 使学生能够运用所学知识设计简单的单片机按键控制系统。

技能目标:1. 培养学生动手实践能力,能够独立完成单片机按键电路的搭建;2. 提高学生编程能力,掌握单片机按键程序的设计与调试;3. 培养学生解决问题的能力,能够针对实际需求设计合适的单片机按键方案。

情感态度价值观目标:1. 培养学生对单片机技术及电子制作的兴趣,激发创新意识;2. 培养学生团队合作精神,学会分享和交流;3. 增强学生面对困难的勇气和毅力,培养勇于挑战的精神。

课程性质分析:本课程为实践性较强的课程,注重理论知识与实践操作的相结合,以培养学生的动手能力和创新能力为核心。

学生特点分析:学生处于初中或高中年级,具有一定的物理和数学基础,对电子技术和编程有一定了解,好奇心强,喜欢动手实践。

教学要求:结合学生特点,注重理论与实践相结合,充分调动学生的积极性,引导学生主动参与,提高学生的实践能力和创新能力。

在教学过程中,将课程目标分解为具体的学习成果,以便进行有效的教学设计和评估。

二、教学内容1. 单片机基础知识:介绍单片机的组成、工作原理、引脚功能等,结合教材相关章节,为学生建立单片机的基本概念。

2. 按键工作原理:讲解按键的物理原理、电路连接方式、去抖动方法等,使学生了解按键在单片机系统中的应用。

3. 单片机按键编程:教授单片机按键程序设计方法,包括I/O口编程、中断处理等,结合教材实例进行讲解。

4. 按键电路搭建:指导学生动手搭建单片机按键电路,学会使用面包板、电子元件等,培养实际操作能力。

5. 按键程序设计与调试:教授编程软件的使用,引导学生编写、调试按键程序,掌握程序设计的基本方法。

6. 应用实例分析:分析典型单片机按键控制系统实例,使学生了解实际应用中的设计方法和技巧。

教学进度安排:1. 第1课时:单片机基础知识及按键工作原理介绍;2. 第2课时:单片机按键编程方法讲解;3. 第3课时:按键电路搭建及编程实践;4. 第4课时:按键程序设计与调试;5. 第5课时:应用实例分析及总结。

对指定程序使用按键的方法-概述说明以及解释

对指定程序使用按键的方法-概述说明以及解释

对指定程序使用按键的方法-概述说明以及解释1.引言1.1 概述概述部分的内容:引言部分旨在介绍本文的主题和目的,即指定程序的按键使用方法。

本文将详细介绍如何正确使用按键来操作指定的程序。

随着技术的发展,越来越多的程序要求用户通过按键来完成各种操作,因此掌握正确的按键使用方法对于提高工作效率和操作体验至关重要。

在本文中,我们将介绍确定程序的按键功能的方法,以及学习和记忆按键组合的技巧。

同时,我们还将分享一些按键使用的技巧和注意事项,包括使用正确的手指和手势,以及练习和熟悉按键位置。

通过阅读本文,您将能够更加灵活和高效地使用指定程序的按键功能。

总之,本文旨在帮助读者掌握正确的按键使用方法,提高操作效率和用户体验。

在结论部分,我们将对指定程序的按键使用方法进行总结,并提供进一步学习和探索的建议。

请继续阅读,了解如何使用按键来更好地操作指定的程序。

1.2文章结构文章结构是指整篇文章的组织框架和内容安排。

一个良好的文章结构可以使读者更易于理解和消化文章的内容。

本文的结构主要分为引言、正文和结论三个部分。

引言部分主要包括概述、文章结构和目的三个要素。

概述部分介绍了文章的主题和背景,引起读者的兴趣。

文章结构部分详细说明了整篇文章的框架和目录结构,为读者提供了整体的导向。

目的部分明确了本文的写作目标和意义,为读者解释了文章的目的。

正文部分是论述和阐述文章主题的核心部分。

本文中的正文内容共分为两个小节。

第一小节是针对指定程序的按键使用方法,其中包括了确定程序的按键功能和学习和记忆按键组合两个子部分。

在第一小节中,读者将了解如何确定指定程序的按键功能,并学习如何有效地掌握和记忆按键组合。

第二小节讨论了按键使用的技巧和注意事项,包括使用正确的手指和手势以及练习和熟悉按键位置等内容。

通过这两个小节的论述,读者将能够全面了解和掌握指定程序的按键使用方法。

结论部分对整篇文章进行总结和提出进一步的学习和探索建议。

在第三小节中,总结了指定程序的按键使用方法,并提供了一些提示和建议,鼓励读者进一步学习和探索相关的内容。

按键处理的几种方法

按键处理的几种方法

新型的按键扫描程序核心算法:unsigned char Trg;unsigned char Release;unsigned char Cont;void KeyRead( void ){unsigned char ReadData = PINB^0xff; // 1 读键值Trg = ReadData & (ReadData ^ Cont); // 2 得到按下触发值Release=(ReadData^Trg^Cont); //3 得到释放触发值Cont = ReadData; //4 得到所有未释放的键值}下面是程序解释:Trg(triger)代表的是触发,Cont(continue)代表的是连续按下。

1:读PORTB的端口数据,取反,然后送到ReadData 临时变量里面保存起来。

2:算法1,用来计算触发变量的。

一个位与操作,一个异或操作,我想学过C语言都应该懂吧?Trg为全局变量,其它程序可以直接引用。

3:算法2,用来计算连续变量。

我们最常用的按键接法如下:AVR是有部上拉功能的,但是为了说明问题,我是特意用外部上拉电阻。

那么,按键没有按下的时候,读端口数据为1,如果按键按下,那么端口读到0。

下面就看看具体几种情况之下,这算法是怎么一回事。

(1)没有按键的时候端口为0xff,ReadData读端口并且取反,很显然,就是 0x00 了。

Trg = ReadData & (ReadData ^ Cont); (初始状态下,Cont也是为0的)很简单的数学计算,因为ReadData为0,则它和任何数“相与”,结果也是为0的。

Cont = ReadData; 保存Cont 其实就是等于ReadData,为0;结果就是:ReadData = 0;Trg = 0;Cont = 0;(2)第一次PB0按下的情况端口数据为0xfe,ReadData读端口并且取反,很显然,就是 0x01 了。

可编程键盘使用方法

可编程键盘使用方法

可编程键盘使用方法当使用可编程键盘时,有许多方法和技巧可以帮助您更高效地利用它的功能。

以下是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.程序运行结束时,释放资源、关闭文件等。

PS2键盘的设计---C51程序

PS2键盘的设计---C51程序

PS2键盘的设计---C51程序+详细注释(转)PS2键盘的设计---C51程序#include <reg51.H>#define Frequence 11 //晶振频率单位是MHZ#define DELAY 10*Frequence/6 //发送程序延时#define SLEEP 8*Frequence/6 //发送程序延时sbit KBCLK="P3"^0; //键盘时钟线sbit KBDATA="P3"^1; //键盘数据线bit bat(void); //基本保证测试无错误返回0,有错返回1unsigned char buf_length(); //返回缓冲区数据个数bit command_s(); //键盘命令检查,有命令要接受返回1void clr_buf(void); //清键盘缓冲区void del_head(); //删除缓冲区头unsigned char exist(unsigned char);//检查键盘缓冲区中是否有与参数相等数,有则返回位置,无则返回255//bit emputy(); //检查键盘缓冲区是否空,是返回1unsigned char get_head(); //取键盘缓冲区头,头指针不变unsigned char get_head_f();//取缓冲区头对应标记,标记为0表示对应键已经松下bit insert(unsigned char,unsigned char);//插入缓冲区,并设置对应标记,成功则返回1void ini_timer01(); //定时器初始化void receive_process(); //接收键盘命令并处理void reset(); //软件复位unsigned char scankb(unsigned char); //扫描第N行,返回列直void send_buf(); //发送缓冲区扫描码bit send_code(unsigned char _KeyNo,bit flag);//发送按键扫描码,flag=0发送断开码,flag=1发送接通码bit send(unsigned char); //发送数据void set_default(); //设置缺省值void set_timer1(); //复位定时器1void set_scan_v(unsigned char); //设置扫描速度(拍发速率、延迟时间)void set_flag(unsigned char); //设置缓冲区对应标记void set_led(unsigned char); //设置LEDvoid secret(unsigned char);void scan(void);unsigned char get_end();bit emputy(void);//-----------------------函数声明,变量定义--------------------------------------------------------#include <reg51.h>#define KEY P1unsigned char key_code; //键值unsigned char key_buf[8]; //按键缓冲区unsigned char key_COUNT; //按键计数器unsigned char COUNT_TI; //定时中断计数//-----------------------变量声明---------------------------------------------------------------------void system_init(void ); //初始化,设置定时器0的工作方式,供主程序调用void TIMER0_SCANkey(); //定时器0中断处理函数bit judge_hitkey(); //判断是否有键按下,有返回1,没有返回0unsigned char scan_key(); //扫描键盘,返回键值(高四位代表行,低四位代表列) void key_manage(unsigned char keycode); //按键处理//...........每个按键对应一个处理程序//--------------------------------------------------------------------------------------------------// 函数名称:scan_key// 函数功能:扫描键盘,返回键值(高四位代表行,低四位代表列)// 无键按下返回0//--------------------------------------------------------------------------------------------------unsigned char scan_key() //扫描键盘,返回键值(高四位代表行,低四位代表列){unsigned char scancode,keycode,keycode_line,keycode_row;scancode="0xF0"; //列置低,行置高KEY="scancode"; //输入扫描码,扫描行keycode_line=KEY;scancode="0xF0"; //列置高,行置低KEY="scancode"; //输入扫描码,扫描列keycode_row=KEY;keycode=(((keycode_line<<4)&0xF0)|(keycode_row&0x0F));return(keycode);}//--------------------------------------------------------------------------------------------------// 函数名称:Timer0_init()// 函数功能:初始化设置// 设定INT0的工作方式//--------------------------------------------------------------------------------------------------void Timer0_init(void ){TMOD="0x20"; //定时器0工作在方式2的定时模式ET0=1; //定时器0中断允许TH0=0;TL0=0;TR0=1; //定时器0开始计数EA="1"; //系统中断允许}//--------------------------------------------------------------------------------------------------// 函数名称:TIMER0_intrupt// 函数功能:定时器0中断处理程序按键定时查询//--------------------------------------------------------------------------------------------------void TIMER0_SCANkey() interrupt 1 using 1{EA="0"; //系统中断禁止if((++COUNT_TI)%30==0){switch(COUNT_TI/30){case 1:if(scan_key()==0)COUNT_TI=0; //无键按下,计数值归零break;case 2:break;case 3:if(scan_key()==0)COUNT_TI=0; //无键按下,计数值归零,上次按键未扰动elsekey_code=scan_key(); //又有效建,获取键值break;default:if(scan_key()==0) //等待按键释放key_manage(key_code); //有一个有效按键,调用按键处理程序}}EA=1;}//--------------------------------------------------------------------------------------------------// 函数名称:key_manage// 函数功能:有效按键处理// 按键计数器加1,缓存区数据后移1位//--------------------------------------------------------------------------------------------------void key_manage(unsigned char keycode){unsigned char i;for(i=7;i>=0;i--){key_buf[i]=key_buf[i-1]; //缓冲区内数据后移1位}key_buf[0]= keycode; //将键值送入缓冲区key_COUNT++; //按键计数器加一}//-----------------------函数声明,变量定义-------------------------------------------------------- #include <reg51.h>#define KEY P1sbit DATA="P3"^1; //数据线sbit CLK="P3"^2; //时钟线unsigned char key_buf[8]; //按键缓冲区unsigned char key_COUNT; //按键计数器//--------------------------------------------------------------------------------------------------// 函数名称:delay// 入口参数:N// 函数功能:延时子程序,实现(16*N+24)us的延时// 系统采用11.0592MHz的时钟时,延时满足要求,其它情况需要改动//--------------------------------------------------------------------------------------------------void delay(unsigned int N){int i;for(i=0;i<N;i++);}//--------------------------------------------------------------------------------------------------// 函数名称:CAL_jiaoyan// 函数功能:计算校验位//--------------------------------------------------------------------------------------------------bit CAL_jiaoyan(unsigned char byte_data){//}//--------------------------------------------------------------------------------------------------// 函数名称:SEND_byte// 函数功能:发送一子节数据//--------------------------------------------------------------------------------------------------void SEND_byte(unsigned char byte_data){unsigned char i,temp;if(CLK==0) //时钟线为低temp="byte"_data;CLK="1";DA TA="0";delay(0);CLK="0"; //发送起始位for(i=0;i<8;i++){delay(0);CLK="1";DA TA=(temp&0x01); //发送数据byte_data=byte_data>>1;delay(0);CLK=0;}delay(0);CLK="1";DA TA=CAL_jiaoyan(byte_data); //发送校验位delay(0);CLK=0;delay(0);CLK="1";DA TA=1; //发送结束位delay(0);CLK=0;}//-------------------------------------------------------------------------------------------------- // 函数名称:RECEIVE_byte// 函数功能:接收一子节数据//-------------------------------------------------------------------------------------------------- unsigned char RECEIVE_byte(){unsigned char byte_data,i;CLK="0";delay(0);CLK="1"; //接收起始位,丢弃for(i=0;i<8;i++){delay(0);CLK="0";delay(0);CLK=1;byte_data=byte_data>>1;if(DATA=1)byte_data=byte_data|0x80;elsebyte_data=byte_data&0x7F; //接收8位数据}for(i=0;i<2;i++){delay(0); //接收校验位和结束位CLK="0";delay(0);CLK=1;}return(byte_data);}//--------------------------------------------------------------------------------------------------// 函数名称:manage// 函数功能:主机命令处理函数//-------------------------------------------------------------------------------------------------- void manage(unsigned char rec_data){}//--------------------------------------------------------------------------------------------------// 函数名称:SEND_keydata// 函数功能:发送按键值到主机//-------------------------------------------------------------------------------------------------- void SEND_keydata(){unsigned char ASCII_code; //// ASCII_code=judge_key(key_buf[key_COUNT]); //判断键值,按键编码成ASCII码SEND_byte(ASCII_code);key_COUNT--;}//--------------------------------------------------------------------------------------------------// 函数名称:主程序// 函数功能:循环查询主机状态//-------------------------------------------------------------------------------------------------- void main(){unsigned char rec_data;while(1){if(CLK==0&&DATA==0){rec_data=RECEIVE_byte(); //接收主机键盘manage(rec_data); //指令处理函数}if(key_COUNT!=0&&CLK==1) //有按键等待处理//线路空闲SEND_keydata();}。

单片机按键设计的四个方案详解

单片机按键设计的四个方案详解

单片机按键设计的四个方案详解在单片机系统里,按键是常见的输入设备,在本文将介绍几种按键硬件、软件设计方面的技巧。

一般的在按键的设计上,一般有四种方案:一是GPIO口直接检测单个按键,如图1.1所示;二是按键较多则使用矩阵键盘,如图1.2所示;三是将按键接到外部中断引脚上,利用按键按下产生的边沿信号进行按键检测,如图1.3所示;四是利用单片机的ADC,在不同的按键按下后,能够使得ADC接口上的电压不同,根据电压的不同,则可以识别按键,如图1.4所示。

在以上四种设计上,各有优点和不足。

第一种是最简单和最基础的,对于单片机初学者很容易理解和使用,但是缺点是,需要在主循环中不断检测按键是否按下,并且需要做消抖处理。

若主循环中某个函数任务占用时间较长,则按键会有不同程度的“失灵”。

第二种,优点是能够在有限的GPIO情况下,扩展尽可能多的按键。

但缺点同上,需要不停检测按键是否按下。

第三种方式是效率最高,不需要循环检测按键是否按下,但是缺点是,需要单片机有足够的外部中断接口以供使用;第四种的优点是,只需要单片机的一个ADC接口,一根线,就能对多个按键进行识别,缺点是按键一旦内部接触不良,则可能按键串位,且按键产生的抖动,会造成一定的识别错误。

在以上的三种常见按键设计的基础上,现在分享我学习和工作中总结的按键方案。

改进一:在原方案一的基础上,加上与门电路,使得任何一个按键按下,都能产生中断,然后在中断里面识别是哪个按键被按下。

因此不需要循环扫描,大大提高了效率。

方案如图1.5所示。

只需要每个按键对应地增加一个二极管,利用二极管的线与特性,可以实现按下任何按键,都能产生中断信号,但是按键之间互不影响。

二极管选用普通整流二极管即可,本人亲测可行。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

在单片机应用系统设计中,人机界面部分的友好程度,很大一部
分取决于键盘处理程序。

在按键时按得快了没有反应,按慢了一连响应几次,总给人紧迫感或迟钝感,不能使人满意。

用以下思路设计的键处理程序取得了满意效果。

判断有没有键值:
1.若有键值:
判断是否为首次按下:
A:若首次按下:判断是否与上次按下的键值相同
a.若相同再判断:是否已经按下了300ms?
1).若已经按下300ms则将此键做为连键处理。

2).若不是连键则判断:是否按下20ms?
1>.若确认按下20ms,得到有效键值等待弹起
2>. 若不是按下20ms直接结束处理(ret)。

b.若不相同则将标志清零结束处理(ret)。

B:若不是首次按下:将键值暂存起来,标志置位结束处理。

2.若无键值:
判断是否有键值已被确认
A.若有键已被确认:判断按键是否首次抬起
a.若首次抬起:判断抬起延时时间(20ms)是否到达
1>.若延时到则将标志处理结束处理。

2>.若延时未到直接结束处理(ret)。

b.若非首次抬起:直接结束处理(ret)。

B.若没有键被确认:直接结束处理(ret)。

具体程序实现流程图如下:(所有延时均为非阻塞式延时)
Lcll scan_key----为调用键扫描程序;
简单的按键处理程序见:
在嵌入程序设计中,键处理程序在一定程度上决定着人机对话界面的友好程度。

WINDOWS是公认的界面友好的典范,我们就借鉴WINDOWS的键处理的思想:
1.当击键时WINDOWS立即作出响应;
2.当按住键不放时,WINDOWS延迟一定时间来判断是否为连键;其间不
作响应;
3.当认为是连键时,会间隔一定时间重复作出响应;
(可以打开记事本,敲个‘h’键试验:瞬时敲击,即可出现‘h’,再按着键不放,无‘h’出现,当延迟一定时间‘h’,就以较快速度出现;)在C8051F020和DSP编程中运用上述的思想所编的键处理程序非常简捷、高效和友好,以下为该程序的流程图:
根据该流程的51系列单片机程序和DSP程序:
1、C8051F020单片机程序如下:
;================================================================= ; function: key_filter ;键盘去抖程序--徐丽红
; input: a
; output: key.bsure
; usage: a,b
;================================================================= key_filter: ;键盘去抖程序
lcall scan_key
jz kf_no ;a=0?
jb bfirst, kf_1th ;first down?
mov b, a
mov a, k_dly
jnz kf_ret ;20ms到
了吗?
mov a, b ;20ms

cjne a, key_tmp,kf_no ;a==k_tmp?
mov k_dly, #10 ;a==k_tmp
dec dly_k
jnb bfast, kf_nofast ;是连键吗?
kf_is0: mov a, dly_k ;是连键
jnz kf_ret ;300ms/ 160ms?
mov dly_k, #12 ;fast OK!
sjmp kf_ftok
kf_nofast:
mov a, dly_k ;不是连

cjne a, #24, kf_is0 ;延时了1次吗? kf_ftok:
mov key, key_tmp ;first OK!
setb bkey_do
setb bfast
kf_ret: ret
kf_1th: mov k_dly, #10 ;first down
mov key_tmp, a
mov dly_k, #25
clr bfirst
clr bfast
ret
2、LF2407型DSP程序如下:
;----------------------------------------------------------
; f unction: judge_key 键值判断
; i nput: ---
; o utput: ---
; u sege: ACC
;----------------------------------------------------------
judge_key: ;键值判断
ldp #PEDATDIR>>7
lacl PEDATDIR
cmpl
and #00110110b
ldp #DP_B01
sacl key_tmp
bcnd k_down, NEQ ;CATCH KEY?
ldp #DP_B01
splk #00h, bknot1
ret
k_down: lacl bknot1
bcnd not_first, NEQ ;first?
lacl key_tmp
sacl key_ok
splk #04, key_clk
splk #50, key_dly
splk #11h, bknot1
splk #00h, bksure
splk #00h, bcontinue
ret
not_first: lacl key_clk ;N times
bcnd T_over, EQ ;12ms?
ret
T_over: lacl key_ok ;12ms
xor key_tmp
bcnd Is_same, EQ ;same key?
splk #00h, bknot1
ret
Is_same: splk #4, key_clk
lacl bcontinue
bcnd Is_fast, NEQ ;continue?
OK_key: splk #11h, bcontinue
splk #11h, bksure
ret
Is_fast: lacl key_dly ;key_dly--
sub #01h
sacl key_dly
bcnd tuch_set, EQ ;500/300ms?
ret
tuch_set: splk #25, key_dly
b OK_key
该程序中:防抖时间是12ms;是否为连键延迟时间是500ms,连键重复处理时间是300ms;在实际中,根据具体情况调节时间,达到最佳效果。

注:以上两个程序中的延时均为非阻塞式延时,没有原地绕圈子式的延时,不会对主程序造成大影响。

相关文档
最新文档