Страница 1 из 1

Помогите разобраться с таймером 1 в меге32

Добавлено: Пн май 12, 2014 20:09:47
Василий_В2
Не могу понять в чем загвоздка, не срабатывает прерывание и все тут. Полазал по форуму похожего не нашел. Помогите пожалуйста!!
использую AVR Studio 5
контроллер АТМЕГА32

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

#include <avr/io.h>
#include <avr/interrupt.h>

unsigned short sec=0, flag=0, min=0;

// обработчик прерывания по переполнению
ICR(TIMER1_OVF_vect) { 
TCNT1H=0;
TCNT1L=0;
sec++;
flag=1;
}

void initTimer1(void)
{
cli();
TCCR1A=0; // выводы - нет,  шим -нет
TCNT1=0; // стартуем начиная с нуля
TCCR1B=2; // тактирование на 8
TIMSK|=_BV(TOIE1); // прерывание по переполнению ТС1
sei();
}

int main(void)
{
initTimer1();

while(1)  {
    if (flag==1){
		flag=0;
		if(sec>59) {
			sec=0;
			min++;
			if(min>59) min=0;
			}
		}
    }
}

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Пн май 12, 2014 20:49:08
ИС-пытатель
А с чего взяли, что не срабатывает? где проверяете? в железе или в эмуляторе?

Переменные sec и flag объявите volatile. И на ваши переменные вполне unsigned char хватит.

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Вт май 13, 2014 18:42:21
Василий_В2
Спасибо ИС-пытатель вроде разобрался )))
сделал некоторые изменения

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

...
int main(void)
{

//проверка на пробу правильно ли собрана цепь светодиода	
DDRD|=_BV(PIN_LED); // pin D6 - output LED
PORTD&=~_BV(PIN_LED);	// v 0 - светодиод горит
_delay_ms(500);
PORTD|=_BV(PIN_LED); // v 1 - светодиод не горит

initTimer1();
while(1)
    {
    if (flag==1){
		flag=0;
		PORTD&=~_BV(PIN_LED);	//  - светодиод горит (меняет 0->1, 1->0 )
		if(sec>59) {
                      ...
Проверяю в протеусе, поставил volatile, все равно переменная sec не увеличивается ! и переменная flag тоже не меняется видимо какая то трабла с выводом переменных в протеусе, потому что светодиод висящий на ноге мигает при эмуляции.
Буду проверять на железе

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Вт май 13, 2014 19:17:25
ИС-пытатель
Протеус частенько тупит с отображением значений переменных, хотя эмулирует в большинстве случаев более-менее правильно.

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Вт май 13, 2014 19:22:08
oldmaelstrom
чего-то я не заметил глобального разрешения прерываний :)

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Вт май 13, 2014 19:25:26
ИС-пытатель
В InitTimer1. Я тоже сначала подумал, что это к прерыванию относится.

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Вт май 13, 2014 19:40:34
oldmaelstrom
я конечно не профи, но мне думается что мало разрешить прерывания в initTimer1(), в главной функции их тоже надо разрешить

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Вт май 13, 2014 20:01:02
ИС-пытатель
Кстати! Тема! Если, не ошибаюсь, СИ сохраняет и восстанавливает флаги при вызове подпрограмм (хотя, может, только при вызове прерываний). Василий ,попробуйте SEI перенести в main.

Проверил. Флаги только при вызове прерываний сохраняются. При вызове подпрограмм они не трогаются. Но лучше все равно перенести.

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Вс май 18, 2014 22:32:26
Василий_В2
sei() перенес ничего не изменилось, но вот беда, не разобрался я еще с этим таймером - оказывается после срабатывания прерывания таймера программа начинает работать с самого начала т.е. с самой первой строчки функции main() - поэтому переменные и не плюсовались у меня. понял это когда эту строчку

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

 PORTD&=~_BV(PIN_LED);  
удалил из While(1), и при этом светодиод все равно продолжал мигать.
Беда какая-то что делать не знаю, подскажите плиз !!!!

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Вс май 18, 2014 22:39:40
ИС-пытатель
Василий_В2 писал(а): оказывается после срабатывания прерывания таймера программа начинает работать с самого начала т.е. с самой первой строчки функции main()
Такое бывает если разрешили какое-то прерывание, а обработчик для него написать забыли (или написали, но не для того). Но в Вашем коде вроде бы все норм. Василий, выложите весь код, пожалуйста.

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Вс май 18, 2014 22:58:34
Василий_В2
вот мой код

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Вс май 18, 2014 23:18:51
ИС-пытатель
Несущественно подправил. Так что должен делать Ваш код? Вы вначале зажигаете светодиоды, потом через полсекунды гасите, а потом, когда таймер срабатывает - снова зажигаете. И.. как бы все..

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Пн май 19, 2014 00:58:18
Василий_В2
Программа должна была при включении зажеч светодиод потом через пол секунды погасить и дальше ничего не делать со светодиодом (при том что закоментированы две строки в main()) и считать счетчики sec и min - по факту получается что она (при закоментированных строках) продолчает мигает светодиодами как ни в чем не бывало!

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Пн май 19, 2014 06:58:57
ИС-пытатель
Сторожевой таймер (watch dog) отключите.

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Вт июн 03, 2014 17:39:06
Василий_В2
Таймер не отключал, но вставлял в программу сбросы watch dog, также удлинял время срабатывания таймера1 до максимального (более чем срабатывает таймер watch dog) - все равно падает ровно на возникновении прерывания(наблюдал по регистрам в протеусе). Какая еще может быть причина?
ЗЫ: железка на которой все проверяется после протеуса такая http://microsin.net/programming/AVR/avr-usb-mega16.html (у меня вариант ATMEGA32) может быть это как-нибудь прояснит ситуацию.

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Вт июн 03, 2014 19:29:17
ARV
я вообще не понимаю, как ваш код скомпилировался без ошибок! макрос для прерываний в WinAVR называется ISR, а не ICR, как у вас.

Re: Помогите разобраться с таймером 1 в меге32

Добавлено: Ср июн 04, 2014 00:45:07
Василий_В2
Спасибо огромное ARV переправил название макроса и все зааработало, уж незнаю как это получалось скомпилировать, видимо такая AVR Studio которая такое пропускает х.з. )))