12单片机外部中断,读取按键。并在数码管上显示
工具/原料
硬件:单片机,按键,数码管等
软件:keil ,usbisp下载工具
硬件平台搭建
1、首先搭建数码管硬件平台,及软件显示代码。
2、在上面的平台基础上 ,焊接两个按键,按键的一端接地。一个按键的一端接到P32引脚上,一个按键的一端接到P33引脚上。如果有开发板会更好一些,硬件上会有消抖处理。
下降沿中断方式
1、所谓的下降沿,即指P32引脚上一个周期是高电平,这个周期是低电平的话,如果开启中断的话就会响应中断。
2、中断初始化函数书写:void INT_Init(void){ IT0 =1 ; IT1 =1; //下降沿触发方式 EX0 = 1; EX1 = 1; //启动外部中断0,1 EA = 1; //使能所有中断}函数分析:(1)、上面所使用的寄存器是可以位寻址的 ,具体的寄存器地址参 数,可以查看数据手册(宏晶的比较详细)。 (2)、一般初始化代码的编写,先设置参数,然后在进行使能开启。
3、中断处理函数书写:void INT0_Text() interrupt 0 using 0{罕铞泱殳 EA = 0; D髫潋啜缅elay10ms(); if(P32==0) Dig_Index++; EA = 1;}函数分析:(1)、INT0_Text() 中断函数的名字 (2)、interrupt 0 声明这个函数用的是0号中断,也就是外部中断 0。这个的顺序是按照我们的中断源地址进行排序的 interrupt 是keil的关键字。 (3)、using 0 表示使用的寄存器组,也是一个关键字 (4)、进入中断处理函数,首先关闭中断,然后延时一段时间在检 测一下引脚是否还保持低电平。 如果保持低电平就说明此次 按键是有效按键,然后对Dig_Index进行自加一,然后退出 中断处理函数。
4、整体处理函墙绅褡孛数:#include"aconf.h"int Dig_Index ;即枢潋雳void main() { P0M0 = 0xff; P0M1 = 0x00; P2M0 = 0x00; P2M1 = 0x00; P3M0 = 0x00; P3M1 = 0x00; Dig_Index = 2; INT_Init(); while(1) { Dig_OutPut(Dig_Index); }}void INT_Init(void){ IT0 = 1; IT1 = 1 ; EX0 = 1; EX1 = 1; EA = 1; }void INT0_Text() interrupt 0 using 0{ EA = 0; Delay10ms(); if(P32==0) Dig_Index++; EA = 1;}void INT1_Text() interrupt 2 using 2{ EA = 0; Delay10ms(); if(P33==0) Dig_Index--; EA = 1;}整体分析:(1)、头文件的包含,一遍调用其他文件的函数 (2)、int Dig_Index ;定义一个全局变量,这个实验就是通过两个 按键对这个变量增减后,然后通过数码管对这个数进行显示 (3)、中断初始化函数调用,启动中断。 (4)、数码管采用动态扫描的方式,所以调用显示函数要循环的调 用。关键点:在于延时消抖。
中断低电平触发:
1、低电平触发需要实现的功能:(1)、单击增减一 (2)、持续按键,快速增减。
2、中断函数初始化:void INT_Init(void){ IT0 =0 ; IT1 =0 ; EX0 = 1; EX1 = 1; EA = 1; }这个初始化函数,和下降沿的方式一样,只是将参数设置成低电平处理方式。
3、中断处理函数:void INT0_Text() interrupt 0 using 0{ 苇质缵爨EA = 0;//判断按键是单次按键还是持续按键艘早祓胂 if(P32 == 0) Dig_Jndex++;else Dig_Jndex=0; //判断按键是单次按键还是持续按键 if(Dig_Jndex>=10)//持续按键处理 { Delay1ms(); Dig_Index++; Dig_OutPut(Dig_Index); } else //单次按键 { Delay100ms(); Dig_Index++; Dig_OutPut(Dig_Index); } EA = 1;}函数分析:(1)、我们通过增加一个全局变量来判断按键的接通时间, 如果接通接近2秒的话 就是持续按键。否则是单次按键。 (2)、可以分析一下首先进入这个函数 Dig_Jndex就会自加1. 这个时候执行单次按键处理,这段代码加上显示函数,加上 延时大约是150ms,我们需要执行10次后,才能定义此按键 持续性按键。也就是大约2秒。 (3)、对于这个变量我们需要进行清0,函数在主函数里。 (4)、和下降沿处理函数对比发现这里增加了显示函数,如果不 增加,由于延时函数过多,而且低电平触发 是频繁触发, 会导致显示不正常。关键点:在于如果判断按键的时间,以及处理显示卡顿闪烁等现象。
4、#include"aconf.h"int Dig_I艘绒庳焰ndex ;int Dig_Jndex ;void m锾攒揉敫ain() { P0M0 = 0xff; P0M1 = 0x00; P2M0 = 0x00; P2M1 = 0x00; P3M0 = 0x00; P3M1 = 0x00; Dig_Index = 2; INT_Init(); while(1) { if((P32 == 1)&&(P33 == 1)) { Delay1ms(); if((P32 == 1)&&(P33 == 1)) Dig_Jndex=0; } Dig_OutPut(Dig_Index); }}void INT_Init(void){ IT0 =0 ; IT1 =0 ; EX0 = 1; EX1 = 1; EA = 1; }void INT0_Text() interrupt 0 using 0{ EA = 0; //P32 = 1; //Delay1ms(); if(P32 == 0) Dig_Jndex++; else Dig_Jndex=0; if(Dig_Jndex>=10) { Delay1ms(); Dig_Index++; Dig_OutPut(Dig_Index); } else { Delay100ms(); Dig_Index++; Dig_OutPut(Dig_Index); } EA = 1;}void INT1_Text() interrupt 2 using 2{ EA = 0; if(P33 == 0) Dig_Jndex++; else Dig_Jndex=0; if(Dig_Jndex>=10) { Delay1ms(); Dig_Index--; Dig_OutPut(Dig_Index); } else { Delay100ms(); Dig_Index--; Dig_OutPut(Dig_Index); } EA = 1;}主函数:(1)、差别就是增加了对 按键类型 判断全局变量清零 (2)、以及就是对于持续按键,显示的处理。
5、http://pan.baidu.com/s/1eSJXksU源码的连接 (包含 数码管的驱动。)
6、实际运行效果