Страница 1 из 1
Проблема с таймером 2 на AtMega16
Добавлено: Чт апр 02, 2009 09:56:53
cvid
Вот пишу простенький код для atmega16
Код: Выделить всё
#include<avr>
#include<util>
#include<avr>
unsigned char flag=0;
//==============timer===================//
SIGNAL(TIMER2_COMP_vect)
{
flag = 1;
}
void init_Timer()
{
OCR2 = 200;
TCCR2 = (1 << WGM21) | (1 << CS22);
TIMSK = (1 << 7);
}
//===================//
int main(void)
{
DDRD = 0xFF;
init_Timer();
while(flag!=1){}
while(1)
{
PORTD = 0xFF;
_delay_ms(20);
PORTD = 0x00;
}
return 0;
}
Проверяю AvrStudio - все нормально, прерывание есть, флаг становится 1, но прога не выходит из бесконечного цикла
В чем же дело?
Добавлено: Чт апр 02, 2009 10:29:21
BerZerK-ku
Не установлен глобальный бит разрешения прерываний.
Re: Проблема с таймером 2 на AtMega16
Добавлено: Чт апр 02, 2009 11:31:39
ikarab
cvid писал(а):все нормально, прерывание есть, флаг становится 1, но прога не выходит из бесконечного цикла
Установка флага означает наличие события вызывающего прерывание, но не само прерывание - прерывание это переход программы по адресу соответствующего прерывания.
Если интересно - почитайте
"Прерывания в AVR"
cvid писал(а): SIGNAL(TIMER2_COMP_vect)
Там же посмотрите что в WinAVR обновился формат описания обработчиков прерываний:
Прерывание в компиляторе WinAVR
#include <avr>
ISR(прерывание_vect)
{
код выполняемый при возникновении
разрешенного локально и глобально прерывания
}
слово "прерывание" нужно заменить на название прерывания из ДатаШита либо из заголовочного файла *.h для вашего МК AVR.
============
Если вы хотель только отдельные биты установить, то вот так не верно - вы еще и нули пишите :
TCCR2 = (1 << WGM21) | (1 << CS22);
TIMSK = (1 << 7);
верно так:
TCCR2 |= (1 << WGM21) | (1 << CS22);
TIMSK |= (1 << 7);
Добавлено: Чт апр 02, 2009 13:29:56
Александр777
Попробуй вместо
unsigned char flag=0; написать
int flag=0;,
возможно несоответствие типов.
Не установлен глобальный бит разрешения прерываний.
Проверяю AvrStudio - все нормально, прерывание есть, флаг становится 1
Действительно непонятно как оно работаетнормально, если нет команды sei().
Добавлено: Чт апр 02, 2009 18:42:07
ARV
уж сколько раз твердили миру... а воз и ныне там...
все переменные, которые изменяются в обработчиках прерываний и затем используются в прочих функциях должны быть объявлены volatile
Добавлено: Чт апр 02, 2009 19:28:07
cvid
Спасибо всем, разобрался. sei() был, просто код скопировал не полностью

А вот volatile - действительно моя ошибка, чё-то совсем запамятовал, спс ARV.