Witam wszystkich majsterkowiczów
Oto mój jeden z pierwszy programów napisanych na ATMEGE 8. Dotychczas programowanie mikrokontrolerów traktowałem jako zabawę, używając do tego BASCOMA i zestawu Treningowego. Obecnie stoję przed zamiarem budowy pewnego urządzenia ale przed rozpoczęciem prac chciałbym mieć pewność że część programowa będzie ok.
Sam nie jestem żadnym specjalistą od programowania mam parę napisanych programów w Pascalu, c++ czy Delphi ale raczej wszystkie prace są okupione ogromną ilością godzin spędzonych przy komputerze i wyrwanych włosów oczywiście….
Ale do rzeczy, urządzenie ma za zadanie zmierzy czas reakcji dwóch strzelców mierzących do celu. Procedura wygląda następująco:
1 - Urządzenie w stanie gotowości.
2 – Naciskamy przycisk START. Od naciśnięcie przycisku start następuje losowe załączenie w ciągu 8 sekund lampy bądź sygnalizatora dźwiękowego dającego strzelcom sygnał do oddania strzału. Od momentu uruchomienia sygnalizatora następuje odmierzanie T czasu.
3 – Zawodnicy oddają strzał aktywując przy tym sensory u celu, które automatycznie określają przedział czasu T1 i T2. (T1w = T1-T oraz T2w = T2-T)
4 – Procesor wylicza czasy reakcji i wyświetla czas zwycięzcy
5 – Po naciśnięciu przycisku RESET wszystko wraca do punktu nr 1.
Program po wgraniu do procesora i emulacji na przyciskach działa aczkolwiek w mojej głowie rodzą się pewne pytania i wątpliwości oto i one:
1. Używając kwarcu 8MHz i przy wybraniu preskalera 8 przy załadowaniu do licznika TIMER0 wartości 156, przerwanie zostaje wywołane co 0,1 ms. Moje pojęcie wywołania tego przerwania jest następujące - (jeżeli jest mylne prosiłbym o wyprowadzenie z błędu), Zmienna Ti w ciągu 0,1 ms zwiększa swoją wartość TYLKO o jeden.
2. Czy ATMEGA 8 jest na tyle szybka aby dokonać pomiaru takiego czasu rzędu 0,1 ms w istniejącym programie, czy też byłaby potrzebna jakaś wstawka asemblerowa. Czytałem w różnych poprzednich postach że przy precyzyjnych pomiarach czasu najlepszy jest asembler ponieważ można policzy czasy procedur co do jednego cyklu zegara. Nie zamierzam tu wywoływać zażartej polemiki pomiędzy zwolennikami prostych języków programowania a programistami używającymi asemblera, bo wskazania logiki mówią o tym że asembler pod tym względem jest dużo lepszy, niestety nie każdy miał z nim do czynienia i nie każdy go rozumie.
Jednak wracając do problemu, czy procedury bascom’owe w tym przypadku nie będą spowalniały pomiaru zegara.
Czy istniałby sens zmiany preskalera na 1, automatycznie zmiany czasu wywołania przerwania a tym samym uprecyzyjnienia pomiaru, czy ma to sens dla tego procesora, czy poradziłby on sobie z takim zliczaniem przy użyciu istniejącego kodu. Czy też musiałbym urzyc czegoś szybszego.
W przypadku niejasności co do kodu proszę pytać, jestem ciekaw ile popełniłem błędów a co do optymalizacji wiem że każdy ma swoje drogi i rozwiązania. Ja na razie oparłem to na części czysto teoretycznej aczkolwiek praktyka pokazała że program po wgraniu do procesora działa, tylko zastanawia mnie na ile realne jest zliczenie tego czasu. Nie wiem też za bardzo jakie w rzeczywistości mogą by różnice pomiędzy dwoma osobnikami oddającymi strzał, tak że z góry zakładam najmniejszy przedział czasu dostępny w mojej testowej konstrukcji ATMEGA 8 .
Oto listing programu
Z góry dziękuję za wszystkie sugestie i porady. Pozdrawiam wszystkich użytkowników portalu.


