мигание светодиода с использованием таймера 1 прерывание переполнения в atmega328p

#c #embedded #avr #atmega

Вопрос:

Я пытаюсь мигнуть светодиодом, используя ISR в течение 3 секунд, здесь используется atmega328p. Я пытаюсь создать задержку в isr на 1 секунду, используя TIMER1(16 БИТ), а затем зациклить ее на 3 секунды. Светодиод подключен к 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 amp;= ~(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 amp;= ~(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  ;
}
 

Комментарии:

1. Не забудьте очистить прерывание. Это обычно включает либо запись в управляющий регистр, либо является побочным эффектом чтения/записи определенного регистра данных.

Ответ №1:

Этот код никогда не выключает светодиод … как только бит установлен, ваш код никогда не очищает его … попробуйте переключить бит вместо того, чтобы устанавливать его

 #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. используйте volatile модификатор доступа перед переменной count, чтобы сообщить компилятору, что вы измените ее из ISR, чтобы убедиться, что count переменная не будет удалена при оптимизации
  2. когда вы устанавливаете TCCR1B , вы должны установить другие биты равными нулю, чтобы работать в обычном режиме
  3. Пересчитайте значение TCNT1 для 8 МГц, которое является внутренней частотой по умолчанию

полный код

 #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 amp;= ~(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
}
 

Комментарии:

1. Ошибка в том, что светодиод не включается сам по себе, я добавил схему в вопрос, можете ли вы сослаться на нее

2. @saravanan Я обновил ответ … скажите мне, если проблема все еще существует