Glaubst Du, dass Du einen Code, den ich mal für ATMega32 geschrieben hab', umbasteln kannst ?
Glaubst Du, dass Du einen Code, den ich mal für ATMega32 geschrieben hab', umbasteln kannst ?
Hallo MagicWSmoke,
Danke für deine schnelle Antwort. Ich denke das ich das schon irgend wie hinkriegen sollte. Ansonsten ist es aber mir bestimmt auch so eine Hilfe. Also wäre ich dir sehr dankbar wenn du das Programm mir schicken oder posten könntest.
Mfg
bnitram
Dann versuch' Dich mal hiermit:
Edit:Code:$regfile = "m32def.dat" $crystal = 8000000 $hwstack = 64 $swstack = 64 $framesize = 64 Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.1 , Db6 = Portd.5 , Db7 = Portd.0 , E = Portd.2 , Rs = Portd.3 Config Lcd = 16 * 2 Cursor Off Const True = 1 Const False = 0 Const Measure_success = 0 Const Measure_failed = 1 Const Measure_request = 2 Dim Frequency As Long Dim Capt_prev_val As Word Dim Capt_curr_val As Word Dim Measure_result As Long Dim Capt_result As Word At Measure_result Overlay ' Differenz aus Capture beschreibt das Low-Word von Measure_Result Dim Ovf_result As Word At Measure_result + 2 Overlay ' Mit dem Overflowergebnis das High-Word von Measure_Result beschreiben, spart das multiplizieren mit 65536 Dim Ovf_ctr As Word Dim F_str As String * 10 ' Variablen zur Ablaufsteuerung Dim Got_edge As Byte Dim Measure_status As Byte Config Timer1 = Timer , Prescale = 1 ' , Noise Cancel = 1 ' , Capture Edge = Falling ' , Noise Cancel = 1 ' Trigger durch Analogkomperator an Pin4, AIN1, AIN0 an Bandgap Reference 1V Config Aci = On , Compare = On Acsr.acbg = 1 On Capture1 Isr_capt Nosave Enable Capture1 On Ovf1 Isr_ovf Enable Ovf1 Ovf_ctr = 0 Got_edge = False Tifr = Bits(icf1 , Tov1) Enable Interrupts Initlcd Cursor Off Noblink Cls Locate 1 , 1 Lcd "START" Wait 2 Cls Do Locate 1 , 1 Measure_status = Measure_request While Measure_status = Measure_request Wend If Measure_status = Measure_failed Then Lcd "Timeout K.Erg." End If If Measure_status = Measure_success Then If Measure_result > 0 Then Measure_result = Measure_result / 10 ' Frequency = 826787928 / Measure_result ' Kalibrierung für abweichenden internen RC Oszillator Frequency = 830996156 / Measure_result ' Frequency = 800000000 / Measure_result F_str = Str(frequency) Lcd "Freq: " ; Format(f_str , "000.000") ; " Hz" Else Lcd "Fehler, Ergebnis = 0" End If End If Waitms 50 Loop End Isr_capt: PUSH R22 LDS R22, ICR1L STS {Capt_curr_val}, R22 LDS R22, ICR1H STS {Capt_curr_val +1}, R22 POP R22 Pushall If Measure_status = Measure_request And Got_edge = True Then ' Messung angefordert und eine Flanke erkannt ? Capt_result = Capt_curr_val - Capt_prev_val ' Ja, dann Werte übernehmen Measure_status = Measure_success If Capt_curr_val < Capt_prev_val Then ' Natürlicher Overflow ? Decr Ovf_ctr ' Bereichsgrenze überschritten, Overflows um 1 erniedrigen End If Ovf_result = Ovf_ctr End If Capt_prev_val = Capt_curr_val ' Aktuellen CAP-Wert speichern Ovf_ctr = 0 ' Overflowzähler zurücksetzen Got_edge = True Popall Return Isr_ovf: Incr Ovf_ctr ' If Ovf_ctr > 122 Then ' Niedrigste Messfrequenz 1 Hz unterschritten If Ovf_ctr > 126 Then ' Korrektur für zu hohe RC Oszillatorfrequenz Got_edge = False Ovf_ctr = 0 If Measure_status = Measure_request Then Measure_status = Measure_failed End If Return
µC wird momentan mit 'nem 16MHz Quarz betrieben, war noch so im Code gestanden, hab's geändert.
Musst die Werte halt auf 4MHz Takt anpassen.
EditEdit:
Hab' gerad' mal den ATMega8 als µC angegeben, das compiliert ohne Probleme. Es sollte also reichen den Takt auf 4MHz anzupassen, da ist nur:
zu ändern. Dann LCD anpassen und der Analog-Comparator-Pin ist auch ein anderer.Code:Frequency = 830996156 / Measure_result If Ovf_ctr > 126 Then
Geändert von MagicWSmoke (10.11.2012 um 19:01 Uhr)
Hallo,
weil ich eigentlich auch gerade an einen Drehzahlmesser gedacht habe (und ich nehme an, es handelt sich noch um das Thema mit dem Benzinmotor)
habe ich das mal ausprobiert.
Ich habe leider auch nur einen ATmega16 herumliegen, das Programm ist also auch für Mega16, jedoch sollte es reichen, einfach die Pins, an die das Display angeschlossen ist, zu ändern.
Der Eingang ist Int0 (den es ja auch beim Mega8 gibt).
Die Umrechnung ist jetzt so ausgelegt, dass der Timer1 1Mio mal pro Sekunde tickt. Wenn man z.B. einen Quarz anderer Frequenz verwenden möchte müsste man das halt entweder im Prescaler oder in der Umrechnung ändern.
Der Code ist getestet und hat bei mir funktioniert.Code:$regfile "M16def.dat" $hwstack = 32 $swstack = 32 $framesize = 32 $crystal = 1000000 'Initialisiere Timer1 Config Timer1 = Timer , Prescale = 1 Enable Timer1 On Timer1 Isr_timer1 'Das LCD konfigurieren Config Lcd = 16 * 2 Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0 'Den Int0 konfigurieren, er dient zum erfassen der Pulse Config Int0 = Rising Enable Int0 On Int0 Isr_puls 'Die Interrupts global aktivieren Enable Interrupts 'Variablen Definieren Dim Timer1_overflows As Byte Dim Ticks As Long Dim Rpm As Long 'Variable auf Null setzen, nur um sicher zu gehen Timer1_overflows = 0 'Anfang Hauptprogramm +++++++++++++++++++++++++++++++++++++++++ Do 'Die Ticks in Umdrehunge pro Sekunde umrechnen Rpm = 60000000 / Ticks Cls Locate 1 , 1 Lcd "Umdrehungen: " Locate 2 , 1 Lcd Rpm 'Eine viertelsekunde warten, damit das Display nicht zu häufig Waitms 250 Loop 'Ende Hauptprogramm +++++++++++++++++++++++++++++++++++++++++ Isr_puls: 'Es wurde ein Puls registriert 'Anzahl der Ticks ermitteln Ticks = Timer1_overflows * 65536 Ticks = Ticks + Timer1 'Zurücksetzen Timer1 = 0 Timer1_overflows = 0 Return Isr_timer1: 'Timer 1 ist übergelaufen Timer1_overflows = Timer1_overflows + 1 Return
Natürlich, es wurde ja schon Code gepostet, aber das habe ich jetzt gerade eben ausprobieren müssen und villeicht nützt es dir ja etwas
EDIT: Habe gerade gesehen, dass die Textphrase "Umdrehungen * 1/min: " garicht platz hat am LCD, siehe Foto.
Also im Code auf "Umdrehungen: " geändert...
Mfg Thegon
Geändert von Thegon (11.11.2012 um 09:00 Uhr)
Danke euch beiden!!
Vielen Dank für die beiden Programme.
@Thegon:
Ja genau für den Verbrenner war es gedacht....
Ich denke ich werde dann den Code von Thegon morgen mal testen, da er eh schon perfekt für meinen Einsatzzweck ist. Trotzdem Danke an MagicWSmoke.
Mfg
bnitram
Hallo nochmal,
Werde erst heute zu dem Test kommen. Der Code funktioniert auf jedenfalls.
Ist es eig. egal wie lang ein "high" Signal ist oder ab wann beginnt der Timer zu zählen ??
Ist eine reine Verständnis frage.
Mfg
bnitram
Der Interrupt ist auf Rising gestellt (siehe Konfiguration des Interrupts), d.h. die ISR wird ausgelöst, wenn die Spannung von Low auf High wechselt. Es wird also genau die Zeit gemessen, die vergeht, zwischen zwei solchen Vorgängen. Wie Lange oder kurz diese pulse sind, ist praktisch egal.
Mfg Thegon
Ok vielen Dank für die info.
Bin heute leider von Test abgehalten worden. Der Hallsensor hat den Geist aufgegeben
Naja. Morgen wird ein neuer besorgt.
Mfg
bnitram
Hallo Forum,
Heute habe ich den Drehzahlmesser testen können. Leider hat er nicht funktioniert.
Ich habe den Sensor via LED getestet und er hat funktioniert. Wenn ich die Beine vom Sensor berühre, dann gibt der LCD mir irgend welche Werte aus. Allerdings funktioniert das ganze zusammen nicht. Werde wohl nochmal alles durchchecken.
Hab Ihr noch welche Ideen woran das liegen könnte??
Mfg
bnitram
Lesezeichen