Oto mój jeden z pierwszy programów napisanych na ATMEGE 8. Dotychczas programowanie mikrokontrolerów traktowałem jako zabawę, używając do tego BASCOMA i zestawu Treningowego. Obecnie stoję przed zamiarem budowy pewnego urządzenia ale przed rozpoczęciem prac chciałbym mieć pewność że część programowa będzie ok.
Sam nie jestem żadnym specjalistą od programowania mam parę napisanych programów w Pascalu, c++ czy Delphi ale raczej wszystkie prace są okupione ogromną ilością godzin spędzonych przy komputerze i wyrwanych włosów oczywiście….
Ale do rzeczy, urządzenie ma za zadanie zmierzy czas reakcji dwóch strzelców mierzących do celu. Procedura wygląda następująco:
1 - Urządzenie w stanie gotowości.
2 – Naciskamy przycisk START. Od naciśnięcie przycisku start następuje losowe załączenie w ciągu 8 sekund lampy bądź sygnalizatora dźwiękowego dającego strzelcom sygnał do oddania strzału. Od momentu uruchomienia sygnalizatora następuje odmierzanie T czasu.
3 – Zawodnicy oddają strzał aktywując przy tym sensory u celu, które automatycznie określają przedział czasu T1 i T2. (T1w = T1-T oraz T2w = T2-T)
4 – Procesor wylicza czasy reakcji i wyświetla czas zwycięzcy
5 – Po naciśnięciu przycisku RESET wszystko wraca do punktu nr 1.
Program po wgraniu do procesora i emulacji na przyciskach działa aczkolwiek w mojej głowie rodzą się pewne pytania i wątpliwości oto i one:
1. Używając kwarcu 8MHz i przy wybraniu preskalera 8 przy załadowaniu do licznika TIMER0 wartości 156, przerwanie zostaje wywołane co 0,1 ms. Moje pojęcie wywołania tego przerwania jest następujące - (jeżeli jest mylne prosiłbym o wyprowadzenie z błędu), Zmienna Ti w ciągu 0,1 ms zwiększa swoją wartość TYLKO o jeden.
Pomiar: ‘ Przerwanie
Timer0 = 156
If Licz = 1 Then
Incr Ti
End If
Return2. Czy ATMEGA 8 jest na tyle szybka aby dokonać pomiaru takiego czasu rzędu 0,1 ms w istniejącym programie, czy też byłaby potrzebna jakaś wstawka asemblerowa. Czytałem w różnych poprzednich postach że przy precyzyjnych pomiarach czasu najlepszy jest asembler ponieważ można policzy czasy procedur co do jednego cyklu zegara. Nie zamierzam tu wywoływać zażartej polemiki pomiędzy zwolennikami prostych języków programowania a programistami używającymi asemblera, bo wskazania logiki mówią o tym że asembler pod tym względem jest dużo lepszy, niestety nie każdy miał z nim do czynienia i nie każdy go rozumie.
Jednak wracając do problemu, czy procedury bascom’owe w tym przypadku nie będą spowalniały pomiaru zegara.
Czy istniałby sens zmiany preskalera na 1, automatycznie zmiany czasu wywołania przerwania a tym samym uprecyzyjnienia pomiaru, czy ma to sens dla tego procesora, czy poradziłby on sobie z takim zliczaniem przy użyciu istniejącego kodu. Czy też musiałbym urzyc czegoś szybszego.
W przypadku niejasności co do kodu proszę pytać, jestem ciekaw ile popełniłem błędów a co do optymalizacji wiem że każdy ma swoje drogi i rozwiązania. Ja na razie oparłem to na części czysto teoretycznej aczkolwiek praktyka pokazała że program po wgraniu do procesora działa, tylko zastanawia mnie na ile realne jest zliczenie tego czasu. Nie wiem też za bardzo jakie w rzeczywistości mogą by różnice pomiędzy dwoma osobnikami oddającymi strzał, tak że z góry zakładam najmniejszy przedział czasu dostępny w mojej testowej konstrukcji ATMEGA 8 .
Oto listing programu
$crystal = 8000000
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.5 , Db5 = Portd.6 , Db6 = Portd.7 , Db7 = Portd.4 , E = Portd.3 , Rs = Portd.2
Config Portb = &B11000110 : Portb = &B1111001
Config Portc = &B11111110 : Portc = &B00000001
Config Portd = &B11111111 : Portd = &B00000000
Config Timer0 = Timer , Prescale = 8 :
Dim A1 As Byte
Dim A2 As Byte
Dim Ti As Long
Dim T1 As Long
Dim T2 As Long
Dim Tl As Byte
Dim T1r As Single
Dim T2r As Single
Dim Licz As Bit
Dim C As Bit
Declare Sub Czysc
Declare Sub Show
Declare Sub Losuj
A1 = 0 : A2 = 0 : Licz = 0 : C = 0 : Ti = 0 : T1 = 0 : T2 = 0
Cls
Lcd " Hey Guys !!!"
Lowerline : Lcd " Lets Go !!!" : Cursor Off
'---------------------------------main program-----------------------------------------
On Timer0 Pomiar
Do
If Pinc.0 = 0 Then 'Pushbutton RESET
Czysc
End If
If Pinb.5 = 0 And C = 0 Then 'Pushbutton START
C = 1
Losuj
Enable Interrupts : Enable Timer0
Licz = 1
End If
If A1 = 1 And A2 = 1 Then
Show
End If
Loop
End 'Glowna petla programu
'----------------------------------przerwanie------------------------------------------
Pomiar:
Timer0 = 156 '
If Pinb.3 = 0 And A1 = 0 Then 'Uruchamia strzelec nr 1
A1 = 1 : T1 = Ti 'in 0-zwarte do masy
End If
If Pinb.4 = 0 And A2 = 0 Then 'Uruchamia strzelec nr 2
A2 = 1 : T2 = Ti
End If
If Licz = 1 Then
Incr Ti
End If
Return
'-----------------------procedura pokazania wyniku------------------------------
Sub Show
Cls
Disable Timer0
T1r = T1 / 10000
T2r = T2 / 10000
Lcd "T1=" ; T1r ; " S"
Lowerline
Lcd "T2=" ; T2r ; " S"
If T1 > T2 Then 'wygrywa nr 2
Portb.2 = 1
End If
If T1 < T2 Then 'wygrywa nr 1
Portb.1 = 1
End If
A1 = 0 : A2 = 0
Cursor Off
End Sub
'-----------------------procedura zerowania i kasowania ekranu------------------
Sub Czysc
Cls
Lcd " Hey Guys !!!"
Lowerline : Lcd " Lets Go !!!" : Cursor Off
Portb.1 = 0 : Portb.2 = 0
Ti = 0 : T1 = 0 : T2 = 0 : A1 = 0 : A2 = 0 : Licz = 0 : C = 0
Portd.0 = 0 'Wylaczenie sygnalizatora
End Sub
'-----------------------procedura losowania czasu do startu------------------
Sub Losuj
Cls
Lcd "....Counting...."
Tl = Rnd(8) : Incr Tl
Wait Tl
Portd.0 = 1 'Sygnalizator, Lampa, syrena - cokolwiek
End Sub
Z góry dziękuję za wszystkie sugestie i porady. Pozdrawiam wszystkich użytkowników portalu.