Страница 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, но прога не выходит из бесконечного цикла

Код: Выделить всё

while(flag!=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.