我正在使用AVR Studio5使用atmel atmega328p对arduino uno rev3进行编程。现在,我正在尝试在1秒内连续闪烁。 代码是:
PORTD = 0b10001010;
TCNT1H = 0xBB;
TCNT1L = 0xBB;
TCCR1A = 0;
TCCR1B = 5; // prescaler is 1024
while((TIFR1 & (1<<TOV1)) == 0)
{
temp = TCNT1H;
while ((TCNT1H - temp) >= 11);
PORTD ^= 1<<7; // blinking as expected
}
TIFR1 = 1<<TOV1;
TCCR1A = 0;
TCCR1B = 0;
上面的代码显示我使用持续1秒的timer1,其中我试图为每个0.032768s的PORTD.7 LED闪烁。 但是,现在问题是定时器工作延迟1秒,但LED保持照明不闪烁。请帮忙 。 (P.S电路工作正常)
补充: 如果我使用以下代码,它会显示LED闪烁。
for ( a = 0;a<2;a++)
{
PORTD = 0b00001010;
TCNT1H = 0xEE;
TCNT1L = 0xEE;
TCCR1A = 0;
TCCR1B = 5; // prescaler is 1024
while((TIFR1 & (1<<TOV1)) == 0);
TIFR1 = 1<<TOV1;
TCCR1A = 0;
TCCR1B = 0;
PORTD = 0b10001010;
TCNT1H = 0xEE;
TCNT1L = 0xEE;
TCCR1A = 0;
TCCR1B = 5; // prescaler is 1024
while((TIFR1 & (1<<TOV1)) == 0);
TIFR1 = 1<<TOV1;
TCCR1A = 0;
TCCR1B = 0;
}
但是,为了简单起见,我更喜欢使用最顶级的方法。
答案 0 :(得分:2)
while ((TCNT1H - temp) >= 10)
{
PORTD ^= 1<<7; // blinking as expected
}
你眨眼太快,太快了,实际上你看到的是一个发光度只有一半的LED。您需要在PORTD ^= 1<<7
的两次调用之间添加一些延迟。
答案 1 :(得分:0)
这是应该用中断完成的。
void TMR_init(void)
{
DDRD|=_BV(PD7); //bit 7 of port D to output
TCNT1=0; //reset the timer counter
OCR1AL=0xC6; //depends on your osc. This values are for 12MHz
OCR1AH=0x2D; //with 12 000 000Hz / 1024 it takes 11718 ticks for 1 sec->0x2D C6
TIMSK1|=_BV(OCIE1A); //enable interrupt on output compare A (when timer value == value in the OCR1AL/H-registers)
TCCR1A=0; //normal operation
TCCR1B=_BV(CS12) | _BV(CS10); //prescaler 1024 and starts the timer
sei(); //enable interrupts
}
//isr
SIGNAL(TIMER1_COMPA_vect)
{
PORTD^=_BV(PD7); //toggle
}
此代码应该可以使用,但未经测试。不要忘记包含avr / interrupt.h。由于编译器的版本差异,某些宏可能会有所不同。