Witam
W prockach dopiero raczkuje.
Robię obrotomierz do samochodu (choć można zastosować to wszedzie). Oparłem to na atmega16 bo taki akurat teraz mam, ale docelowo ma byc na 2312.Na razie jest wszystko w fazie testowej na biurku, ale założenia są takie: na kole zamachowym umieszczam siakiś czujnik, podaje to na układ formowania impulsu, z którego będę otrzymywał dodatnie impulsy,każda o czasie trwania 1ms(lub mniej bo procek i tak se to wychwyci).Impulsy testowe generuje sobie na innym procku, na przerwaniach, wiec są bardzo dokładne.
Zasada pomiaru polega na pomiarze czasu między impulsami.Dla 60obr/min. koła zamachowego otrzymuje 1sek, dla 6000obr/min otrzymuje 0,01sek czyli 10ms.Program napisałem w przeklętym BASCOM'ie, ale widze, że trza powoli się przesiąść na asm i C.Ale póki co robię to w bascom'ie.Mam dwie wersje.W ver1 pomiar polega na tym, że impulsy są podawane na zew. przerwanie (wyzwalane zerem ale to szczegol), gdy wystapi przerwanie zatrzymuje sie timer1 zapamietuje stan licznika, zaruje timer, startuje od nowa, przeliczenie licznika na oborty ,licznik*czas 1 taktu timera (bascom robi to szczegolnie wolno) wyswietla obroty, wraca do petli glownej , i tak w kółko.WADA: odswierzanie wyniku zalezy od obrotów ,nie wiem czy on nadąża przeliczać obroty,powyzej 3000obr wyswietlanie się "kaszani", procek miedzy impulsami nic nie robi.Druga wersja:przenioslem wszystko do petli glownej programu i wykorzystalem polecenie BITWAIT.Tu tez wyswietlenie wyniku zalezy od obortow ale nie jest juz tak czeste i nic sie nie kaszani.Nie moge wykorzystac przrwania do wyswietlenia wyniku bo wtedy pojawiaja sie bledy w pomiarze czasu miedzy impulsami a wiec w obrotach.
Gdyby nie zaokrąglenie do obrotycal(kowite), bo nie chce az tak dokładnie, to obrotomierz jest dokładny do 3 miejsca po przecinku.Ta wersja pracuje OK.
Mile widziane jakieś sugestie ,uwagi porady.Dziękuję
Ponizej listingi:
W prockach dopiero raczkuje.
Robię obrotomierz do samochodu (choć można zastosować to wszedzie). Oparłem to na atmega16 bo taki akurat teraz mam, ale docelowo ma byc na 2312.Na razie jest wszystko w fazie testowej na biurku, ale założenia są takie: na kole zamachowym umieszczam siakiś czujnik, podaje to na układ formowania impulsu, z którego będę otrzymywał dodatnie impulsy,każda o czasie trwania 1ms(lub mniej bo procek i tak se to wychwyci).Impulsy testowe generuje sobie na innym procku, na przerwaniach, wiec są bardzo dokładne.
Zasada pomiaru polega na pomiarze czasu między impulsami.Dla 60obr/min. koła zamachowego otrzymuje 1sek, dla 6000obr/min otrzymuje 0,01sek czyli 10ms.Program napisałem w przeklętym BASCOM'ie, ale widze, że trza powoli się przesiąść na asm i C.Ale póki co robię to w bascom'ie.Mam dwie wersje.W ver1 pomiar polega na tym, że impulsy są podawane na zew. przerwanie (wyzwalane zerem ale to szczegol), gdy wystapi przerwanie zatrzymuje sie timer1 zapamietuje stan licznika, zaruje timer, startuje od nowa, przeliczenie licznika na oborty ,licznik*czas 1 taktu timera (bascom robi to szczegolnie wolno) wyswietla obroty, wraca do petli glownej , i tak w kółko.WADA: odswierzanie wyniku zalezy od obrotów ,nie wiem czy on nadąża przeliczać obroty,powyzej 3000obr wyswietlanie się "kaszani", procek miedzy impulsami nic nie robi.Druga wersja:przenioslem wszystko do petli glownej programu i wykorzystalem polecenie BITWAIT.Tu tez wyswietlenie wyniku zalezy od obortow ale nie jest juz tak czeste i nic sie nie kaszani.Nie moge wykorzystac przrwania do wyswietlenia wyniku bo wtedy pojawiaja sie bledy w pomiarze czasu miedzy impulsami a wiec w obrotach.
Gdyby nie zaokrąglenie do obrotycal(kowite), bo nie chce az tak dokładnie, to obrotomierz jest dokładny do 3 miejsca po przecinku.Ta wersja pracuje OK.
Mile widziane jakieś sugestie ,uwagi porady.Dziękuję
Ponizej listingi:
ver1------------------------------------------------------------------------
$crystal = 16000000 'atmega16-16
Config Portd = &B1111010
Portd = &B1111111
Dim Licznik As Word
'do tej zmniennej przypisuje stan licznika
Dim Czas As Single
'czas między impulsami,licznik*czas 1 taktu
Dim Obroty As Single
'przeliczony czas na obroty
Dim Obrotycal As Integer
'przeliczony czas na obroty
Config Timer1 = Timer , Prescale = 256
'czas taktu 16us
Enable Interrupts
Enable Int0
On Int0 Measurement
'wlaczenie obslugi przerwania int0
'w razie przerwania skocz do podprogramu: pomiar
Stop Timer1
'zatrzymanie timera
Cls
'-----------petla glowna-------------
Do
Loop
End
'------------nudno tu---------------
'podprogram pomiar
Measurement:
Stop Timer1
'zatrzymanie timera
Licznik = Timer1
'przypisanie jego zawartosci do zmiennej licznik
Timer1 = 0
'zerowanie timera
Start Timer1
'start timera
Czas = 0.000016 * Licznik
Obroty = 60 / Czas
Obrotycal = Obroty
'oblicznia licznika na obroty
Locate 1 , 10
Lcd Obrotycal ; " obrtow"
'wyswietlenie wyniku
Return
'procek wraca odpoczywac
ver2------------------------------------------------------------------------
$crystal = 16000000 ' atmega16-16
Config Portd = &B1111010
Portd = &B1111111
Dim Pom As Integer
'pomaga opóźnic wyswietlenie obr
Dim Licznik As Word
'do tej zmniennej przypisuje stan licznika
Dim Czas As Single
'czas między impulsami,licznik*czas 1 taktu
Dim Obroty As Single
'przeliczony czas na obroty
Dim Obrotycal As Integer
'przeliczony czas na obroty
Config Timer1 = Timer , Prescale = 256
'czas taktu 16us
Stop Timer1
Cls
Pom = 0
'--------------petla glowna--------------
Do
Timer1 = 0
'zerowanie timera1
Bitwait Pind.2 , Reset
Start Timer1
'oczekiwanie na impuls (tu akurat na "zero")
'oraz start timer1
Waitus 1200
'chwila przerwy az impuls 1ms sie skocznczy
Bitwait Pind.2 , Reset
Stop Timer1
'oczekiwanie na kolejny impuls
'zatrzymanie timera
Licznik = Timer1
'przypisanie zawartosci timera do zmiennej licznik
Czas = 0.000016 * Licznik
'przeliczenie licznika na czas
Obroty = 60 / Czas
'przeliczenie czasu na oborty
Obrotycal = Obroty
'przeliczenie obrotow na wartosci calkowite
If Pom = 10 Then
Locate 1 , 10
Lcd Obrotycal ; " "
Pom = 0
End If
Pom = Pom + 1
' ten warunek sprawia, ze wynik nie jest wyswietlany co 10ms tylko co 100ms
Loop
'------------------------------------
End