blokowanie obsługi przycisku a funkcja while

Mar 22, 2016 4 Replies

W ramach tworzonego programu na AVR MEGA8 wymyśliłem sobie, by opóźnienie niezbędne przy wyłączaniu urządzenia przyciskiem (tak, by z powrotem się zaraz nie włączało) zrealizować poprzez funkcję while i Timer 1, którego przerwanie jest generowane co 1 sekundę.



Fragment kodu w funkcji obsługującej długie naciśnięcie przycisku, która ma wyłączać urządzenie, wygląda tak:



OLED_putString(" Power off! "); g_off_timer=5; while(g_off_timer>1);



i dalej zestaw funkcji powodujących wyłączenie zasilania (zdjęcie stanu wysokiego z odpowiednich pinów)



zmienna g_off_timer jest dekrementowana w ramach obsługi przerwania od Timera 1 w następujący sposób:



if (g_off_timer>0) { g_off_timer--; PORT(TESTOUT_PORT) ^= (1<<TESTOUT); }



i to wiem, że działa prawidłowo bo LED podłączony do wyjścia TESTOUT mruga z częstotliwością 0,5Hz.



Zakładam, że gdy program dojdzie do "while(g_off_timer>1)" to powinien w tym miejscu utknąć w pętli i czekać, aż z kolejnymi wygenerowanymi wywołaniami przerwania od Timera 1 wartość tej zmiennej dojdzie do 1, wówczas warunek w while będzie niespełniony i program poleci dalej. Program jednak utyka na dobre w tym miejscu, mimo iż zmienna g_off_timer osiąga wartość 0 - sprawdziłem to dodając prosty warunek w obsłudze przerwania od Timera 1:



if (g_off_timer==0) { PORT(TESTOUT_PORT) |= (1<<TESTOUT); }



Zgodnie z przewidywaniem, po kilku mrugnięciach LED zapalił się na stałe. Gdzie mam błąd?


Użytkownik "badworm" napisał w wiadomości grup dyskusyjnych:85o7yor6fejs$. snipped-for-privacy@badworm.pl...

A w deklaracji napisales volatile ? To napisz :)

Optymalizator piekna rzecz :-)

Nad jakims HALT mozna by jeszcze pomyslec - po co ma sie krecic w kolko bez potrzeby.

J.

On 2016-03-22 12:34, badworm wrote: [...]

  1. Obstawiam, że g_off_timer nie jest zadeklarowana jako „volatile”. A tego, jak jest zadeklarowana nie pokazałeś.
  2. To prawdopodobnie nie jest źródłem tego konkretnego problemu, ale jest źródłem potencjalnych problemów – miejsca „programu głównego” w których modyfikujesz g_off_timer musisz „owinąć” sekcją krytyczną (czyli w tym przypadku zapewne zwykłym wyłączeniem, a przy wyjściu z sekcji włączeniem przerwania od Timera 1) – chodzi o to, aby przerwanie timera nie weszło w trakcie modyfikacji g_off_timer w „programie głównym” i tym samym nie narobiło kaszanki.

Dnia Tue, 22 Mar 2016 13:11:23 +0100, J.F. napisał(a):

Pomogło, dzięki! :)

Wiedz jednak że to bardzio złym pomysł i uchodzi Ci to tylko na sucho bo jesteś na grupie elektronika :P

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required