【发布时间】:2021-07-31 05:02:31
【问题描述】:
对于计时器,我想每隔一秒切换一次 LED。我正在使用 ATMega32,时钟频率为 1MHz。我可以使用 8 位计数器达到 0.1 秒,并且对于每 10 个定时器中断,我会闪烁 LED。
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
typedef unsigned char u8_t;
typedef unsigned short u16_t;
void func();
int main(void)
{
DDRC = 0x80;
TCCR0 |= (1 << WGM01); // CTC bit.
TCCR0 |= (1 << CS02) | (1 << CS00); // Prescalar = 1024.
OCR0 = 98; // 98 ticks correspond to roughly 0.1 second with 1024 prescaler
TIMSK |= (1 << OCIE0);
TCNT0 = 0;
sei();
while(1)
{
if (!(TIFR & (1 << OCF0))) {
func();
}
}
}
void func()
{
static u8_t extra_time = 0;
if (extra_time == 10)
{
extra_time = 0;
PORTC ^= 0x80;
}
else extra_time++;
TIFR |= (1 << OCF0);
}
在前面的代码中,我没有为TIMER0_COMP_vect 中断定义ISR。
来自数据表:
当 Timer/Counter0 和 OCR0 中的数据——输出比较寄存器 0。 OCF0 在执行时由硬件清零 相应的中断处理向量。 或者,OCF0 通过写入逻辑 1 来清除 旗帜。当 SREG 中的 I 位、OCIE0(Timer/Counter0 比较匹配中断使能)和 OCF0 置位(一),执行 Timer/Counter0 比较匹配中断。
强调我的。
因此,通过强调的句子,我可以检查 OCF0 位是否为零,如果是,我可以“处理”on-compare-match 事件。
但是,LED 闪烁的频率要高得多(每次闪烁之间甚至不到十分之一秒,但我当然无法测量)。
如果我只是在TIMER0_COMP_vect 上设置 ISR 并且什么都不检查,这工作正常,但我想知道为什么 OCF0 总是(?)逻辑 0,因此“开启”,即使我将它设置为高每个func() 电话。而且这种方法有什么问题。
【问题讨论】:
标签: c timer interrupt avr atmega32