Привет, хорошие люди переполнения стека. Моя проблема - это процедура обслуживания прерываний (ISR), которая, по-видимому, никогда не выполняется! Вот некоторые сведения о моей настройке: Я сверкаю avr attiny85. У меня есть голые кости проекта, созданного до сих пор с помощью простого main.c и двух модулей: timer и hardwareInit. В модуле таймера у меня есть функция timer0_init, которую я использую для настройки таймера0 для режима CTC для переполнения всего 1 мс. Вот функция:Прерывание переполнения таймера AVR не работает
void timer0_init(void)
{
cli();
TCCR0B |= 3; //clock select is divided by 64.
TCCR0A |= 2; //sets mode to CTC
OCR0A = 0x7C; //sets TOP to 124 so the timer will overflow every 1 ms.
TIMSK |= 2; //Enable overflow interrupt
sei(); //enable global interrupts
}
с таймером установленным, я добавил ISR для увеличения клещей каждый раз, когда счетчик переполнения, так что я могу отслеживать, сколько времени прошло, и т.д.
ISR(TIMER0_OVF_vect)
{
cli();
//ticks ++;
PORTB |= (1 << PORTB0);
sei();
}
Как вы можете видеть, я прокомментировал тики ++, потому что он не работал, и заменил его на PORTB |= (1 << PORTB0);
, который просто включает светодиод, поэтому, если прерывание выполняется, я узнаю, что светодиод включен.
К сожалению, я не могу заставить его включиться и не вижу, что мне не хватает. (чтобы доказать, что у I есть светодиод, установленный на правом штифте, и 2. я манипулирую правильным битом в правильном регистре, я поставил только это заявление PORTB |= (1 << PORTB0);
в моем бесконечном цикле и подтвердил, что загорелся светодиод)
Для дальнейшего объяснения, вот мой main.c:
/*================================= main.c =================================*/
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "timer.h"
#include "hardwareInit.h"
int main(){
//Initialize hardware HERE
DDRB |= (1 << PORTB0); //set this pin as an output for an LED
SetClockPrescale(1); //internal clock divided by 1 = 8 MHz, from hardwareInit
timer0_init(); //set up timer0 for 1 ms overflow
while(1)
{
/* if(getTicks() > 0)
{
PORTB |= (1 << PORTB0);
_delay_ms(1000);
PORTB &= ~(1 << PORTB0);
_delay_ms(1000);
} */
}
return 0;
}
Итак, что вы видите в бесконечном цикле, что я попробовал первый, но после этого не работал, я пытался что-то более простое, просто имеющий пустую петлю (прокомментировал предыдущий материал) и ожидал, что прерывание начнет срабатывать, и включит светодиод.
Любая помощь, которую вы могли бы дать, была бы действительно оценена. Я очень озадачен, почему это не работает.
Попробуйте изменить 'TIMSK | = 2,' в 'TIMSK | = (1 < <4); 'и' TIMER0_OVF_vect' - 'TIM0_COMPB_vect'. Однако никаких гарантий нет. – andars
Альтернативно, оставьте инициализацию таймера тем же и просто попробуйте изменить вектор на 'TIM0_OVF_vect' – andars