当前位置:文档之家› 单片机按键程序(按钮处理)

单片机按键程序(按钮处理)

单片机按键程序(按钮处理)
单片机按键程序(按钮处理)

单片机案件程序(案件处理)

(c语言)

#include//包含单片机对应的头文件

#include

void delay_ms(unsigned int time) //延时毫秒数

{

unsigned int i,j;

for(i=time;i>0;i--)//i不断减一,知道i大于0条件不成立为止{

for(j=125;j>0;j--)//i不断减一,知道i大于0条件不成立为止{;}

}

}

void main(void)

{

while(1)

{

P3=0xff;

if(P3==0xfe)

{

delay_ms(5);

if(P3==0xfe)

while(1)

{

if(P3==0xff)

break;

}

P1=0x80;

P0=0x00;

P2=0x00;

}

if(P3==0xfd)

{

delay_ms(5);

if(P3==0xfd)

{

while(1)

{

if(P3==0xff)

break;

}

P0=0x00;

P2=0xff;

P1=0xff;

}

}

}

}

图如下:

自己写的按键单片机程序

自己写的按键单片机程序 用4个按键来控制数码管显示的内容#include#define duan P0//段选#define wei P2//位选unsigned char code wei1[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选控制查表的方法控制unsigned char code duan1[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0 x71};//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码unsigned char ge,shi,bai,a,b;sbit key1=P1;sbit key2=P1 ;sbit key3=P1 ;sbit key4=P1 ;void keys();//按键函数void s(unsigned char xms);//延时函数void DigDisplay(); //动态显示函数void init(); //初始化函数void main(void){init(); while(1){DigDisplay();keys();} }void DigDisplay(){unsigned char i;unsigned int j;bai=a/100;shi=a%100/10;ge=a%10;i=0;wei = wei1[i];//发送位选duan = duan1[bai]; //发送段码j = 10;//扫描间隔时间设定while(j--);duan = 0x00; //消隐i++;wei = wei1[i];//发送位选duan = duan1[shi]; //发送段码j = 10;//扫描间隔时间设定while(j--);duan = 0x00; //消隐i++;wei = wei1[i];//发送位选duan = duan1[ge]; //发送段码j = 10;//扫描间隔时间设定while(j--);duan = 0x00; //消隐}void init() {key1=1;key2=1;key3=1;key4=1;TMOD=0X01;TH0=(65536- 45872)/256;TL0=(65536-45872)%256;EA=1;ET0=1;}void s(unsigned char xms){unsigned char x,y;for(x=xms;x>0;x--)for(y=110;y>0;y--);}void times() interrupt 1{TH0=(65536-45872)/256;TL0=(65536-45872)%256;b++;if(b==20){b=0;a++;if(a==256){a=0;}}}void keys(){if(key1==0){s(10);if(key1==0){a++;TR0=0;if(a==256)a=0;while(!key1)Dig Display();}}if(key2==0){s(10);if(key2==0){TR0=0;if(a==0)a=256;a--

51单片机04矩阵按键逐行扫描,行列扫描代码

矩阵键盘扫描原理 方法一: 逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。 方法二: 行列扫描:我们可以通过高四位全部输出低电平,低四位输出高电平。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。

//行列扫描 #include #define GPIO_KEY P0 #define GPIO_LCD P2 unsigned char code a[17]= {~0xfc,~0x60,~0xda,~0xf2,~0x66,~0xb6,~0xbe,~0xe0, ~0xfe,~0xf6,~0xee,~0x3e,~0x9c,~0x7a,~0xde,~0x8e,~0x00}; //按位取反的用法 void delay10ms(); void keydown();//要与下面的定义一致 void main() { GPIO_LCD=a[16];//初始化数码管 while(1) { keydown(); } }

void delay10ms() { unsigned char a,b; for(a=38;a>0;a--) for(b=130;b>0;b--); } void keydown() //检测按下,按下时需要消抖,检测松开,返回按键值//没有按键时保持 { unsigned char n=0,key; GPIO_KEY=0x0f; if(GPIO_KEY!=0x0f)//读取按键是否按下 { delay10ms(); //延时10ms消抖 if(GPIO_KEY!=0x0f)//再次检测按键是否按下 { GPIO_KEY=0x0f;//测试列 switch(GPIO_KEY) { case 0x07: key=0;break;

键盘消抖电路的研究与分析

