|
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "led.h"
uint c_tmp=0;
uchar dis_buf[]={0,0,0,0,0,0},pos=0;
ISR(TIMER0_COMP_vect)//2.5ms
{
PORTC=0xff;
PORTA=led[dis_buf[pos]];
PORTC=~(1<<pos);//以上三句点亮一位数码管
if(++pos==2)//总共两个数码管
pos=0;
if(++c_tmp==200)//200*2.5ms=500ms,延时一次
{
c_tmp=0;
_delay_ms(5);//延时5ms
}
}
int main()
{
uchar tmp;
DDRA=0xff;
PORTA=0xff;
DDRC=0xff;
PORTC=0xff;
//CTC模式,定时2.5ms
TCCR0=0x0c;
OCR0=108;
TIMSK=0x02;
TCNT0=0;
sei();
while(1);
return 0;
}
症状:两位数码管(本来是6位的,为了测试改成2位的),每500ms闪烁一下,闪烁不是一闪一闪的,是稍微抖一下,不太明显。
数码管2.5ms扫描一位,问题出在:
if(++c_tmp==200)//200*2.5ms=500ms,延时一次
{
c_tmp=0;
_delay_ms(5);//延时5ms
}
500ms到,会延时5ms,可5ms也够短了吧?一位2.5ms,延时5ms,再次点亮当前数码管也就2.5+5ms=7.5ms,怎么会闪?我试了下,6位数码管,小于4ms点亮一位就不会闪,那就是重新点亮一位的最大时间为4*(6-1)=20ms。不加那段语句,没问题。定时为2.5ms时,延时超过3ms就会闪,当定时为1.25ms时,延时超过2ms就闪了。照理说,把时间缩短了,应该不会闪啊,很费解。。
本来是个18B20测温的程序,51做的,发现问题后,查了很久,没有结果,后来想到AVR上试下,结果还是一样。_delay_ms(5)实际是读温度时间,为了测试改成延时。那个500ms是温度转换时间,500ms转换一次。时间到后,读温度,完了之后,重启18B20准备下一次转换,500ms再到,继续读温度、重启。
刚在一个QQ群里问了下,上来就被一个人鄙视了下,“数码管问题也要问?”,老师不要笑话,希望能帮我看下,多谢! |
|