单片机按键的解决方法_第1页
单片机按键的解决方法_第2页
单片机按键的解决方法_第3页
单片机按键的解决方法_第4页
单片机按键的解决方法_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、单片机按键的解决解决方案1、 单片机上的按键控制一般采用两种控制方法:中断和查询。中断必须借助中断引脚,而查询按键可用任何IO端口。按键较少时,一个按键占用一个端口,而按键较多时,多采用矩阵形式(如:经常用4个端口作为输出,4个端口作为输入的4X4矩阵来获得16个按键);还可以用单片机的AD转换功能一个引脚接多个按键,根据电阻分压原理判断是哪个按键按下。2、 中断形式STM32可支持68个中断通道,已经固定分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n(8位,但是STM32中只使用4位,高4位有效),每4个通道的8位中断优先级控制字构成一个32位的优先级寄存器。68

2、个通道的优先级控制字至少构成17个32位的优先级寄存器.4bit的中断优先级可以分成2组,从高位看,前面定义的是抢占式优先级,后面是响应优先级。按照这种分组,4bit一共可以分成5组 第0组:所有4bit用于指定响应优先级; 第1组:最高1位用于指定抢占式优先级,后面3位用于指定响应优先级; 第2组:最高2位用于指定抢占式优先级,后面2位用于指定响应优先级; 第3组:最高3位用于指定抢占式优先级,后面1位用于指定响应优先级; 第4组:所有4位用于指定抢占式优先级。所谓抢占式优先级和响应优先级,他们之间的关系是:具有高抢占式优先级的中断可以在具有

3、低抢占式优先级的中断处理过程中被响应,即中断嵌套。当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。每一个中断源都必须定义2个优先级。有几点需要注意的是: 1)如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果; 2)抢占式优先级别相同的中断源之间没有嵌

4、套关系;3)如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。GPIO外部中断:STM32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间智能使用一个,如:PA0,PB0,PC0,PD0,PE0,PF0这些为1组,如果我们使用PA0作为外部中断源,那么别的就不能使用了,在此情况下我们使用类似于PB1,PC2这种末端序号不同的外部中断源,每一组使用一个中断标志EXTI x.EXTI0EXTI4这5个外部中断有着自己单独的中断响应函数。EXTI5EXTI9共用一

5、个中断响应函数,EXTI10EXTI15共使用一个中断响应函数。对于中断的控制,STM32有一个专用的管理机构NVIC.中断的使能,挂起,优先级,活动等等都是由NVIC在管理的。编写IO口外部中断步骤及其注意事项:(1) 设置中断优先级组;(2)开启时钟(IO口时钟,复用时钟);(3)设置中断线并对中断进行初始化配置(设置中断线,确定中断模式,中断触发沿设置,使用指定设置初始化外部中断);(4)设置中断管理器NVIC各参数(包括:使能产生外部中断外设的IO口所在的外部中断通道;设置外部中断的优先级-抢占优先级,响应优先级;使能外部中断通道;使用设置好的各个中断管理器上的参数来初始化中断管理器)

6、。外部中断服务函数完成中断操作需要最终达到的目标。3、 矩阵形式键盘矩阵原理:a*b矩阵键盘由a条行线和b条列线组成,行线接端口P3(p3表任一端口)P3.0、P3.1、P3.2p3.(a-1);列线接p 3.a,p3.(a+1)P3.(b-1).按键位于每条行线和列线的交叉点上。按键的识别可采用行扫描法和线反转法,这里采用简单的线反转法,只需三步。第一步,执行程序使X0X3均为低电平,此时读取各列线Y0Y3的状态即可知道是否有键按下。当无键按下时,各行线与各列线相互断开,各列线仍保持为高电平;当有键按下时,则相应的行线与列线通过该按键相连,该列线就变为低电平,此时读取Y0Y1Y2Y3的状态,

7、得到列码。第二步,执行程序使Y0Y3均为低电平,当有键按下时,X0X3中有一条行线为低电平,其余行线为高电平,读取X0X1X2X3的状态,得到行码。第三步,将第一步得到的列码和第二步得到的行码合并得到按键的位置码,即是Y3Y2Y1Y0X3X2X1X0(因为行线和列线各有一条电平,其余为高电平,所以位置码低四位和高四位分别只有一位低电平,其余为高电平)。也就是说,当某个键按下时,该键两端所对应的行线和列线为低电平,其余行线和列线为高电平.比如,当0键按下时,行线X0和列线Y0为低电平,其余行列线为高电平,于是可以得到0键的位置码Y3Y2Y1Y0x3X2X1X0为11101110即是0xEE.全部