判断是否有键按下;简单硬件消抖则 是采用电容来平掉信号的毛刺。但是对稳定性要求比较高的应用则需要采用相对复杂的集成电路来实现。 1 简单键盘消抖方法 1.1 软件延时消抖 按键抖动时间的长短由按键的机械特性决定,一般为5ms~10ms,按键稳定闭合时间的长短则是由操作人员的按键动作决定的,一般为零点几秒至数秒,如图1所示。 利用软件延时消除键盘抖动所产生的毛刺信号时需设置一个定时器中断,每中断一次则读取键盘接口的信号数据,如果与上次读取的数据不一致,说明当前读取的是前沿抖动数据,将当前的数据保留,等待下次定时器中断。如果当前读取的数据和前次读取数据相同则说明读取的是稳定状态下的数据,则确认为真正有键按下。当检测到按键释放后,需要延时5ms~10ms的时间,待后沿抖动消失后才能转入该键的处理程序。 软件延时并不需要增加新的硬件,但采用这种方式来设计,一般通过软件指令或者定时器的方式来设定延时的时间,采用通用处理器,由于运行速度不一致,需要将软件做相应的修改,比较麻烦。 1.2 简单硬件消抖 采用简单的硬件延时消抖是在键盘数据线接入单片机的引脚的地方并入一小电容,利用电容的充放电原理来实现消除因键盘的抖动所产生的毛刺。如图2所示,键盘按键信号key通过由R2,C1构成的RC振荡电路,过滤到毛刺,到达MCU的引脚上。 基金项目:武汉科技大学校基金资助项目(2006XY26) 键盘消抖电路的研究与分析 邢远秀1 陈姚节2 1、武汉科技大学理学院 4300812、武汉科技大学计算机学院 430081 键盘是计算机和工业控制等领域不可缺少的输入设备,通过它可以实现人机对话,完成各种功能操作。但是,通常的按键所用开关为机械弹性开关,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,因而在闭合及断开的瞬间均伴随有一连串的抖动,键抖动会引起一次按键被误读多次,为了确保对按键的一次闭合仅作一次处理,必须去除按键抖动。常见的消抖方法采用软件或硬件来实现:软件消抖主要是采用延时多次读取键盘接口数据,通过比较前后两次读取键盘端口的数据来 RC振荡电路实现键盘消抖的成本相对较低,工作不是很稳定,可能出现差错(即产生抖动信号),这只适合对消除抖动要求不高的场合。 2 集成电路消抖 集成电路实现键盘消抖主要是采用双组可再触发单稳态多谐振荡器-74HC123,它可把按键所产生的小脉冲信号转换成大方波信号并送到处理器引脚进行计数。 2.1 74HC123工作原理 74HC123包括两个独立的单稳态触发 表1 74HC123功能表 图3 74HC123管脚与内部结构 图2 RC消抖电路原理图 图1 按键波形图

单片机键盘输入程序

这是读取键盘的子程序 主要内容为:如何定义位,如何得到按键状态,防止键盘干扰的方法 以及如何处理读入的键值 思路:首先在某一引脚输出一个电平,然后读入引脚的电平,如果刚好相反 那么可能有按键发生,但是不排除干扰,为了防止干扰,需要软件延时20ms 应该说键盘输入是单片机外部指令输入的重要途径,因此如何设计键盘以及键盘的工作原理、读键盘的方法、键盘的抗干扰设计等在单电能机系统设计中占有重要地位。这个例子在系统硬件的基础上设计了软件查询程序、软件延时程序(防止干扰),大致讲述了一种查询式键盘的工作原理与读取方式。 下面是汇编语言写的单片机键盘输入程序 ************************************************** led1 bit p1.0;LED 显示位定义 led2 bit p1.1 led3 bit p1.2 led4 bit p1.3 led5 bit p1.4 led6 bit p1.5 led7 bit p1.6 led8 bit p1.7 s1 bit p0.0 ;数码管位定义 s2 bit p0.1 s3 bit p0.2 s4 bit p0.3 s5 bit p0.4 s6 bit p0.5 s7 bit p0.6 s8 bit p0.7 led_data equ p2;数码管显示数据定义 key1 bit p3.5 ;按键引脚定义

key2 bit p3.6; key3 bit p3.7; key equ 46h;按键寄存单元 org 00h jmp main org 030h main:mov sp,#30h;首先定义 lcall REST;初始化子程序 lp:lcall pro_key;调用键盘查询子程序 lcall KEYPR ;用来显示所查询到的键值jmp lp;反复调用,不断查询 REST: mov a,#00h mov b,#00h mov p0,#0 mov p1,0ffh ; mov p2,#0 mov key,#00h mov p2,#255 clr beep RET KEYPR: mov a,key;键值在累加器KEY中 jz PROEND ;如果A= 0,表示没有按键,返回cjne a,#1,k1;A= 1 ,用户按了第一个键mov a,#1 ;处理 A = 1的情况 mov dptr,#tab_nu ;查表 movc a,@a+dptr mov led_data,a ;显示"1" setb s1 ;在第一位

