【问题标题】:blinking a led using timer 1 overflow interrupt in atmega328p使用 atmega328p 中的定时器 1 溢出中断闪烁 LED
【发布时间】:2021-06-11 23:35:39
【问题描述】:

我正在尝试使用 ISR 使 LED 闪烁 3 秒,这里使用了 atmega328p。我正在尝试使用 TIMER1(16 BIT) 在 isr 中创建 1 秒延迟,然后将其循环 3 秒。 LED连接到PD7,我不知道为什么它不闪烁,谁能指出错误。我用的是simulIDE,这是电路,timer_circuit

#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#define SET_BIT(PORT,BIT) PORT |= (1<<BIT)
#define CLR_BIT(PORT,BIT) PORT &= ~(1<<BIT)
unsigned int count = 0;
void timer()
{
  TCCR1A = 0x00; // Normal mode of operation
  TCNT1 = 0xC2F8; // decimal value is 49912
  TCCR1B |= ((1 << CS10) | (1 << CS12));
  TCCR1B &= ~(1 << CS11); //1024 prescaler

  sei(); // Global interrupt
}

int main(void)
{
    SET_BIT(DDRD,PD7);
    timer();
    while(1)
    {
        TIMSK1 |= TOIE1;
        if(count>=3)
        {
            SET_BIT(PORTD,PD7);
            count=0;
        }
    }
    ;
    return 0;
}
ISR(TIMER1_OVF_vect)
{
  count++;
}

【问题讨论】:

  • 别忘了清除中断。这通常涉及写入控制寄存器,或者是读取/写入特定数据寄存器的副作用。

标签: c embedded avr atmega


【解决方案1】:

此代码永远不会关闭 LED ...一旦设置了该位,您的代码就永远不会清除它...尝试切换该位而不是设置它

#define toggle_BIT(PORT,BIT) PORT ^= (1<<BIT) //this will flip the bit
...
if(count>=3)
  {
     toggle_BIT(PORTD,PD7);
     count=0;
     TCNT1 = 0xC2F8; // reset counter
  }

更新

  1. 在 count 变量之前使用 volatile 访问修饰符告诉编译器您将从 ISR 更改它以确保 count 变量不会在优化中删除
  2. 当您设置 TCCR1B 时,您必须将其他位设置为零才能在正常模式下运行
  3. 8 MHz 重新计算值 TCNT1,这是内部默认频率

完整代码

#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#define toggle_BIT(PORT,BIT) PORT ^= (1<<BIT) //this will flip the bit
#define SET_BIT(PORT,BIT) PORT |= (1<<BIT)
#define CLR_BIT(PORT,BIT) PORT &= ~(1<<BIT)

volatile unsigned int count = 0;

void timer()
{
    TCCR1A = 0x00; // Normal mode of operation
    TCNT1 = 64754; // over flow after 1 sec calculated at 8 MHZ
    TCCR1B = ((1 << CS10) | (1 << CS12)); //1024 prescaler
    TIMSK1 |= 1<<TOIE1; // Enable timer1 overflow interrupt
    sei(); // Global interrupt
}

int main(void)
{
    SET_BIT(DDRD,PD7);
    timer();
    while(1)
    {
        
        if(count>=3)
        {
            toggle_BIT(PORTD,PD7);
            count=0;
        }
    }
    
    return 0;
}
ISR(TIMER1_OVF_vect)
{
    count++;
    TCNT1 = 64754; // reset to over flow after 1 sec calculated at 8 MHZ
}

【讨论】:

  • 错误是LED不亮,我在问题中添加了电路,你可以参考一下
  • @saravanan 我已经更新了答案...告诉我问题是否仍然存在
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多