Прерывание переполнения Timer0 не работает
Я пытаюсь использовать Timer0 Arduino Leonardo (ATmega32u) для запуска прерывания через равные промежутки времени, используя простой avr-gcc (не библиотеку arduino). Пытаюсь для проверки помигать встроенным светодиодом, но он не загорается.
Если я помещаю PINC=0x80;
в основную функцию, светодиод загорается, но не в том случае, если я делаю это из прерывания.
Что я делаю не так?
EDIT: светодиод загорается при TCCR0B = (1 << CS00);
, (без прескалера) или TCCR0B = (1 << CS01) (предделитель /8), но не с
TCCR0B = (1 << CS00) | (1 << CS02);
(предделитель /1024, то, что я хочу). При частоте процессора 16 МГц результирующая частота должна быть больше 15 кГц, поэтому я должен увидеть это сразу.
Вот мой код:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
ISR(TIMER0_OVF_vect)
{
PINC = 0x80;
}
int main()
{
DDRC = 0b10000000;
//Запуск таймера 0 при 15625 Гц
TCCR0A = 0;
TCCR0B = (0b101 << CS00);
TIMSK0 = (1 << TOIE0);
sei();
while(true); // Избегайте возврата из main
}
@Simon Tagne, 👍0
Обсуждение1 ответ
Я нашел ответ здесь: https://www.avrfreaks.net/ форум/atmega32u4-arduino-leonardo-strange-timer-behavior
Похоже, что соединение USB генерирует прерывания с более высоким приоритетом. Я до сих пор не знаю, почему прерывания работают на более высокой частоте.
Решения включают питание платы от зарядного устройства USB или другого источника питания, а не через USB компьютера, или добавление следующего кода перед разрешением прерывания:
// Очистить флаги прерывания usb
USBINT = 0;
UDINT = 0;
for (uint8_t i = 0; i < 6; i++)
{ // Для каждой конечной точки USB
UENUM = i; // выбираем _i-ю конечную точку
UEINTX = UEIENX = 0; // Очистить флаги прерывания для этой конечной точки
}
Спасибо тем, кто мне помог!
Я думаю, что обработчик прерывания отсутствует при выходе из загрузчика, поэтому avr-gcc по умолчанию сбрасывает плату, что может привести к более высокой частоте включения светодиода , в то время как при более низкой частоте плата сбрасывается до первого прерывания., @Simon Tagne
- Прерывания TIMER1 CTC не работают с avr-gcc
- Входной Режим захвата PPM сигнала
- Захват ввода с включенным спящим режимом на плате ATM32u4 работает только при каждом втором чтении в спящем режиме.
- Где в даташите предупреждение о ненадежности чтения PINxn?
- Проблема с таймером 0
- Использование millis() и micros() внутри процедуры прерывания
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Использование TIMER0_COMPB_vect
какое исследование вы провели?, @jsotola
@jsotola Я прочитал соответствующие главы таблицы данных процессора и некоторое время гуглил, но нашел только несвязанные проблемы (например, использование режима CTC или возврат из основного)., @Simon Tagne
я невнимательно прочитал....удалив мои комментарии....можете удалить свои, @jsotola
тогда вы должны предположить, что ISR никогда не вызывается.....может это поможет......http://www.instructables.com/id/Arduino-Timer-Interrupts/, @jsotola
Примечание:
0b101 << CS00
выглядит как плохой код. Лично; Я бы использовал(1 << CS00) | (1 << CS02)
, @Gerben