单片机矩阵键盘扫描程序

#include #include #define uint unsigned int #define uchar unsigned char sbit E=P2^7; //1602使能引脚 sbit RW=P2^6; //1602读写引脚 sbit RS=P2^5; //1602数据/命令选择引脚 uint keyflag ; //键盘正在读取标志位,如果Keyflag为1 ,表示正在读取键盘,停止其他功能; char x,y,m,n,c; //Keyflag为0,读取键盘结束,恢复其他功能 char flag1=0; //频率范围10~1000Hz uchar Hrate = 0; //一个周期内高点平占据时间 uchar Lrate = 0; //一个周期内低电平占据时间 uint FREQ0; //定时器T0的计数变量// uint FREQ1; //定时器T1的计数变量// sbit P2_1=P2^0; //设置P2.1,作为信号输出口// uint disbuf[3]; uint figure=0; int sum2=0; int sum1=0; int flag=0; uint count=0; uint max=0; uint disbuf_temp=0; /******************************************************************** * 名称: 1602显示延时函数delay() * 功能: 延时,延时时间大概为5US。

* 输出: 无 ***********************************************************************/ void delay() { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } /******************************************************************** * 名称: bit Busy(void) * 功能: 这个是一个读状态函数,读出函数是否处在忙状态 * 输入: 输入的命令值 * 输出: 无 ***********************************************************************/ bit Busy(void) { bit busy_flag = 0; RS = 0; RW = 1; E = 1; delay(); busy_flag = (bit)(P0 & 0x80); E = 0; return busy_flag; } /******************************************************************** * 名称: wcmd(uchar del) * 功能: 1602命令函数 * 输入: 输入的命令值 * 输出: 无 ***********************************************************************/ void wcmd(uchar del) { while(Busy()); RS = 0; RW = 0; E = 0; delay(); P0 = del; delay(); E = 1;

单片机按键连接方法

单片机按键连接方法总结(五种按键扩展方案详细介绍) 单片机在各种领域运用相当广泛,而作为人机交流的按键设计也有很多种。不同的设计方法,有着不同的优缺点。而又由于单片机I/O资源有限,如何用最少的I/O口扩展更多的按键是我所研究的问题。接下来我给大家展示几种自己觉得比较好的按键扩展方案,大家可以在以后的单片机电路设计中灵活运用。 1)、第一种是最为常见的,也就是一个I/O口对应一个按钮开关。 这种方案是一对一的,一个I/O口对应一个按键。这里P00到P04,都外接了一个上拉电阻,在没有开关按下的时候,是高电平,一旦有按键按下,就被拉成低电平。这种方案优点是电路简单可靠,程序设计也很简单。缺点是占用I/O资源多。如果单片机资源够多,不紧缺,推荐使用这种方案。 2)、第二种方案也比较常见,但是比第一种的资源利用率要高,硬件电路也不复杂。 这是一种矩阵式键盘,用8个I/O控制了16个按钮开关,优点显而易见。当然这种电路的程序设计相对也还是很简单的。由P00到P03循环输出低电平,然后检测P04到P07的状态。比方说这里P00到P03口输出1000,然后检测P04到P07,如果P04为1则说明按下的键为s1,如果P05为1则说明按下的是s2等等。为了电路的可靠,也可以和第一种方案一样加上上拉电阻。 3)、第三种是我自己搞的一种方案,可以使用4个I/O控制8个按键,电路多了一些二极管,稍微复杂了一点。 这个电路的原理很简单,就是利用二极管的单向导电性。也是和上面的方案一样,程序需要采用轮训的方法。比方说,先置P00到P03都为低电平,然后把P00置为高电平,接着查询P02和P03的状态,如果P02为高则说明按下的是s5,若P03为高则说明按下的是s6,然后再让P00为低,P01为高,同样检测P02和P03的状态。接下来分别让P02和P03为高,其他为低,分别检测P00和P01的状态,然后再做判断。这种方案的程序其实也不难。 4)这是我在一本书上看到的,感觉设计的非常巧妙,同样它也用到了二极管,不过比我的上一种方案的I/O利用率更高,他用4个I/O口控制了12个按键。我相信你了解了之后也会惊奇的。 首先好好品味一下这个方案吧,想想怎么来识别按键呢!

单片机4X4键盘扫描和显示课程设计

