| Author |
Message
|
nauritius Poziom 7

Joined: 28 Dec 2009 Posts: 22
|
#1
17 Mar 2010 12:33 [Mega8][Bascom] Pomiar prędkości obrotowej |
|
|
|
Celem jest pomiar prędkosci obrotowej. Program się kompiluje, ale wyświetla cały czas 0.0 rpm. Nie wiem gdzie tkwi błąd, czy ktoś może mi pomóc?
| Code: |
$regfile = "m8def.dat"
$crystal = 8000000
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
Config Timer1 = Timer , Prescale = 8 , Capture Edge = Rising
Config Int0 = Rising
Dim Wynik As Single
Dim Zmienna As Single
Enable Interrupts
Enable Timer1
Enable Int0
On Int0 Przerwanie
Do
cls
Lcd "obrotomierz"
Lowerline
Lcd Wynik ; " rpm"
Loop
End
Przerwanie:
Stop Timer1
Zmienna = Timer1
Wynik = 60000000 / Zmienna
Start Timer1
Return
|
|
|
| Back to top |
|
 |
Google

|
#
17 Mar 2010 12:33 |
|
|
|
|
|
| Back to top |
|
 |
M. S. Poziom 21

Joined: 12 Jan 2005 Posts: 1492 Location: Czechowice - Dziedzice
|
#2
17 Mar 2010 12:58 Re: [mega8][Bascom] Dlaczego program nie działa? |
|
|
|
Wstaw przed Do instrukcję Start Timer1. Z helpa nie wynika, że Config włącza timer automatycznie, a jeśli ten się nie uruchomi to nie będzie przerwania i nie zadziałają instrukcje Start/Stop w podprogramie obsługi przerwania.
P. S. Nie miga ci wyświetlacz? Zastosuj Locate albo Upperline zamiast CLS.
|
|
| Back to top |
|
 |
janbernat Poziom 23

Joined: 21 Oct 2008 Posts: 3680 Location: Warszawa
|
#3
17 Mar 2010 15:28 Re: [mega8][Bascom] Dlaczego program nie działa? |
|
|
|
Sprawdź połączenia- czy na wejście INT0 wchodzi jakiś sygnał.
|
|
| Back to top |
|
 |
nauritius Poziom 7

Joined: 28 Dec 2009 Posts: 22
|
#4
17 Mar 2010 18:08 Re: [mega8][Bascom] Dlaczego program nie działa? |
|
|
|
OK, dzięki;) Faktycznie, sygnał miałem podpięty do pind.5...
|
|
| Back to top |
|
 |
janbernat Poziom 23

Joined: 21 Oct 2008 Posts: 3680 Location: Warszawa
|
#5
17 Mar 2010 19:06 Re: [mega8][Bascom] Dlaczego program nie działa? |
|
|
|
Co nie zmienia faktu że głopoty pokazuje.
|
|
| Back to top |
|
 |
emarcus Poziom 18

Joined: 29 Nov 2008 Posts: 556 Location: Tecumseh, Ca
|
#6
17 Mar 2010 23:44 Re: [mega8][Bascom] Dlaczego program nie działa? |
|
|
|
| nauritius wrote: |
| Celem jest pomiar prędkosci obrotowej. |
Ta czesc twojej wypowiedzi rozumiem, ale dalej jest gorzej.
Z listingu programu nie mozna doszukac sie jaka metode przyjmujesz w pomiarze RPM.
Czy to ma byc zwyczajny pomiar czasu jednego obrotu i przliczenie na RPM (pomiar pomiedzy dwoma 'rising edges') z uzyciem jednego z timerow i jednego interruptu, czy tez w okreslonych przedzialach czasu masz zamiar zliczac ilosc impulsow (obrotow) i to przeliczyc na RPM (z usrednianiem wyniku albo bez).
Masz Timer1 skonfigurowany do pracy w trybie 'Capture".
Tryb ten ma swoj interrupt ICP1 sterowany na pin PB0, ale musialby on byc uruchomiony i dopisana odpowiednia procedura co ma byc zrobione na okolicznosc wystapienia "Capture1". Inaczej nic z tego.
W zaleznosci od wybranej metody bedzie inna procedura pomiaru i obliczania wyniku.
Najprosciej i najlatwiej zrobisz to stosujac Timer0 i Interrupt powiedzmy INT0.
Zliczaj do jednej zmiennej przepelnienia timera0.
W momencie wystapienia INT0 kopiujesz stan Timera0 do innej zmiennej a takze stawiasz flage np: F=1
W petli Do ... loop dajesz caly rachunek obliczenia wszystkich zliczonych przedzialow czasowych, przeliczenie tego na RPM, kasowanie flagi i wyswietlenie wyniku na LCD. Aby nie "mrugac" wyswietlasz tylko zmienione wartosci na display
e marcus.
|
|
| Back to top |
|
 |
