#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
}
Обновить
- используйте
volatile
модификатор доступа перед переменной count, чтобы сообщить компилятору, что вы измените ее из ISR, чтобы убедиться, чтоcount
переменная не будет удалена при оптимизации - когда вы устанавливаете
TCCR1B
, вы должны установить другие биты равными нулю, чтобы работать в обычном режиме - Пересчитайте значение
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 Я обновил ответ … скажите мне, если проблема все еще существует