8、按键码为: 矩阵键盘在单片机上的简单应用-显示数码管:0F(51单片机) #include<reg51.h> #define uchar unsigned char#define uint unsigned intSbit buzzer =P10;Uchar code_dis=/09,AF 0xC0,0XF9,0XA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x90,0z88,0x83,0xC6,0xA1,0x86,0x8E;Uchar code_tab=/矩阵键盘按键位置码 0x77,0xb7,0xd7,0xe7, 0x7b,0xbb,0xdb,0xeb,0

9、x7d,0xbd,0xdd,0xed,0x7e,0xbe,0xde,0xee;void delay(uint x) /延时函数uchar i; while(x-) for(i=0;i<120;i+); uchar scan()/矩阵键盘扫描函数,得到按键号,采用线反转法 uchar a,b,c,i; P3=0XF0; /P3口输出11110000 a=P3; /读取列码delay(10); /防抖延时10ms P3=0X0F; /P3口输出00001111 b=P3; /读取行码c=a+b;/得到位置码for(i=0;i<16;i+) if(c=tabi)return i; /查表

10、得到按键序号并返回 return -1; /无按键,则返回-1Void beep(void)/蜂鸣器发出声音,模拟按键声音 Uchar i; For(i=0;i<100;i+)Buzzer=buzzer;Delay(1);Buzzer=0;Void main(void) uchar key; buzzer=0; /关闭蜂鸣器while(1) key=scan(); /得到按键号if(key!=-1)/有按键则显示,并且蜂鸣器发出声音 P0=diskey; beep(); delay(100); 扫描法:矩阵键盘工作原理:由于按键没有接地,4行  4列正好占用8个I/O 

11、; 如果4行我们送 P3.0到P3.3送入0 1 1 1 然后去读取 4列的值,如果P3.0的按键按下那么P3.4-P3.7的值等于 0 1 1 1,假如是第2个键按下的话那么读回来的值是 1 0 1 1 ,如果第3个键按下去读回来的值是 1 1 0 1 ,如果第4个键按下去读回来的值是 1 1 1 0 ,如果没有键按下去读回来就是1 1 1 1。  所以我们就根据读回来的值来判断按下去的是那个键。当然这是对P3.0这一行,因为矩阵键盘是扫描的,所以下次把P3.0 给1  P3.1 给0对第2行,陆续的第3 行第4行, 0111 1011 1101 11

12、10  而每次都去从新扫描一遍列值列有4个值,以确定是那个键按下。无论何时任何一个时间有一个按键被按下就跳出循环。当然不可能有2个键刚好一起按下你的手没有这么好的力度,就算有2个键一起按键,程序也有先后检测的顺序,只能检测一个后面的检测不到。P3 = 0XFE; /第一行给0temp ;定义个变量temp = P3 ;读回来  由于读需要先写1  因为P3= FE  已经把高4位给1了  所以能读了temp & oxf0   如果没有按键按下结果还是0xf0 .如果有键按下结果就不是0xf0了。num &#

13、160; 然后我们再定义一个变量 让它赋值给这个按下去的按键值。 一次类推把第一行赋值0 扫描一遍 然后把第2行赋值0扫描一遍.共扫描16遍。只要有键按下 就会得到一个值 num 就从1排到16. 共16个按键 4*4 的矩阵键盘。我再总结下思路:首先 低4位是行 共4行  分别把每行给0 低电平   就4次 0 1 1 1 、1 0 1 1 、 1 1 0 1 、1 1 1 0 对吧然后去检测高4位  4列啊 先不考虑极端情况,4列就4个按键只要按下一个 P3口的高4位就会有一个值。根据这个值就能判断是

14、那个键了。如:P3= 1111 1110   低四位是行先把第一行给0 有按键下的话 temp = P3 读回来  1101 1110 然后temp &  0xf0  与运算下就判断下还等于oxf0吗?如还等于就没有按下,如果不等于就肯定有按键按下。定义个变量让它等于这个不是0XF0的值,做个标记。依次类推。然后用这个思路写个程序吧!写的不太好看的不是很清楚只是做个参考吧,只要把思路理清楚就行了。是这样我们分别按这16个按键让它分别显示是第几个 比如 按下第一个数码管就显示1 第2个数码管就显示2,依次类推

15、。一直到 F  (为了方便让所有的数码管显示同一个数0-F)#include#define uint unsigned int#define uchar unsigned charsbit dula = P26;sbit wela = P27;sbit key1= P34;uchar code table =0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0/加这个0就是什么都不显示;uchar num,temp,num1;void delay(uint z) u