atom1477 Poziom 25

Joined: 14 Jul 2005 Posts: 6360
|
#7
18 Mar 2010 06:48 Re: [mega8][Bascom] Dlaczego program nie działa? |
|
|
|
| emarcus wrote: |
| Z listingu programu nie mozna doszukac sie jaka metode przyjmujesz w pomiarze RPM. |
Ja jakoś się doszukałem. A nie, sory. Nawet doszukiwać się nie musiałem.
Liczy okres pomiędzy impulsami.
Ale przerwanie to powinno wyglądać tak:
| Code: |
Przerwanie:
Zmienna = Timer1
Timer1 = 0
Wynik = 7500000 / Zmienna
Return
|
Preskaler Timera ustaw na 64.
A:
| Code: |
Capture Edge = Rising
|
przy konfiguracji Timera jako "Timer" jest niepotrzebne (w sumie to nawet błędne).
Pomijam już to że te całe obliczenia to trzeba by robić w pętli głównej. Tak jak napisał emarcus.
|
|
| Back to top |
|
 |
Google

|
#
18 Mar 2010 06:48 |
|
|
|
|
|
| Back to top |
|
 |
nauritius Poziom 7

Joined: 28 Dec 2009 Posts: 22
|
#8
18 Mar 2010 18:11 Re: [mega8][Bascom] Dlaczego program nie działa? |
|
|
|
Nie byłem pewien, czy Capture Edge jest potrzebne, ale sprawa już się wyjaśniła. Na razie nie mam możliwości "polowego" przetestowania, bo coś szwankuje mi generator. Mierze okres między dwoma impulsami (zbocza narastające). Przy prescalerze 8 minimalna mierzona prędkość to ok. 920rpm, także dodam jeszcze fragment zliczający przepełnienia. Dlaczego prescale 64 byłby lepszy? Czy nie zmniejszy się dokładność?
|
|
| Back to top |
|
 |
atom1477 Poziom 25

Joined: 14 Jul 2005 Posts: 6360
|
#9
18 Mar 2010 19:13 Re: [mega8][Bascom] Dlaczego program nie działa? |
|
|
|
Preskale 64 był by lepszy bo mógł byś mierzyć mniejsze prędkości.
|
|
| Back to top |
|
 |
nauritius Poziom 7

Joined: 28 Dec 2009 Posts: 22
|
#10
18 Mar 2010 21:01 Re: [mega8][Bascom] Dlaczego program nie działa? |
|
|
|
Zrobiłem przypadek ze zliczaniem przepełnień timera1:
| Code: |
$regfile = "m8def.dat"
$crystal = 8000000
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
Config Timer1 = Timer , Prescale = 8
Config Int0 = Rising
Dim Wynik As Single
Dim Zmienna As Single
Dim Zmienna2 As Single
Dim M As Byte
Dim N As Byte
Enable Interrupts
Enable Timer1
Enable Int0
M = 0 'ilość przepelnien timera1
N = 0 '0-pierwszy pomiar;1-pomiary kolejne
On Int0 Przerwanie
Do
If Timer1 = 65536 Then
Stop Timer1
Timer1 = 0
Incr M
Start Timer1
End If
Wynik = 60000000 / Zmienna 'obliczanie rpm
Cls
Lcd "obrotomierz"
Lowerline
Lcd Wynik ; " rpm"
Loop
End
Przerwanie:
Stop Timer1
If N = 0 Then 'sprawdzam, czy to pierwszy pomiar
Start Timer1
N = 1 'ustawiam,ze pierwszy pomiar wykonano
Return
Else
If M = 0 Then ' rpm mieszcza sie w zakresie licznika timer1
Zmienna = Timer1
Else 'nastapiło m przepelnien
Zmienna2 = M * 65536
Zmienna = Zmienna2 + Timer1
Timer1 = 0
M = 0
N = 1
End If
End If
Start Timer1
Return
|
jak myślicie, zadziała? Mam takie pytania:
1. Czy stop timer1 automatycznie zeruje timer?
2. Opłaca się uwzględniać, to , że w pierwszym przerwaniu będe miał 0-rowy okres?
|
|
| Back to top |
|
 |
atom1477 Poziom 25