二、设计内容 1、本设计利用各种器件设计,并利用原理图将8255单元与键盘及数码管显示单元连接,扫描键盘输入,最后将扫描结果送入数码管显示。键盘采用4*4键盘,每个数码管可以显示0-F共16个数。将键盘编号,记作0-F,当没按下其中一个键时,将该按键对应的编号在一个数码管上显示出来,当在按下一个 键时,便将这个按键的编号在下一个数码管上显示,数码管上 可以显示最近6次按下的按键编号。 设计并实现一4×4键盘的接口,并在两个数码管上显示键盘所在的行与列。 三、问题分析及方案的提出 4×4键盘的每个按键均和单片机的P1口的两条相连。若没有按键按下时,单片机P1口读得的引脚电平为“1”;若某一按键被按下,则该键所对应的端口线变为地电平。单片机定时对P1口进行程序查询,即可发现键盘上是否有按键按下以及哪个按键被按下。 实现4×4键盘的接口需要用到单片机并编写相应的程序来识别键盘的十六个按键中哪个按键被按下。因为此题目还要求将被按下的按键显示出来,因此可以用两个数码管来分别显示被按下的按键的行与列

表示任意一个十六进制数)分别表示键盘的第二行、第三行、第四行;0xXE、0xXD、0xXB、0xX7(X表示任意一个十六进制数)则分别表示键盘的第一列、第二列、第三列和第四列。例如0xD7是键盘的第二行第四列的按键 对于数码管的连接,采用了共阳极的接法,其下拉电阻应保证芯片不会因为电流过大而烧坏。 五、电路设计及功能说明 4×4键盘的十六个按键分成四行四列分别于P1端口的八条I/O 数据线相连;两个七段数码管分别与单片机的P0口和P2口的低七 位I/O数据线相连。数码管采用共阳极的接法,所以需要下拉电阻 来分流。结合软件程序,即可实现4×4键盘的接口及显示的设计。 当按下键盘其中的一个按键时,数码管上会显示出该按键在4×4键 盘上的行值和列值。所以实现了数码管显示按键位置的功能 四、设计思路及原因 对于4×4键盘,共有十六个按键。如果每个按键与单片机的一个引脚相连,就会占用16个引脚,这样会使的单片机的接口不够用(即使够用,也是对单片机端口的极大浪费)。因此我们应该行列式的接法。行列式非编码键盘是一种把所有按键排列成行列矩阵的键盘。在这种键若没有按键按下时,单片机从P1口读得的引脚电平为“1”;若某一按键被按下,则该键所对应的端口线变为地电平。因此0xEX(X表示任意4×4键盘的第一行中的某个按键被按下,相应的0xDX、0xBX、0x7X(X 二、实验内容

单片机按键扫描数码管显示C语言程序

单片机按键扫描数码管显示C语言程序按键扫描数码管显示程序共定义了6个键的功能:K1、K 2、K 3、K4以及K 5、K8组成的一对复合键,其中K2,K3为连击键,K5为上档键。在正常工作模式下按K1则切换至状态,在设定模式下按K1键循环选择4个数码管中的某个,被选中的数码管闪烁,此时单按K2键显示数值加1;常按K2显示数值以一定速度递增,同时数码管停止闪烁,当K2松开,数码管恢复闪烁,显示数值停留在K2松开前的值上。K3完成的功能和K2类似。其完成减操作。这2个键只有在设定状态才有效,可以有效防止误操作。K4为确认键,按下该键回到正常显示状态,所有指示灯熄灭,数码管显示刚刚设定的数值。K5+K8这对复合键执行复位操作,任何情况下同时按下K5和K8或先按下K5再按下K8,所有数码管的显示全为0,指示灯全灭,进入正常显示状态。同时程序还对如下几个异常操作进行了处理: 1. 2个或多个功能键同时按下 2.一个功能键按下未释放,又按另一个功能键,然后再松开其中一个功能键 3.先按下功能键再按下上档键 4.多个上档键和一个功能键同时按下,此时不做处理。等到松开其他上档键,只剩下一个上 5.档键和一个功能键时才执行这对复合键;或松开所有上档键,处理单一功能键。 /***************************************************************** **************/ #include #include

#define uchar unsigned char #define uint unsigned int #define RCtrl 0x20 //定义上挡键第5键 #define RConti 0xfe //定义连击键第6键 #define N 2 //去抖年龄下限 #define MaxRate 50 //重复前的延迟值600ms #define MinRate 20 //重复速度240ms #define leddark 83 //闪烁时灭时间1s #define ledshow 83 //闪烁时亮时间1s #define decimal 0x80 //小数点的段数 #define KEY_DDR DDRC #define KEY_PORTO PORTC #define KEY_PORTI PINC #define OUT 0x3f #define IN 0xc0 #define KeyValue 0x3f #define LEDD_DDR DDRB #define LEDD_PORTO PORTB #define LEDS_DDR DDRD #define LEDS_PORTO PORTD #define LEDS_MASK 0xfc

按键消抖与时间按键

按键消抖与时间按键 这篇文章写给正在学51单片机的或者刚入门51单片机准备进阶的的朋友,我们来着重讨论一下按键消抖和时间按键这两项。 我们常用的按键大多都是机械的,机械开关就会出现机械振动,这个由物理学或者实验可以推出来,抖动会在单片机上面出现重复扫描次数,次数多少与单片机的时钟晶振有关,时钟晶振越高单片机执行速度越快,重复次数就越多 整个按键数百ms 按下瞬间,抖动时间大概10ms 弹起瞬间,抖动大概10ms 按键一次出现的电平变化 (上面的时间都是老师说的和书上现成的,没有实际测试,而且不同的按键应该也会有差异,作为学习研究确实不应该,找个时间锅锅会测出这个时间供大家参考,嘿嘿) 由图我们可以看出,按下去瞬间会出现抖动,弹起来也会出现抖动,明显是个阻尼振动,按键扫描程序是按顺序执行的; 首先提出三个问题大家思考一下 1.为什么要消除抖动 2.如何消抖 3.是不是按键都要消抖,不是的话,哪些需要消抖,哪些不需要消抖 4.消抖的时间是不是必须10ms 5.按键消抖的方式是不是一定像书上的那样,如何消抖更节省CPU,且更简单 按键如果不消除抖动,那么单片机检测到的低电平的次数就不止一次,那我们按键一次,单片机会检测到多次,比如我们把按某个按键设置按一次成某个变量加1,结果按一次就加了很多次,这样我们就不能精确的通过按键来调整我们想要的参数,所以我们消除抖动的目的就是要实现按一次按键让单片机读出一次按键操作 消抖分硬件和软件消抖, 硬件消抖有《模拟电子技术》上提到用三态门实现,当然还有周立功那个7920(管理数码管和按键的芯片),当然还有很多硬件电路以及一些按键有自带消抖电路,但是如果要做产

第六课按键的硬件消抖

51单片机进阶篇 ---按键的硬件消抖 本文作者:Cepark 更新时间:2010/07/20 作者博客:https://www.doczj.com/doc/2f15632929.html,

按键的硬件消抖 在上一节课中,我们介绍了使用软件延时的方法来进行消抖从而进行按键的检测,软件延时的优点是硬件电路简单,但是程序相对来讲会复杂,而且一般的延时函数是使用计数延时,这会增加CPU的负担。硬件消抖电路可以简化程序的编写,但是需要额外的器件支持。两种方法各有利弊,在不同的情况下根据不同的情况来选择使用哪一种消抖方法,这一节课我们主要介绍一下常见的硬件消抖电路。 1、RS触发器构成的消抖电路的主要原理 用R-S触发器形成消抖电路时单片机外围电路设计中的常用手段,它可以减少单片机软件对按键动作的延时和计算。要使用R-S触发器形成的消抖电路,首先用了解R-S触发器的基本工作原理图和工作特点。 R-S触发器的基本构成如图所示,它是由两个与非门交叉耦合而成,S和R是信号的输 Q既表示触发器的状态,又是触发器的输出端。 入端,低电平有效,Q和 在启动过程中,S端一旦下降到开门电平,Q端电平就会上升,反馈到门B的输入端, Q端的电平下降,反馈到门A的输入端,进一步促使门A截止,促使B由截止转向导通, Q的电平进一步下降,这样的过程,是Q端电平进一步上升,Q端电平上升的结果又会使 的门A很快截止、门B很快导通,触发器在极短的时间内完成由截止到导通的转换。通过R 段的复位时也有类似的正反馈过程发生,从而完成按键开关的消抖功能。 典型的硬件消抖方法是在单片机和检测管脚之间加入由74LS02或者其他的门电路组成的R-S触发器消抖电路。如下所示。

51单片机矩阵键盘扫描程序

/*----------------------------------------------- 名称:矩阵键盘依次输入控制使用行列逐级扫描 论坛:https://www.doczj.com/doc/2f15632929.html, 编写:shifang 日期:2009.5 修改:无 内容:如计算器输入数据形式相同从右至左使用行列扫描方法 ------------------------------------------------*/ #include //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 #define DataPort P0 //定义数据端口程序中遇到DataPort 则用P0 替换 #define KeyPort P1 sbit LATCH1=P2^2;//定义锁存使能端口段锁存 sbit LATCH2=P2^3;// 位锁存 unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码 unsigned char TempData[8]; //存储显示值的全局变量 void DelayUs2x(unsigned char t);//us级延时函数声明 void DelayMs(unsigned char t); //ms级延时 void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数 unsigned char KeyScan(void);//键盘扫描 unsigned char KeyPro(void); void Init_Timer0(void);//定时器初始化 /*------------------------------------------------ 主函数 ------------------------------------------------*/ void main (void) { unsigned char num,i,j; unsigned char temp[8]; Init_Timer0(); while (1) //主循环 { num=KeyPro();

单片机与4x4键盘去抖松手检测程序

单片机与4x4键盘去抖松手检测程序 刚写的一个4*4 键盘,去抖 松手检测程序。项目中要用4*4 键盘,扫描的程序有。但是去抖,和松手检测的程序没有,那么为了提高效率,可靠性,以及更加合理化。到网上找了一些关于”状态机“的资料,按照它的思路写了一个,写了半天,写好一个,经过特发帖纪录一下。 //对按键扫描的值进行处理去抖松手检测 uint8_t key_scan(void) { static uint8_t key_state = 0; static uint8_t key_num_flag1=0; uint8_t temp_key_num=0; uint8_t return_key_num=0; temp_key_num=KeyMap();//读取4*4 键盘返回的按键值不要去抖 switch(key_state)//检测状态

case key_state_0: if(temp_key_num!=0) //如果按键返回不是0 说明有按键按下 { key_num_flag1=temp_key_num; //记录下第一次按键按下的值 key_state=key_state_1; //进入下一个状态去抖 } break; case key_state_1: if(temp_key_num!=0) //如果按键返回不是0 说明按键是按下的 { if(key_num_flag1==temp_key_num)//判断是否和上次记录按键值一样。 {

return_key_num=temp_key_num; // 按键仍按下,赋值给返回按键值 key_state = key_state_2; // 状态转换到键释放态 } else { key_state=key_state_0; //回到初始状态 } } else ///没有按键按下 {

关于单片机按键的抖动与消抖

关于单片机按键的抖动与消抖 在单片机的程序中,如果涉及到按键,一般都会看到几行注释着消抖 的代码。比如下面这一段:if((KeyV|0xc3)==0xff){//无键按下return 0; } mDelay(10);//延时,去键抖KeyV=P3; if((KeyV|0xc3)==0xff){//无键按下return 0; } 关于其作用与目的,有如下解释:按键在按下时会产生电平的变化,通常是由高电平变为低电平,而且这一过程也不是瞬间完成的,按键按下之后, 电平会有一段不稳定变化的时间。一般情况下,我们的程序读取这个电平变化 并做相关的动作。但由于机械按键的局限性,当系统受到外力而产生抖动或其 它动作时,也可能使系统内部产生电平变化(通常这种变化持续的时间非常短),这种现象称之为按键的抖动。这种抖动显然不是我们期望出现的,一旦程序中没有针对它进行特殊处理,这种隐患很可能导致系统执行我们不希望出现 的动作。进而可能酿成一场悲剧。避免按键抖动的操作就称之为消抖。目前,单片机的消抖主要分为软件消抖和硬件消抖。其中,软件消抖增加软件资源,但不增加硬件成本;硬件消抖反之。现在普遍采用的是软件消抖的方式。软件消抖具体的操作思路是:当监听到按键被按下时,不立刻执行相关的操作,而进行一定时间的延时(通常是50ms),之后再次检测按键是否被按下,如果 此时按键仍然被按下,则判定按键确实被按下了(因为不论是异常情况导致的 抖动还是正常情况下按键被按下产生的电平变化都会在这一段时间内过去,紧 接着的电平将会是稳定的),然后进行按键被按下之后所需要的操作,否则判 定按键未被按下,继续监听按键状态。实际上,以上所说的软件消抖的方法在 真正的软件中应用的不多,只是在练习的时候使用。真正的应用上,会在可能 产生抖动的那一段时间内等间隔多次监听按键状态(电流状态),等到数次 (可以是连续5 次)电流平稳了才确定按键被按下。按键被放开时采取同样操

实验七 单片机键盘LED显示实验

实验七单片机键盘LED显示实验 一、实验目的 1、掌握键盘和LED显示器的接口方法和编程方法。 2、掌握键盘扫描和LED八段码显示器的工作原理。 3、学习并口扩展的程序编写方法。 二、实验说明 利用实验仪提供的键盘扫描电路和显示电路,做一个扫描键盘和数码显示实验,把按键输入的键码在六位数码管上显示出来。 实验程序可分成三个模块。 ①键输入模块:扫描键盘、读取一次键盘并将键值存入键值缓冲单元。 ②显示模块:将显示单元的内容在显示器上动态显示。 ③主程序:调用键输入模块和显示模块。 三、实验仪器 计算机 伟福实验箱(lab2000P ) 四、实验内容 1、本实验仪提供了一个6×4的小键盘,向列扫描码地址(0X002H)逐列输出低电平,然后从行码地址(0X001H)读回。如果有键按下,则相应行的值应为低,如果无键按下,由于上拉的作用,行码为高。这样就可以通过输出的列码和读取的行码来判断按下的是什么键。在判断有键按下后,要有一定的延时,防止键盘抖动。地址中的X是由KEY/LED CS 决定,参见地址译码。做键盘和LED实验时,需将KEY/LED CS 接到相应的地址译码上。以便用相应的地址来访问。例如将KEY/LED CS信号接CS0上,则列扫描地址为08002H,行码地址为08001H。列扫描码还可以分时用作LED的位选通信号。 2、本实验仪提供了6 位8段码LED显示电路,只要按地址输出相应数据,就可以实现对显示器的控制。显示共有6位,用动态方式显示。8位段码、6位位码是由两片74LS374输出。位码经MC1413或ULN2003倒相驱动后,选择相应显示位。 3、本实验仪中8位段码输出地址为0X004H,位码输出地址为0X002H。此处X是由KEY/LED CS 决定,参见地址译码。做键盘和LED实验时,需将KEY/LED CS 接到相应的地址译码上。以便用相应的地址来访问。例如,将KEY/LED CS 接到CS0上,则段码地址为08004H,位码地址为08002H。 五、思考题 1、按键接收到的数据加1显示出来; 2、实现第2功能键,即按下A后,再按下0-9键为加1显示; 3、保存前一个接收到的数据,数据向前推动显示。 六、源程序修改原理及其仿真结果 原程序: OUTBIT equ 08002h ; 位控制口 OUTSEG equ 08004h ; 段控制口 IN equ 08001h ; 键盘读入口 LEDBuf equ 60h ; 显示缓冲 ljmp Start

按键处理程序 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; } } else Key.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去抖动

单片机实验--键盘扫描

实验 4 键盘实验 一、实验目的: 1.掌握 8255A 编程原理。 2.了解键盘电路的工作原理。 3.掌握键盘接口电路的编程方法。 二、实验设备: CPU 挂箱、 8031CPU 模块 三、实验原理: 1.识别键的闭合,通常采用行扫描法和行反转法。 行扫描法是使键盘上某一行线为低电平,而其余行接高电平,然后读取列值,如所读列值中某位为低电平,表明有键按下,否则扫描下一行,直到扫完所有行。 本实验例程采用的是行反转法。 行反转法识别键闭合时,要将行线接一并行口,先让它工作于输出方式,将列线也接到一个并行口,先让它工作于输入方式,程序使 CPU 通过输出端口往各行线上全部送低电平,然后读入列线值,如此时有某键被按下,则必定会使某一列线值为 0。然后,程序对两个并行端口进行方式设置,使行线工作于输入方式,列线工作于输出方式,并将刚才读得的列线值从列线所接的并行端口输出,再读取行线上的输入值,那么,在闭合键所在的行线上的值必定为 0 。这样,当一个键被按下时,必定可以读得一对唯一的行线值和列线值。 2.程序设计时,要学会灵活地对8255A 的各端口进行方式设置。 3.程序设计时,可将各键对应的键值(行线值、列线值)放在一个表中,将要显示的 0?F字符放在另一个表中,通过查表来确定按下的是哪一个键并正确显示出来。 实验题目 利用实验箱上的 8255A 可编程并行接口芯片和矩阵键盘,编写程序,做到在键盘上每 按一个数字键(0?F),用发光二极管将该代码显示出来。 四、实验步骤: 将键盘 RL10 ? RL17 接 8255A 的 PB0 ? PB7;KA10 ? KA12 接 8255A 的 PA0? PA2; PC0?PC7接发光二极管的 L1?L8 ; 8255A 芯片的片选信号 8255CS接CS0。 五、实验电路:

第13讲51单片机按键电路

标题:键盘接口电路 教学目标与要求: 1.键盘去抖动和连接、控制方式 2.独立式按键及其接口电路 3.矩阵式键盘及其接口电路 授课时数:2 教学重点:.矩阵式键盘及其接口电路 教学内容及过程: 一、键盘接口概述 1、按键开关去抖动问题 机械式按键再按下或释放时,由于机械弹性作用的影响,通常伴随有一定时间的触点机械抖动,然后其触点才稳定下来。其抖动过程如图9-11所示,抖动时间的长短与开关的机械特性有关,一般为5 10 ms 在触点抖动期间检测按键的通与断状态,可能导致判断出错,即按键一次按下或释放被错误地认为是多次操作,这种情况是不允许出现的。为了克服按键触点机械抖动所致的检测误判,必须采取去抖动措施。这一点可从硬件、软件两方面予以考虑。在键数较少时,可采用硬件去抖,而当键数较多时,采用软件去抖。在硬件上可采用在键输出端加R-S触发器(双稳态触发器)或单稳态触发器构成去抖动电路。图9-12是一种由R-S触发器构成的去抖动电路,当触发器一旦翻转,触点抖动不会对其产生任何影响。 软件上采取的措施是:在检测到有按键按下时,执行一个10 ms左右(具体时间应视所使用的按键进行调整)的延时程序后,再确认该键电平是否仍保持闭合状态电平,若仍保持闭合状态电平,则确认该键处于闭合状态。同理,在检测到该键释放后,也应采用相同的步 骤进行确认,从而可消除抖动的影响。

2.编制键盘程序 一个完善的键盘控制程序应具备以下功能: (1) 检测有无按键按下,并采取硬件或软件措施,消除键盘按键机械触点抖动的影响。 (2) 有可靠的逻辑处理办法。每次只处理一个按键,其间对任何按键的操作对系统不产生影响,且无论一次按键时间有多长,系统仅执行一次按键功能程序。 (3) 准确输出按键值(或键号),以满足跳转指令要求。 二、独立式按键 单片机控制系统中,往往只需要几个功能键,此时,可采用独立式按键结构。 1. 独立式按键结构 独立式按键是直接用I/O口线构成的单个按键电路,其特点是每个按键单独占用一根I/O口线,每个按键的工作不会影响其它I/O口线的状态。独立式按键的典型应用如图7.4所示。 独立式按键电路配置灵活,软件结构简单,但每个按键必须占用一根I/O口线,因此,在按键较多时,I/O口线浪费较大,不宜采用。 2.矩阵式键盘 I/O端线分为行线和列线,按键跨接在行线和列线上,按键按下时,行线与列线发生短路。特点: ①占用I/O端线较少; ②软件结构教复杂。 适用于按键较多的场合。 3.键盘扫描控制方式 ⑴程序控制扫描方式 键处理程序固定在主程序的某个程序段。 特点:对CPU工作影响小,但应考虑键盘处理程序的运行间隔周期不能太长,否则会影响对键输入响应的及时性。 ⑵定时控制扫描方式 利用定时/计数器每隔一段时间产生定时中断,CPU响应中断后对键盘进行扫描。 特点:与程序控制扫描方式的区别是,在扫描间隔时间内,前者用CPU工作程序填充,后者用定时/计数器定时控制。定时控制扫描方式也应考虑定时时间不能太长,否则会影响对键输入响应的及时性。 ⑶中断控制方式 中断控制方式是利用外部中断源,响应键输入信号。 特点:克服了前两种控制方式可能产生的空扫描和不能及时响应键输入的缺点,既能及时处理键输入,又能提高CPU运行效率,但要占用一个宝贵的中断资源。 三、独立式按键及其接口电路 1、按键直接与I/O口连接

单片机矩阵键盘行列扫描程序学习资料

//行列扫描程序,可以自己定义端口和扫描方式,这里做简单介绍 #include //包含头文件 #define uchar unsigned char #define uint unsigned int unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F uchar keyscan(void); void delay(uint i); void main() { uchar key; P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符 while(1) { key=keyscan();//调用键盘扫描, switch(key) { case 0x7e:P0=dofly[0];break;//0 按下相应的键显示相对应的码值 case 0x7d:P0=dofly[1];break;//1 case 0x7b:P0=dofly[2];break;//2 case 0x77:P0=dofly[3];break;//3 case 0xbe:P0=dofly[4];break;//4 case 0xbd:P0=dofly[5];break;//5 case 0xbb:P0=dofly[6];break;//6 case 0xb7:P0=dofly[7];break;//7 case 0xde:P0=dofly[8];break;//8 case 0xdd:P0=dofly[9];break;//9 case 0xdb:P0=dofly[10];break;//a case 0xd7:P0=dofly[11];break;//b case 0xee:P0=dofly[12];break;//c case 0xed:P0=dofly[13];break;//d case 0xeb:P0=dofly[14];break;//e case 0xe7:P0=dofly[15];break;//f } } } uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法 {

相关主题
文本预览
相关文档 最新文档