Przerwania w Bascomie
- Aro
- Użytkownik
- Posty: 677
- Rejestracja: 30 paź 2006, 18:49
- Lokalizacja: Świerczyniec | Wrocław
- Kontakt:
Przerwania w Bascomie
Mam problem z ustawieniem pierwszeństwa przerwań . Chcę aby w trakcie wykonywania jakiegoś przerwania można było obsłużyc przerwanie od timera1. Chodzi o procesory AVR (atmega8)
-
ZbeeGin
W procesorach AVR nie ma możliwości dodatkowego ustawienia sprzętowo priorytetów przerwań - tzw. custom polling. Są one ustalone na sztywno i przerwanie o najmniejszym adresie wektora jest najważniejsze, zaś przerwanie o największym adresie jest najmniej ważne. System ten działa jedynie gdy w jednym momencie zgłoszone są dwa przerwania na raz. Wtedy system pollingu rozstrzyga, co ma być wykonane jako pierwsze.
W normalnych warunkach przerwanie zostaje zgłoszone, globalny system przerwań zostaje tymczasowo wyłączony (znacznik I), na stos trafia adres powrotny i rozpoczyna się obsługa tego przerwania. Zatem w tym czasie przerwania z innych źródeł nie zostaną wykonane. Podczas powrotu z przerwania stan globalnego systemu przerwań zostanie automatycznie przywrócony i jeśli teraz system stwierdzi, iż jakakolwiek flaga przerwania jest aktywna - zgłoszona wcześniej - to procesor znów przechodzi to trybu obsługi tego przerwania. Itd, aż wszystkie zgłoszone przerwania zostaną obsłużone.
Aby Twój program reagował na przerwanie od Timer1 w dowolnym innym przerwaniu wystarczy dodać na początku tej procedury polecenie Enable Interrupts, które ponownie włączy na żądanie programu użytkonika globalny system przerwań. Spowoduje to, że procesor będzie reagował na każde inne przerwanie w trakcie obsługi aktualnie wykonywanego. Jeśli korzystasz tylko z dwóch przerwań, z czego jedno to licznik Timer1, to taki system może być wystarczający. Jest tylko jednen wyjątek: jeśli tym pierwszym przerwaniem jest linia zewnętrzna (np. INT0) to taki system się nie sprawdzi. Dlaczego? Spróbuj wywnioskować sam...
Jeśli zależy ci zaś na obsłudze tylko tego jedynego przerwania - bo używasz ich więcej niż 2 lub jest aktywne którekolwiek przerwanie INTx - to należałoby przed włączeniem przerwań globalnych wyłączyć niepotrzebne przerwania przez Disable a przy opiuszczaniu procedury - tuż przed Return - włączyć je przez Enable. Na przykład:
Zauważ, że w procedurze obsługującej Timer1 nie włączam/wyłączam żadnych przerwań, gdyż globalny system wyłącza się automatycznie. Dopiero Return przywróci możliwość zgłaszania następnych przerwań. Chciałem aby przerwanie to stało się jakby najważniejsze w hierarchii i nie zostało przerwane przez żadne inne - oprócz "przerwania" na skutek wyzerowania procesora.
I pamiętaj o jednym, każde zreaktywowane przerwanie w innym przerwaniu to możliwość kolejnego odłożenia 25 bajtów na stosie HWStack! Zatem należy ten stos powiększyć, czy to przez dyrektywę $HWSTACK =, czy też w opcjach kompilatora. Domyślna wartość 32 na 100% nie wystarczy.
W normalnych warunkach przerwanie zostaje zgłoszone, globalny system przerwań zostaje tymczasowo wyłączony (znacznik I), na stos trafia adres powrotny i rozpoczyna się obsługa tego przerwania. Zatem w tym czasie przerwania z innych źródeł nie zostaną wykonane. Podczas powrotu z przerwania stan globalnego systemu przerwań zostanie automatycznie przywrócony i jeśli teraz system stwierdzi, iż jakakolwiek flaga przerwania jest aktywna - zgłoszona wcześniej - to procesor znów przechodzi to trybu obsługi tego przerwania. Itd, aż wszystkie zgłoszone przerwania zostaną obsłużone.
Aby Twój program reagował na przerwanie od Timer1 w dowolnym innym przerwaniu wystarczy dodać na początku tej procedury polecenie Enable Interrupts, które ponownie włączy na żądanie programu użytkonika globalny system przerwań. Spowoduje to, że procesor będzie reagował na każde inne przerwanie w trakcie obsługi aktualnie wykonywanego. Jeśli korzystasz tylko z dwóch przerwań, z czego jedno to licznik Timer1, to taki system może być wystarczający. Jest tylko jednen wyjątek: jeśli tym pierwszym przerwaniem jest linia zewnętrzna (np. INT0) to taki system się nie sprawdzi. Dlaczego? Spróbuj wywnioskować sam...
Jeśli zależy ci zaś na obsłudze tylko tego jedynego przerwania - bo używasz ich więcej niż 2 lub jest aktywne którekolwiek przerwanie INTx - to należałoby przed włączeniem przerwań globalnych wyłączyć niepotrzebne przerwania przez Disable a przy opiuszczaniu procedury - tuż przed Return - włączyć je przez Enable. Na przykład:
Kod: Zaznacz cały
On Int0 INT0_klawiury
On Timer0 Licznik0_czas
On Timer1 Licznik1_alarm
Enable Int0
Enable Timer0
Enable Timer1
Enable Interrupts
Do
' tu główny program
Loop
int0_klawiury:
'tutaj reakcja na klawisze
Disable Int0
Disable Timer0
Enable Interrupts
' przetwarzamy klawiury
Enable Int0
Enable Timer0
Return
licznik0_czas:
'tutaj reakcja na impulsy z czasowstrzymywacza :)
Disable Int0
Disable Timer0
Enable Interrupts
' przetwarzamy czas
Enable Int0
Enable Timer0
Return
licznik1_alarm:
'--_ALARM---
' przetwarzamy zgłoszenie alarmu
ReturnI pamiętaj o jednym, każde zreaktywowane przerwanie w innym przerwaniu to możliwość kolejnego odłożenia 25 bajtów na stosie HWStack! Zatem należy ten stos powiększyć, czy to przez dyrektywę $HWSTACK =, czy też w opcjach kompilatora. Domyślna wartość 32 na 100% nie wystarczy.
-
ZbeeGin
-
ZbeeGin
- Aro
- Użytkownik
- Posty: 677
- Rejestracja: 30 paź 2006, 18:49
- Lokalizacja: Świerczyniec | Wrocław
- Kontakt:
Jak chce wysłac jako kod to wyskakuje coś takiego:
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, [no address given] and inform them of the time the error occurred, and anything you might have done that may have caused the error.
More information about this error may be available in the server error log.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
nie wiem o co w tym chodzi i przesyłam jeszcze raz załącznik:
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, [no address given] and inform them of the time the error occurred, and anything you might have done that may have caused the error.
More information about this error may be available in the server error log.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
nie wiem o co w tym chodzi i przesyłam jeszcze raz załącznik:
- Załączniki
-
- program.rar
- Program
- (1.57 KiB) Pobrany 301 razy
-
ZbeeGin
Nie posiadam już zestawu z Mega8 (Przeszedł w inne dobre ręce...), ale uruchomiłem poprawiony program w symulatorze BASCOM AVR. I działał prawie dobrze. Niestety skąpość komentarzy
nie pozwala na szybkie rozgryzienie całości...
Program wchodzi w ustawienia, można z nich wyjść. Można zmienić dzień tygodnia (do tego doszłem) i raz udało Mi się także zmienić godzinę alarmu.
Wskazówki na przyszłość:
- dodawaj wymagane dyrektywy na początku (jaki procesor, stos, szybkość pracy łącza RS232),
- najpierw wszystko skonfiguruj a potem dopiero włączaj globlany system przerwań,
- jeśli użyjesz NoSave to raczej taką procedurę piszę się całą w asemblerze,
- więcej komentarzy!,
- stosuj wcięcia.
ps. Istotnie tego programu nie można wkleić w tag Code... (??)
Program wchodzi w ustawienia, można z nich wyjść. Można zmienić dzień tygodnia (do tego doszłem) i raz udało Mi się także zmienić godzinę alarmu.
Wskazówki na przyszłość:
- dodawaj wymagane dyrektywy na początku (jaki procesor, stos, szybkość pracy łącza RS232),
- najpierw wszystko skonfiguruj a potem dopiero włączaj globlany system przerwań,
- jeśli użyjesz NoSave to raczej taką procedurę piszę się całą w asemblerze,
- więcej komentarzy!,
- stosuj wcięcia.
ps. Istotnie tego programu nie można wkleić w tag Code... (??)
Ostatnio zmieniony 27 sie 2008, 18:08 przez ZbeeGin, łącznie zmieniany 1 raz.
Kod: Zaznacz cały
$regfile = "m8def.dat"
$hwstack = 64 'przerwania wymagają podania większej wartości niż domyślna
$framesize = 24
$swstack = 8
[ Dodano: 2006-11-01, 16:39 ]
Kod: Zaznacz cały
$regfile = "m8def.dat"
$hwstack = 64 'przerwania wymagają podania większej wartości niż domyślna
$framesize = 24
$swstack = 8
'******budzik************************************
' kwarc 32768
Config Pind.0 = Input
Config Pind.1 = Input
Config Pind.2 = Input
Dim B As Byte
Dim St1 As Byte , St2 As Byte
Dim M As Byte , G As Byte , D As Byte
Dim Sd As Bit , Stt As Bit , Flaga As Bit , S As Bit
Dim R As Byte
Dim A As Byte
Dim I As Byte
Dim Gb(7) As Byte
Dim Mb(7) As Byte
Dim Db As Byte
Deflcdchar 1 , 6 , 9 , 9 , 9 , 31 , 6 , 12 , 32
***********************************************
[ Dodano: 2006-11-01, 16:40 ]
Coś chyba jest z wielkością pliku zobaczę vzy nie ma jakichś ograniczeń