Joined: 14 Jul 2005 Posts: 6360
|
#11
18 Mar 2010 21:34 Re: [mega8][Bascom] Dlaczego program nie działa? |
|
|
|
1. Nie.
2. Też nie.
Ale opłacało by się zrobić sprawdzanie przekroczenia zakresu. Bo bez tego jak znikną impulsy to układ zamarznie na ostatnim wskazaniu.
A w tym programie strasznie nakombinowałeś.
Ja bym po prostu dodał jedną zmienną od przepełnienia:
| Code: |
'--------------------------------------
Dim Okres As Long
Dim Predkosc As Single
Dim Timer1_MSB As Byte
Do
If Flaga = 1 Then
cli
Predkosc = Okres 'atomowy dostęp do zmiennej bo przerwanie od Timera też z niej korzysta
sei
Predkosc = 7500000 / Predkosc
Flaga = 0
...
...
End If
Loop
'--------------------------------------
Przerwanie_INT0:
Okres = Timer1_MSB
Shift Okres, Left, 16
Okres = Okres + Timer1
Timer1 = 0
Timer1_MSB = 0
Flaga = 1
Return
'--------------------------------------
Przerwanie_Timer1:
Timer1_MSB = Timer1_MSB + 1
If Timer1_MSB >= 100 Then 'Zabezpieczenie przed przepełnieniem
Timer1 = 0
Timer1_MSB = 0
Predkosc = 0
End If
Return
'--------------------------------------
|
|
|
| Back to top |
|
 |
emarcus Poziom 18

Joined: 29 Nov 2008 Posts: 556 Location: Tecumseh, Ca
|
#12
19 Mar 2010 03:24 Re: [mega8][Bascom] Dlaczego program nie działa? |
|
|
|
| atom1477 wrote: |
Ja jakoś się doszukałem. A nie, sory. Nawet doszukiwać się nie musiałem.
Liczy okres pomiędzy impulsami.
|
Eh, Nie kazdy nosi imie Albert...
e marcus
|
|
| Back to top |
|
 |
atom1477 Poziom 25

Joined: 14 Jul 2005 Posts: 6360
|
#13
19 Mar 2010 11:01 Re: [mega8][Bascom] Dlaczego program nie działa? |
|
|
|
No nie każdy. Ja też nie noszę ;)
|
|
| Back to top |
|
 |
Google

|
#
19 Mar 2010 11:01 |
|
|
|
|
|
| Back to top |
|
 |
janbernat Poziom 23

Joined: 21 Oct 2008 Posts: 3680 Location: Warszawa
|
#14
20 Mar 2010 13:20 Re: [Mega8][Bascom] Pomiar prędkości obrotowej |
|
|
|
| Code: |
'Działa od 30rpm do 300000rpm
$regfile = "m8def.dat"
$crystal = 8000000
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
Config Timer1 = Timer , Prescale = 64
Config Int0 = Rising
Dim Flaga As Byte
Dim Text As String * 10
Dim Wynik As Single
Dim Zmienna As Word
Dim Okres As Long
Dim Predkosc As Single
Dim Timer1_msb As Byte
Enable Interrupts
Enable Int0
enable OVF1
Cls
Lcd "obrotomierz"
Cursor Off
On Int0 Przerwanie_int0
On Ovf1 Przerwanie_timer1
Do
If Flaga = 1 Then
cli
Predkosc = Okres 'atomowy dostęp do zmiennej bo przerwanie od Timera też z niej korzysta
sei
Wynik = 7500000 / Predkosc
Flaga = 0
Text = Fusing(wynik , "#.&")
Lowerline
Lcd "rpm: " ; Text ;" "
End If
Loop
Przerwanie_int0:
Okres = Timer1_msb
Shift Okres , Left , 16 'a tu była mała pomyłka
Okres = Okres + Timer1
Timer1 = 0
Timer1_msb = 0
Flaga = 1
Return
Przerwanie_timer1:
'Timer1_msb = Timer1_msb + 1; 'A to nie działa-nie wiem dlaczego
Incr Timer1_msb
If Timer1_msb >= 100 Then 'Zabezpieczenie przed przepełnieniem
Timer1 = 0
Timer1_msb = 0
Predkosc = 0
End If
Return
|
Chociaż wynalazków atoma to tak do końca nie rozumiem- ale chyba ten typ tak ma.
No ale sprawdziłem w praktyce- działa.
Pewnie sam bym to starał się zrobić w bardziej tradycyjny sposób- a nie tak "atomowy"- ale pewnie by zajęło więcej kodu.
P.S.
Przy braku impulsów na INT pokazuje ostatni wynik- a nie 0.
|
|
| Back to top |
|
 |