#c
#c
Вопрос:
Я столкнулся с проблемой при использовании ATmega32U4, когда я успешно могу использовать переполнения таймера 1, но когда я пытаюсь перепрофилировать код для таймера 3, он не работает.
Следующий код включает и выключает светодиод (на выводе b7) при переполнении таймера 1 (16 бит). Это работает.
#include <avr/io.h>
#include <avr/interrupt.h>
int main (void) {
DDRB |= (1<<7);; //PortB Output
PORTB = 0x00; //PortB All LEDs off
TCCR1B |= (1<<CS10) | (1<<CS12); //Set Prescaler to 1024
TIMSK1 |= (1<<TOIE1); //Enable Timer Overflowinterrupt
sei(); //Enable Interrupts
while(1);
return 0;
}
ISR(TIMER1_OVF_vect)
{
PORTB ^= (1<<7); //toggle LED
}
Следующий код предназначен для выполнения той же функциональности с использованием таймера 3, но не работает.
#include <avr/io.h>
#include <avr/interrupt.h>
int main (void) {
DDRB |= (1<<7);; //PortB Output
PORTB = 0x00;
TCCR3B |= (1<<CS30) | (1<<CS32); //Set prescaler to 1024
TIMSK3 |= (1<<TOIE3); //Enable Timer Overflowinterrupt
sei(); //Enable Interrupts
while(1);
return 0;
}
ISR(TIMER3_OVF_vect)
{
PORTB ^= (1<<7);
}
Этот последний блок кода использовался для проверки того, что значение счетчика таймера 3 увеличивалось (без задействованных прерываний), что так и есть. (В этом тесте я использую другой светодиод)
#include <avr/io.h>
int main()
{
// Prescaler of 1024
TCCR3B |= (1<<CS32)|(1<<CS30);
// Initialize Counter
TCNT3 = 0;
// Initialize LED
DDRE |= (1 << 6); // LED0
// Infinite Loop
while (1)
{
// Flash every 0.016 secs
// COUNTER = 0.016 / (PRE SCALER / CPU FREQ)
// 250
if( TCNT3 >= 250 )
{
// Toggle LED
PORTE ^= (1 << 6); // If output use PORT, If input use PIN
TCNT3 = 0;
}
}
return 0;
}
Исходя из этого, я предполагаю, что я делаю что-то неправильно при вызове прерывания, я просто не уверен, что
Комментарии:
1. Вы используете LilyPad, Flora или Leonardo?
Ответ №1:
Я не уверен, используете ли вы LilyPad или Leonardo.
Из приведенного выше кода я предполагаю, что это LilyPad. Измените значение TCR3B на 256 и посмотрите, исправит ли это проблему для вас.
TCCR3B = 0x0C; // prescaler = 256
Комментарии:
1. На самом деле я вообще не использую продукт arduino, это пользовательский микроконтроллер. Я реализовал ваше предложение, однако это не решило мою проблему. Индикатор по-прежнему не горит. В третьем фрагменте кода, который я опубликовал, я фактически использую таймер 3 с предварительной шкалой, установленной на 1024, и считываю значение счетчика TCNT3 (которое работает как ожидалось и увеличивается). Так что я не уверен, что это проблема.