AVR单片机I/O口、定时器和按键编程总结
扫描二维码
随时随地手机看文章
首先,用到了定时器2的溢出中断,用于控制灯的闪烁。在这部分程序的设计中,遇到的困难是当灯一旦闪烁起来,就无法控制其它的内容了。后来明白是由于中断服务程序太长,没等执行完计数器就计满了,然后就一直的在执行闪烁程序,导致无法在执行其它命令。最开始在每次延迟函数之后令计数器置零,可是还是没有起到太大效果,因为最长的延迟函数为2s,时间太长,最后经考虑,在进入中断服务程序的时候,屏蔽定时器2溢出中断,在离开之前再使能,然后再令计数器置零,结果实现了所要的结果。
第二个问题就是关于按键。要求相应的I/O口即能做输出,又能做输入,能够用按键控制。似乎很简单的一个程序,可是第一次做也遇到不少问题。当按下相应的按键,就给data赋一个值,去实现不同的功能,最初发现不行,由于是按键程序循环执行,因此data数据不变时会一直执行,因此在程序的开头先有一条语句data= =0xff,如果!0xff就执行语句否则不执行。还有就是关于按键的稳定性问题,由于单片机速度比较快,即使你轻轻的按了一下,也可能已经执行了很多次相应的程序,而且按得太快会有毛刺,有不稳定现象。解决该问题借助了别人的一些帮助,自己从中确实学到了东西。采用了一条while((PINA&(1<<0))==0);语句,当按键不送开始程序一直在这里循环。
还有就是针对AVR单片机的特点,在每一个函数或子函数中,必须把定义变量放在最前面,否则将会不识别。而且,即使在
void Key_Handle2(void)
{ unsigned char i;
unsigned char temp7;
temp7=data;
i=PORTA;
DDRA=0xe0;
data=0xff;
这样的函数中,有时把temp7=data;i=PORTA;DDRA=0xe0;安排的先后顺调一下就可能不能出现正确的结果,本人目前也没有搞懂,但是有时就在一个问题上连续几天都解决不了,就突然换换顺序,马上成功,所以建议在自己感觉一切正确却又不能出正确结果时不妨试一试调换一下这些赋值的次序,也许就有新的发现。
第四,在写max7219的数码管驱动程序时,由于是用普通的I/O口做驱动,而且该口其它管脚还有其它用途,这也使得在最初写完程序时不能得到正确结果。把相应的程序发上来,有需要的就参考,绝对原创,不用担心其它问题。
void show(unsigned char addr,unsigned char content)
{ unsigned char i,j,t;
t=PORTA&0x
PORTA&=~(1<<6);
PORTA&=~(1<<5);
for(i=8;i>0;i--)
{ PORTA&=~(1<<7);
PORTA=(((addr&0x80)>>2)|t);
addr=addr<<1;
delay1();
PORTA|=(1<<7);
delay();
PORTA&=~(1<<5);
}
for(j=8;j>0;j--)
{ PORTA&=~(1<<7);
PORTA=(((content&0x80)>>2)|t);
content=content<<1;
delay1();
PORTA|=(1<<7);
delay();
PORTA&=~(1<<5);
}
PORTA|=(1<<6);
}