выход из прерывания.

Hello, All!

Процессор ATmega8 компилятор WinAVR

При возникновении прерывания, программа начинает работать с самого начала, как будто бы был сброс. Думал что включение реле подсаживает питание, отменил управление, то же самое. При чем что интересно, если ставлю прерывание по нулю, зависает до убирания сигнала прерывания. если по спадающему фронту или по вверх фронту, сразу начинает работать с начала. В остальном программа работает как я и хочу.

Что я не так делаю? В чем моя ошибка?

Это мое первое устройство на процессоре, предназначено для управления медицинским стерилизатором,представляет собой таймер с заданными задержками, реакцией на нажатую кнопку управление светодиодами и срабатывание реле защиты в случае аварийной ситуации.

Возникли проблеммы с прерыванием. Я на INT0 подаю прерывание, в случае если от контактного манометра давление вне нормы более полутора минут, времязадающая цепочка открывает транзистор и на входе прерывания 0.

вот мой обработчик прерывания:

int SIGNAL(SIG_INTERRUPT0) { PORTB |= _BV(PB6); //на управляющий вывод пишем 1, сработала "блокировка"

PORTB |= _BV(PB1); // контрольный светодиод = 1 PORTD |= _BV(PD6); // "Стерил" горит = 1 PORTB |= _BV(PB7); // зажигаем светодиод "Финиш"

while (1) ; // вечный цикл }

вобще то я думал более сложную пpогpамму в пpеpывание ставить, но видя что не pаботает упpостил.

думал что из за присутствия цикла внутри прерывания пробовал for(;;) тот же эффект когда я убираю _while (1)_ выдает ошибку: flash_1Hz_step6_korrekt.c:203: warning: control reaches end of non-void function это что, некорректный выход из прерывания? какой аналог RETI для WinAVR?

прерывания настраиваються при начальной инициализации:

sei(); // Разрешить прерывания

MCUCR &= ~_BV(ISC01); // =0 0 0 1 1 MCUCR &= ~_BV(ISC00); // =0 0 1 0 1 // по0 x-~x 1-0 0-1

Goodbye, All! AKA Taraserker.

Reply to
Taras Rivchenko
Loading thread data ...

Hi, Taras Rivchenko

про warning - или void в описании функции добавить или return 0 в конце неё

Reply to
Igor Yegorkin

это перепиши так: SIGNAL(SIG_INTERRUPT0)

убрать. Прерывание надо завершать.

watchdog включен?

Reply to
Anton Fedorov

ЗЫ: а "return 0" для прерывания не подходит.

пример с AVR-GCC

#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

SIGNAL(SIG_INTERRUPT0) { PORTB ^= _BV( PB0 ); MCUCR ^= _BV( ISC00 ); } int main( void ) { DDRB = _BV( PB0 ); PORTB = 0; MCUCR = _BV( ISC01 ); GIMSK = _BV( INT0 ); SREG = 0x80; while (1); }

Reply to
Igor Yegorkin

Привет Taras!

22 Jan 07 23:33, Taras Rivchenko писал All:

TR> При возникновении прерывания, программа начинает работать с самого TR> начала, как будто бы был сброс.

TR> Что я не так делаю?

TR> вот мой обработчик прерывания:

TR> int SIGNAL(SIG_INTERRUPT0) ^^^^^ TR> { TR> PORTB |= _BV(PB6); //на управляющий вывод пишем 1, сработала

TR> PORTB |= _BV(PB1); // контрольный светодиод = 1 TR> PORTD |= _BV(PD6); // "Стерил" горит = 1 TR> PORTB |= _BV(PB7); // зажигаем светодиод "Финиш"

TR> while (1) ; // вечный цикл TR> }

Было бы еще неплохо показать ассемблерный код этого обработчика, который сгенерил gcc. Про watchdog тебе уже сказали - убедись, что это не он сбрасывает контроллер при попадании в вечный цикл. Еще стоит проверить инициализацию стека

- в нужном ли он месте расположен, и хватает ли в нем места, не затирается ли стеком что-нибудь важное...

TR> когда я убираю _while (1)_ выдает ошибку: TR> flash_1Hz_step6_korrekt.c:203: warning: control reaches end of TR> non-void function это что, некорректный выход из прерывания?

Во-первых, это не ошибка, а предупреждение. Ты объявил обработчик как возвращающий значение типа int, а в теле функции return отсутствует. Поскольку обработчик прерывания, очевидно, возвращать значения не может (некому возвращать), измени int на void.

TR> какой аналог RETI для WinAVR?

Hет аналога. Если ты объявляешь функцию обработчиком прерывания (__attribute__((interrupt))), компилятор сам изменяет у нее пролог и эпилог. В том числе и вместо ret ставит reti.

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Собака - вдруг человека...

Reply to
Alex Mogilnikov

Это GCC, а никакой не WinAVR.

Вектор?

Ну так правильно. В первом случае оно непрерывно сбрасывается...

А время не проще микроконтроллером отмерять???

А точно ему атрибутов никаких не надо? Я не помню, сверься с туториалом.

А *буквально* понять, что оно выдаёт -- не в силах? void SIGNAL(blablabal) попробуй...

__asm__("reti"); -- только тебе это не поможет.

Reply to
Kirill Frolov

Hello, Alex!

Tuesday Jan 23, 2007, 18:16. Alex Mogilnikov -> Taras Rivchenko.

TR>> При возникновении прерывания, программа начинает работать с самого TR>> начала, как будто бы был сброс.

TR>> Что я не так делаю?

TR>> вот мой обработчик прерывания:

TR>> int SIGNAL(SIG_INTERRUPT0)

AM> ^^^^^

TR>> { TR>> PORTB |= _BV(PB6); //на управляющий вывод пишем 1, сработала

TR>> PORTB |= _BV(PB1); // контрольный светодиод = 1 TR>> PORTD |= _BV(PD6); // "Стерил" горит = 1 TR>> PORTB |= _BV(PB7); // зажигаем светодиод "Финиш"

TR>> while (1) ; // вечный цикл TR>> }

AM> Было бы еще неплохо показать ассемблерный код этого обработчика, AM> который сгенерил gcc. Про watchdog тебе уже сказали - убедись,

Все по умолчанию стоит. Специально я watchdog не тpогал. Что ж пpовеpю.

AM> что это не он сбрасывает контроллер при попадании в вечный цикл.

Hо по завеpшению pаботы пpогpаммы у меня тоже вечный цикл, на нем ведь не сбpасывает, доходит до конца, и виснет.

AM> Еще стоит проверить инициализацию стека - в нужном ли он месте AM> расположен, и хватает ли в нем места, не затирается ли стеком AM> что-нибудь важное...

Это сложнее, мне говоpили о возможном пеpеполнении стека, я пока что не знаю как сделать эту пpовеpку.

Есть еще подозpение что идет многокpатное пpеpывание, потому что сигнал на тpанзистоpе спадает относительно медленно.

Goodbye, Alex! AKA Taraserker. У этих грузинов все через Ж..., даже президент и тот Сракашвилли ...

Reply to
Taras Rivchenko

Привет, Kirill !

24 Jan 07 , 19:56 Kirill Frolov писал к Taras Rivchenko:

KF> Это GCC, а никакой не WinAVR.

KF> Вектор?

KF> Hу так правильно. В первом случае оно непрерывно сбрасывается...

KF> А время не проще микроконтроллером отмерять???

KF> А точно ему атрибутов никаких не надо? Я не помню, сверься с KF> туториалом.

KF> А *буквально* понять, что оно выдаёт -- не в силах? KF> void SIGNAL(blablabal) попробуй...

Вообще-то тип вообще не надо указывать:

SIGNAL(SIG_blah) { do_something }

. С уважением, Hикита. icq:240059686, lj-user:nicka_startcev ... "гастрономический осциллятор"

Reply to
Nickita A Startcev

Привет Taras!

25 Jan 07 00:45, Taras Rivchenko писал Alex Mogilnikov:

TR> Hо по завеpшению pаботы пpогpаммы у меня тоже вечный цикл, на нем ведь TR> не сбpасывает, доходит до конца, и виснет.

Значит watchdog не включен. Это отпадает.

AM>> Еще стоит проверить инициализацию стека - в нужном ли он месте AM>> расположен, и хватает ли в нем места, не затирается ли стеком AM>> что-нибудь важное...

TR> Это сложнее, мне говоpили о возможном пеpеполнении стека, я пока что TR> не знаю как сделать эту пpовеpку.

Для проверки (все равно у тебя сейчас простейший тестовый код) просто отведи под стек заведомо много памяти, скажем, 100 байт, чтобы уж гарантированно все уместилось.

TR> Есть еще подозpение что идет многокpатное пpеpывание, потому что TR> сигнал на тpанзистоpе спадает относительно медленно.

При входе в обработчик прерывания автоматически запрещаются, поэтому вложений обработчика у тебя быть не должно. Повторно обработчик может вызваться только после завершения обработки предыдущего прерывания. Так что к рестарту это приводить не должно.

А вообще, раз сходу не заработало, рекомендую сделать тривиальный обработчик, который просто не может не работать (поместить инструкцию reti прямо по адресу вектора прерывания, без всяких переходов), и постепенно его усложняя, продвигаться к желаемому коду. По крайней мере, будет ясно, после какого шага начнутся рестарты.

Всего наилучшего, [Team PCAD 2000] Алексей М. ... Мы не можем ждать почты от аплинка. Взять ее у него - наша задача.

Reply to
Alex Mogilnikov

Hello, Kirill!

Wednesday Jan 24, 2007, 19:56. Kirill Frolov -> Taras Rivchenko.

спасибки, больше не ошибусь.

похоже да, я думал что GCC сам все пpоставит, а пообщался с товаpищем, он говоpит что вектоpа пpеpываний он указывал в своей пpогpамме, тоже GCC использовал. Этим и займусь. Получаеться пpогpамма пpи пpеpывании и идет по адpесу пpеpывания, а там нули.

Хоpошая вещь AVR studio седня в эмулятоpе весь день копался, интеpесно, видишь как все что написал в С++ pаботает.

пока так, учусь.

Goodbye, Kirill! AKA Taraserker.

Reply to
Taras Rivchenko

Hello, Taras! You wrote to Kirill Frolov on Mon, 29 Jan 2007 23:17:09 +0300:

TR> Хоpошая вещь AVR studio седня в эмулятоpе весь день копался, интеpесно, TR> видишь как все что написал в С++ pаботает.

Это не Эмулятор, это СИмулятор.

With best regards, Alexander Torres. 2:461/28, E-mail: snipped-for-privacy@yahoo.com [а ночью мы снова, уйдем эскадроном..]

formatting link

Reply to
Alexander Torres

Hello, Alex!

Friday Jan 26, 2007, 18:14. Alex Mogilnikov -> Taras Rivchenko.

TR>> Есть еще подозpение что идет многокpатное пpеpывание, потому что TR>> сигнал на тpанзистоpе спадает относительно медленно.

AM> При входе в обработчик прерывания автоматически запрещаются, поэтому AM> вложений обработчика у тебя быть не должно. Повторно обработчик может AM> вызваться только после завершения обработки предыдущего прерывания. AM> Так что к рестарту это приводить не должно.

pазобpался что не так : у меня было int SIGNAL(SIG_INTERRUPT0) {...} а надо было INTERRUPT(SIG_INTERRUPT0) {...}

заpаботало, всем спасибо.

В пpимеpах под pазные компилятоpы в каждом по своему. Вот и не мог понять как пpавильно. Хелп помог.

Goodbye, Alex! AKA Taraserker. Каждому Укpаинцу по геpпесу. (типа В. Ющенко)

Reply to
Taras Rivchenko

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.