| 单片机新手,入门前的感悟第十篇。 
 终于看完中断了,理论知识还是比较好掌握的,感觉就是四个寄存器的设定。课本这章主要介绍了外部中断,先看这个用按键控制的一位LED数码管显示系统的程序
 #include <mega16.h>
 flash unsigned char led_7[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
 unsigned char counter;
 
 interrupt [EXT_INT0] void ext_int0_isr(void)
 {
 if (++counter>=16) counter=0;
 
 }
 
 
 interrupt [EXT_INT1] void ext_int1_isr(void)
 {
 if (counter) --counter;
 else counter=15;
 }
 
 
 void main(void)
 {
 PORTA=0xff;
 DDRA=0xff;
 GICR|=0xc0;      //使能INT0,INT1中断
 MCUCR=0x0a;     //INT0,INT1下降沿触发
 GIFR=0xc0;       //清除INT0,INT1中断标志位
 counter=0;      //计数单元初始化为0
 #asm("sei")        //使能全局中断
 
 while (1)
 {
 PORTA=led_7[counter];
 };
 }
 但是接到单片机上一试,发现反映太灵敏,按一下,数变好多次,读完第九章键盘输入接口与状态机设计,知道这是因为按键的时候有抖动,有硬件和软件两种方式,由于我现在主要学软件,给大家介绍一下软件消抖的方案
 #include <mega16.h>
 #define key_input PIND.7
 #define key_state_0 0
 #define key_state_1 1
 #define key_state_2 2
 
 unsigned char read_key(void)
 {
 static unsigned char key_state=0;
 unsigned char key_press,key_return=0;
 key_press=key_input;
 switch(key_state)
 {
 case key_state_0:
 if(!key_press) key_state=key_state_1;
 break;
 case key_state_1:
 if(!key_press)
 {
 key_return=1;
 key_state=key_state_2;
 }
 else
 key_state=key_state_0;
 break;
 case key_state_2:
 if (key_press) key_state=key_state_0;
 break;
 }
 return key_return;
 }
 因为抖动的时间为10到20ms所以是这个函数每10ms执行一次即可。
 PIND.7那行表示按键的输入口为PD7
 |