16、int x,y; for(x=z;x>0;x-)  for(y=110;y>0;y-);uchar keyscan();/声明一下/void display(uchar num1);/这里可以做个显示函数,但是我没做。void main()     num = 17;/让它显示0 什么都不显示。 因为函数返回num值     dula =1 ;     P0= 0;     dula =0;&#

17、160;    wela = 1;     P0= 0xc0;     wela = 0;      /以上P0口控制数码管的一上电什么都不显示   while(1)               num1 = keyscan();/没按下返回17 &

18、#160;             dula =1;               P0= tablenum1-1;/17-1 =16               dula = 0; 

19、0;            /用uchar keyscan() 带返回值的函数 代替整个矩阵键盘  当然显示就不要了 dula  那3行我注释掉了uchar keyscan()P3= 0xfe; /高4位是f 等于写了1 1 1 1 也满足了先写1的要求temp =P3;/读回来了temp &= 0xf0;/因为我们只是读回来高4位while (temp != 0xf0) /下面的几个while循环判断可以用if好理解。只看到第一行就行了。/这几个

20、while 都是做判断用的delay(5);/消除抖动的temp=P3;temp &= 0xf0;while(temp != 0xf0) /确实不等于0xf0有按键按下temp = P3;/我们这个时候只是把P3口的值赋给了tempswitch (temp) /检测P3口。  case 0xee:      num = 1;   break;  case 0xde:       

21、num=2; break;  case 0xbe:      num=3;   break;  case 0x7e:    num=4; break;    while(temp != 0xf0)/有按键按下可能是不等于的   循环在这里面  松手检测   temp = P3;  temp = temp & 0xf0; /这个是松

22、手检测  松手这里就等于了0xf0  /下面就显示一下  退出整个一行的循环,不加松手检测会退不出去循环/到这里是把第一行检测了。/以下下是其他几行检测的代码P3= 0xfd; /高4位是f 等于写了1 1 1 1 也满足了先写1的要求temp =P3;/读回来temp &= 0xf0;/因为我们只是读回来高4位while (temp != 0xf0) delay(5);/消除抖动的 temp=P3; temp &= 0xf0; while(temp != 0xf0) /确实不等于0xf0有按键按下

23、 temp = P3;/我们这个时候只是把P3口的值赋给了temp switch (temp) /检测P3口。  case 0xed:      num = 5;   break; case 0xdd:      num=6;break; case 0xbd:    num=7; break; case 0x7d:&#

24、160;     num=8;  break;  while(temp != 0xf0)/有按键按下可能是不等于的   循环在这里面  松手检测 temp = P3;temp = temp & 0xf0; /这个是松手检测  松手这里就等于了0xf0 /下面就显示一下  退出整个2行的循环。不加松手检测会退不出去循环 /到这里是把第2行检测了。       P

25、3= 0xfb; /高4位是f 等于写了1 1 1 1 也满足了先写1的要求       temp =P3;/读回来了       temp &= 0xf0;/因为我们只是读回来高4位       while (temp != 0xf0)            delay(5);/消除抖动的 

26、;           temp=P3;            temp &= 0xf0;          while(temp != 0xf0) /确实不等于0xf0有按键按下          &

27、#160;  temp = P3;/我们这个时候只是把P3口的值赋给了temp             switch (temp) /检测P3口。                  case 0xeb:        &

28、#160;             num =9;                       break;             

29、60;   case 0xdb:                      num=10;                     break;  &

30、#160;              case 0xbb:                     num=11;            &

31、#160;         break;                 case 0x7b:                    num=12;  

32、0;                 break;        while(temp != 0xf0)/有按键按下可能是不等于的   循环在这里面  松手检测  temp = P3;temp = temp & 0xf0; /这个是松手检测松手这里就等于了0xf0    

33、                  /下面就显示一下  退出整个3行的循环。  不加松手检测会退不出去循环    /到这里是把第3行检测了。                   

34、P3= 0xf7; /高4位是f 等于写了1 1 1 1 也满足了先写1的要求       temp =P3;/读回来了       temp &= 0xf0;/因为我们只是读回来高4位       while (temp != 0xf0)            delay(5);/消除抖动的

35、0;           temp=P3;            temp &= 0xf0;          while(temp != 0xf0) /确实不等于0xf0有按键按下         temp =

36、 P3;/我们这个时候只是把P3口的值赋给了temp switch (temp) /检测P3口                   case 0xe7:                      num =13

37、 ;                       break;                 case 0xd7:                      num=14;                   

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论