Aktyw Forum
Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.
Sprawdź punkty Zarejestruj sięProblem z przerwaniami
Moderatorzy:Jacek Bogusz, robertw, k.pawliczak, Moderatorzy
Ponizej zamieszczony kod dziala prawidlowo, ale tylko wowczas, gdy w podprogramie "Int0_int" nie ma blokady przerwan i/lub skoku do innego podprogramu - dlaczego? W ukladzie sa tylko dwa przyciski i (wydaje mi sie), ze musze je zablokowac, abym mogl wykonywac nimi jakiekolwiek ustawienia, bo inaczej bedzie ciagle wywolywane przerwanie..
Prosze o pomoc w rozwiazaniu tego pojedynku..
Config Pind.2 = Input
Config Pind.3 = Input
Config Pina.7 = Output
Config Pind.6 = Output
Config Pind.7 = Output
Portd.2 = 1
Portd.3 = 1
Porta.7 = 0
Portd.7 = 1
Portd.6 = 1
On Int0 Int0_int
On Int1 Int0_int
Enable Interrupts
Enable Int0
Enable Int1
Do
'w tej petli ma nic nie byc (glowna programu)
Loop
End
Int0_int:
Portd.6 = 0
Disable Int0
Disable Int1
Porta.7 = 1
Do
If Pind.2 = 0 And Pind.3 = 0 Then
Portd.6 = 1
Portd.7 = 1
Stop Timer1
End If
Loop
Return
Prosze o pomoc w rozwiazaniu tego pojedynku..
Config Pind.2 = Input
Config Pind.3 = Input
Config Pina.7 = Output
Config Pind.6 = Output
Config Pind.7 = Output
Portd.2 = 1
Portd.3 = 1
Porta.7 = 0
Portd.7 = 1
Portd.6 = 1
On Int0 Int0_int
On Int1 Int0_int
Enable Interrupts
Enable Int0
Enable Int1
Do
'w tej petli ma nic nie byc (glowna programu)
Loop
End
Int0_int:
Portd.6 = 0
Disable Int0
Disable Int1
Porta.7 = 1
Do
If Pind.2 = 0 And Pind.3 = 0 Then
Portd.6 = 1
Portd.7 = 1
Stop Timer1
End If
Loop
Return
Nie napisałeś co się dzieje, ale zgaduje, ż epo jednym wykryciu przycisku więcej juz nie reaguje na naciskanie
A tylko dlatego, że wyłączasz przerwania, wykonujesz obsługe przerwania, a potem należy je spowrotem właczyć, czego Ty juz mie robisz.
Jeśli to jest dla procka AVR to przynajmniej częśc z nich jeśli nie wszystkie ma możliwośc ustawienia wywołania przerwania zboczem, zamiast poziomem, co też może być rozwiązaniem, jeśli przy przyciskach masz układy RC, które odfiltrują drgania styków przy przełączeniu.
pozdroofka
A tylko dlatego, że wyłączasz przerwania, wykonujesz obsługe przerwania, a potem należy je spowrotem właczyć, czego Ty juz mie robisz.
Jeśli to jest dla procka AVR to przynajmniej częśc z nich jeśli nie wszystkie ma możliwośc ustawienia wywołania przerwania zboczem, zamiast poziomem, co też może być rozwiązaniem, jeśli przy przyciskach masz układy RC, które odfiltrują drgania styków przy przełączeniu.
pozdroofka
Fakt, nie napisalem, przepraszam.Nie napisałeś co się dzieje, ale zgaduje, ż epo jednym wykryciu przycisku więcej juz nie reaguje na naciskanie
Do Portd.6 jest podlaczona dioda. I sęk w tym, ze przy PIERWSZYM nacisnieciu przycisku, gdy jeszcze przerwania sa zalaczone, dioda ta NIE zapala sie, gdy usune Disable INT0, DISABLE INT1, to jest wszystko w porzadku, malo tego, gdy jest skok do podprogramu, rowniez ta dioda sie nie zapala, moj wniosek jest taki, ze program albo sie wiesza, albo cos inszego, ale nie wiem juz co Kombinuje nadal z tym i caly czas mam ten sam problem, juz nawet od zera to napisalem i nic...
Jeszcze dodam, ze procek to AT90S8515 @ 4MHz
Eh odwieczny problem, programista widzi to co chce, a nie to co jest
Od poczatku:
Wywołujesz przerwanie, procek je wykonuje i....
zapentla się tutaj:
<quote>
Do
If Pind.2 = 0 And Pind.3 = 0 Then
Portd.6 = 1
Portd.7 = 1
Stop Timer1
End If
Loop
</quote>
teraz jeśli przerwania są właczone, to kolejne przerwanie powoduje ponowne wykonanie obsługi tego przerwania. Ale jeśli wyłączysz te przerwania, to procek już nie ma szans wyjścia z tej pentli i jedyny ratunek to reset.
Od poczatku:
Wywołujesz przerwanie, procek je wykonuje i....
zapentla się tutaj:
<quote>
Do
If Pind.2 = 0 And Pind.3 = 0 Then
Portd.6 = 1
Portd.7 = 1
Stop Timer1
End If
Loop
</quote>
teraz jeśli przerwania są właczone, to kolejne przerwanie powoduje ponowne wykonanie obsługi tego przerwania. Ale jeśli wyłączysz te przerwania, to procek już nie ma szans wyjścia z tej pentli i jedyny ratunek to reset.
A okazalo sie, ze rozwiazanie banalne;] dodalem "Exit Do" i dzialaEh odwieczny problem, programista widzi to co chce, a nie to co jest
Od poczatku:
Wywołujesz przerwanie, procek je wykonuje i....
zapentla się tutaj:
<quote>
Do
If Pind.2 = 0 And Pind.3 = 0 Then
Portd.6 = 1
Portd.7 = 1
Stop Timer1
End If
Loop
</quote>
Raczej trywialne
Zamiast dodać "Exit Do" , wystarczy usunąć "Do" i "Loop", a "Disable Intx" jest zbędne , ponieważ AVR-y robią to automatycznie.
[/quote]
Dobra, zrobie to, co powinienem zrobic na samym poczatku, opisze dokladnie co chce uzyskac. Wiec tak:
Po wlaczeniu zasilania uPC jest w stanie uspienia (sleep), wyswietlacz LCD wylaczony (przy pomocy MOSFET'a[BSS89] odlaczone zasilanie). Po nacisnieciu jednego z dwoch przyciskow uklad budzi sie, zalaczany jest wyswietlacz i pojawia sie temperatura z dwoch czujnikow. Zalaczony zostaje tez Timer1 w trybie Timer ustawiony na 10. Jezeli czas uplynie to uklad ponownie "idzie spac", natomiast gdy uzytkownik wcisnie oba przyciski (petla Do...loop w podprogramie obslugujacym przerwanie) to przechodzimy do ustawien termometru (alarmy, RS232 oraz czas po jakim uklad "idzie spac"), w tym podprogramie WSZYSTKIE przerwania sa zablokowane, gdy wybiore w menu "Wyjscie" dopiero wtedy ponownie Ovf1 z Timer1 jest zalaczane.
Problemem dla mnie jak na razie jest odpowiednia obsluga przerwan, nie mam pomyslu jak je pogodzic aby dzialalo.
Moze teraz bedzie Wam, Forumowicze, latwiej pomoc mi w rozwiazaniu problemu przerwaniowego.
Zamiast dodać "Exit Do" , wystarczy usunąć "Do" i "Loop", a "Disable Intx" jest zbędne , ponieważ AVR-y robią to automatycznie.
[/quote]
Dobra, zrobie to, co powinienem zrobic na samym poczatku, opisze dokladnie co chce uzyskac. Wiec tak:
Po wlaczeniu zasilania uPC jest w stanie uspienia (sleep), wyswietlacz LCD wylaczony (przy pomocy MOSFET'a[BSS89] odlaczone zasilanie). Po nacisnieciu jednego z dwoch przyciskow uklad budzi sie, zalaczany jest wyswietlacz i pojawia sie temperatura z dwoch czujnikow. Zalaczony zostaje tez Timer1 w trybie Timer ustawiony na 10. Jezeli czas uplynie to uklad ponownie "idzie spac", natomiast gdy uzytkownik wcisnie oba przyciski (petla Do...loop w podprogramie obslugujacym przerwanie) to przechodzimy do ustawien termometru (alarmy, RS232 oraz czas po jakim uklad "idzie spac"), w tym podprogramie WSZYSTKIE przerwania sa zablokowane, gdy wybiore w menu "Wyjscie" dopiero wtedy ponownie Ovf1 z Timer1 jest zalaczane.
Problemem dla mnie jak na razie jest odpowiednia obsluga przerwan, nie mam pomyslu jak je pogodzic aby dzialalo.
Moze teraz bedzie Wam, Forumowicze, latwiej pomoc mi w rozwiazaniu problemu przerwaniowego.
To w ramach testu :
To tylko szkic programu
Piotrek
Kod: Zaznacz cały
Dim I As Byte
On Int0 Pobudka Nosave
On Int1 Pobudka Nosave
Enable Int0
Enable Int1
Do
Gosub Idz_spac
' Portd.x=x 'włączamy LCD i co tam jeszcze potrzeba
Initlcd 'bo był wyłączony i jednocześnie czas potrzebny
'na stabilizację styków przycisków
' Waitms xx ' dla pewności że LCD się "rozgrzał" i styki przycisków już się "uspokoiły"
Cls
If Pind.2 = 0 And Pind.3 = 0 Then
Gosub Ustawienia
Else
Gosub Temperatura
End If
Loop
Ustawienia:
'podprogram do ustawiania parametrów urządzenia
Lcd "Ustawienia" 'test
Wait 1 'test
Return 'test
Temperatura:
For I = 0 To 10 'dobrać doświadczalnie
'pobierz i wyświetl temperaturę tylokrotnie , żeby to zajęło procowi np. 10s
Lcd I 'test
Wait 1 'test
Home 'test
Next
Return
Idz_spac:
' Portx.x=x ' wyłączamy LCD, itp.
Enable Interrupts
sleep
Return
Pobudka:
Disable Interrupts
Ret 'a nie return(reti) bo by włączył przerwania łobuz jeden :)
Piotrek
[quote="szymel"]To w ramach testu :
Fakt. Niepotrzebnie bawilem sie w timer1 Ale do rzeczy, dziala wszystko rewelacyjnie, za wyjatkiem tego, ze CPU niie idzie "spać". Doszedlem do tego, ze zrobie wstawke asemblerowa:
$asm
ldi r16,$02
Out Mcucr , R16
sei
in r16,mcucr
ori r16,(1<SE)
Out Mcucr , R16
sleep
$end Asm 'umieszczona w miescu, w ktorym wpisales sleep.
Efekt jest taki, ze CPU idzie spac, ale nie budzi sie INT0 i INT1 nie rusza go. Na hibernatyka nadaje sie, gorzej z budzeniem
Kod: Zaznacz cały
Idz_spac:
' Portx.x=x ' wyłączamy LCD, itp.
Enable Interrupts
sleep
Return
Pobudka:
Disable Interrupts
Ret 'a nie return(reti) bo by włączył przerwania łobuz jeden :)
$asm
ldi r16,$02
Out Mcucr , R16
sei
in r16,mcucr
ori r16,(1<SE)
Out Mcucr , R16
sleep
$end Asm 'umieszczona w miescu, w ktorym wpisales sleep.
Efekt jest taki, ze CPU idzie spac, ale nie budzi sie INT0 i INT1 nie rusza go. Na hibernatyka nadaje sie, gorzej z budzeniem
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 22 gości