Я пытаюсь проверить частоту Timer3 с помощью счетчика. Значение счетчика, объявленное как volatile, увеличивается в ISR, и каждую секунду сумма отображается в основном цикле, а значение сбрасывается в ноль.
Таймер был настроен правильно. (Если я выберу таймер 3 Гц, я вижу мигание светодиода)
Проблема
Счетчик не увеличивается. Вот вывод:
Setup Completed
tick: 1
tick: 0
tick: 0
tick: 0
КОД
volatile int cont = 0;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
// Initialize Timer
cli(); // disable global interrupts
TCCR3A = 0; // set entire TCCR3A register to 0
TCCR3B = 0; // same for TCCR3B
// set compare match register to desired timer count: 800 Hz
OCR3B = 20; // 800Hz 5; // 3 Hz
// turn on CTC mode:
TCCR3B |= (1 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR3B |= (1 << CS30) | (1 << CS32);
// enable timer compare interrupt:
TIMSK3 |= (1 << OCIE3B);
// enable global interrupts:
sei();
Serial.println("Setup completed");
}
void loop()
{
if (millis() % 1000 == 0)
{
Serial.print(" tick: ");
Serial.println(cont);
cont = 0;
}
}
ISR(TIMER3_COMPB_vect)
{
//digitalWrite(13, digitalRead(13) ^ 1);
cont++;
}
РЕДАКТИРОВАТЬ Этот таймер используется для считывания значения журнала из акселерометра и сохранения его в массиве с плавающей точкой. Но на данный момент я застрял в этой проблеме обновления.
РЕШЕНИЕ 1 Благодаря Гербену
volatile int cont = 0;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
// Initialize Timer
cli(); // disable global interrupts
TCCR3A = 0; // set entire TCCR3A register to 0
TCCR3B = 0; // same for TCCR3B
// set compare match register to desired timer count: 800 Hz
OCR3A = 20; // 20; //800Hz 5; // 3 Hz
// turn on CTC mode:
TCCR3B |= (1 << WGM32);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR3B |= (1 << CS30) | (1 << CS32);
// enable timer compare interrupt:
TIMSK3 |= (1 << OCIE3B);
// enable global interrupts:
sei();
Serial.println("Setup completed");
}
void loop()
{
delay(1000);
Serial.println(cont);
cont = 0;
}
ISR(TIMER3_COMPB_vect)
{
cont++;
}
РЕШЕНИЕ 2 Благодаря BrettM
volatile int cont = 0;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
// Initialize Timer
cli(); // disable global interrupts
TCCR3A = 0; // set entire TCCR3A register to 0
TCCR3B = 0; // same for TCCR3B
// set compare match register to desired timer count: 800 Hz
OCR3B = 20; //800Hz 5; // 3 Hz
// turn on CTC mode:
//TCCR3B |= (1 << WGM32);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR3B |= (1 << CS30) | (1 << CS32);
// enable timer compare interrupt:
TIMSK3 |= (1 << OCIE3B);
// enable global interrupts:
sei();
Serial.println("Setup completed");
}
void loop()
{
Serial.println(cont);
cont = 0;
delay(1000);
}
ISR(TIMER3_COMPB_vect)
{
TCNT3 = 0;
cont++;
}
digitalWrite
линию, вы увидите, что светодиод мигает примерно раз в секунду (каждые 0,66 с)?digitalWrite
и установлюOCR3B = 5;
светодиод мигает примерно на этой частоте.cont = 0;
внутри цикла? Что происходит потом?Ответы:
В режиме CTC вершина есть
OCR3A
, нетOCR3B
!После этого
TIMSK3 |= (1 << OCIE3B);
также следует заменить наTIMSK3 |= (1 << OCIE3A);
, иISR(TIMER3_COMPB_vect)
вISR(TIMER3_COMPA_vect)
Для 3 Гц
OCR3A
должно быть 5208, а не 20.Технически
TCCR3B |= (1 << WGM12);
должно бытьTCCR3B |= (1 << WGM32);
источник
TIMSK3 |= (1 << OCIE3B);
. Спасибо Гербен! Пожалуйста, измените свой ответ, и я приму его в качестве решения.ISR(TIMER3_COMPB_vect)
должно бытьISR(TIMER3_COMPA_vect)
. Если ISR не определен, AVR будет сброшен сам, как вы испытывали. Рад, что ты получил это работает.Похоже, мой ответ на этот вопрос ранее был неполным, спасибо, что указали, что режим CTC работает только с OCR3A Gerben. Я прошу прощения за то, что не протестировал ответ, прежде чем опубликовать его
Учитывая информацию только в этом вопросе, ответ Гербена полон, но поскольку ваш другой вопрос подразумевает, что вы не можете использовать OCR3A из-за библиотеки сервоприводов, я добавлю немного. (Я также отредактировал этот ответ)
Вы можете эмулировать поведение режима CTC, установив TCNT3 на 0 в своей подпрограмме прерывания. Не забудьте удалить строку, которая включает режим CTC в вашем коде.
Я проверил ваш код с этим ISR:
и эта конфигурация таймера записывается
Это может быть немного менее точно на высоких частотах, чем CTC, я не уверен, но на 3 Гц он работал отлично. Обратите внимание, что 5208 было правильным значением OCR, а не 20 (опять же, благодаря Гербену).
источник
TCNT3=0;
в ISR () и удалил//TCCR3B |= (1 << WGM32);
в setup (), как вы сказали. Я также пыталсяcont=0;
println(cont); delay(1000);
. Также вы все еще включаете биты с cli (), TCCR3A и т. Д. Правильно?