单片机新手,入门前的感悟第十篇。
终于看完中断了,理论知识还是比较好掌握的,感觉就是四个寄存器的设定。课本这章主要介绍了外部中断,先看这个用按键控制的一位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 |