Hallo zusammen
Ich bastel hier grad rum um komme nicht weiter.
Was ich machen will ist folgendes.
Per Comparator möchte prüfen, ob eine anliegende Frequenz am AIN0 (+) in einem bestimmten Frequenzbereich liegt.
Dafür löst der AC ein Interrupt aus bei fallenden Flanken.
Der Comparator sollte so konfiguriert sein, dass beim Auslösen des Interrupts der Timerwert von Timer1 ins Capture-Register kopiert wird.
Die ISR wird sauber ausgelöst und das schön im Takt der Eingangsfrequenz. Alles korrekt.
Aber wenn ich in der ISR den Capture-Wert auswerte, kommt was falsches raus.
Wenn die Frequenz stimmt, sollte die Grüne LED an gehen, stimmt sie nicht, die Rote.
Hier mal das Programm
Alles anzeigen
Das Programm zeigt beharrlich nur rot an.
Das könnte man auch ohne Programm hinbekommen
Aber was stimmt am Programm nicht?
Wird hier der Timer1-Wert nicht im Capture-Register gespeichert?
Ich bastel hier grad rum um komme nicht weiter.
Was ich machen will ist folgendes.
Per Comparator möchte prüfen, ob eine anliegende Frequenz am AIN0 (+) in einem bestimmten Frequenzbereich liegt.
Dafür löst der AC ein Interrupt aus bei fallenden Flanken.
Der Comparator sollte so konfiguriert sein, dass beim Auslösen des Interrupts der Timerwert von Timer1 ins Capture-Register kopiert wird.
Die ISR wird sauber ausgelöst und das schön im Takt der Eingangsfrequenz. Alles korrekt.
Aber wenn ich in der ISR den Capture-Wert auswerte, kommt was falsches raus.
Wenn die Frequenz stimmt, sollte die Grüne LED an gehen, stimmt sie nicht, die Rote.
Hier mal das Programm
BASCOM-Quellcode
- $Regfile = "m168def.dat"
- $HWStack = 40
- $SWStack = 40
- $Framesize = 40
- $Crystal = 8000000
- Dim ISRTimeOld as Word ' letzter Timer1-Stand
- Dim ISRTimeNew as Word ' aktueller Timer1-Stand
- Dim ISRTimeDelta as Word ' Differenz der TimerNew-TimerOld
- Dim ISRCountOK as Byte ' Zähler Flanken-Anstand korrekt
- Dim ISRCountFail as Byte ' Zähler Flanken-Abstand nicht korrekt
- Dim GrenzeLow as Word
- Dim GrenzeHigh as Word
- GrenzeLow = 625 ' 1 / (625 * 8µs) = 200Hz
- GrenzeHigh = 125 ' 1 / (125 * 8µs) = 1kHz
- PinTrigger Alias PortC.5 ' Test-Pin
- Config PinTrigger = Output
- LED_OK Alias PortC.4
- LED_Fail Alias PortC.3
- Config LED_OK = Output
- Config LED_Fail = Output
- Declare Sub ISR_Flanke()
- Declare Sub ISR_Timer1Overflow()
- Config ACI = On , Compare = On , Trigger = falling
- ' Erzeugt FastPWM mit ca. 488kHz
- Config Timer1 = Timer , Prescale = 64 , PWM = 8 , Compare_A = Clear , Compare_B = CLEAR ' Periodendauer 8µs
- Config PortB.1 = Output
- Config PortB.2 = Output
- Compare1A = 20
- Compare1B = 20
- On ACI ISR_Flanke
- Enable ACI
- On OVF1 ISR_Timer1Overflow
- 'Enable OVF1
- Enable Interrupts
- Do
- NOP
- Loop
- Sub ISR_Flanke()
- ISRTimeNew = Capture1 ' Zeitstempel holen
- ISRTimeDelta = ISRTimeNew - ISRTimeOld ' Differenz berechnen
- ISRTimeOld = ISRTimeNew ' Aktuelle Stand sichern
- ' Bewerten, ob Flankenabstand im Range ist
- ' Select Case ISRTimeDelta
- ' Case GrenzeHigh to GrenzeLow ' 200Hz bis 1kHz
- ' 'If ISRCountOK < 255 then Incr ISRCountOK
- ' 'If ISRCountFail > 0 then Decr ISRCountFail
- ' Set LED_OK
- ' Reset LED_Fail
- ' Case Else ' außerhalb gültigem Bereich
- ' 'If ISRCountOK > 0 then Decr ISRCountOK
- ' 'If ISRCountFail < 255 then Incr ISRCountFail
- ' Reset LED_OK
- ' Set LED_Fail
- ' End Select
- If ISRTimeDelta > GrenzeLow and ISRTimeDelta < GrenzeHigh then
- Set LED_OK ' Grüne LED an
- Reset LED_Fail
- Else
- Reset LED_OK ' Rote LED an
- Set LED_Fail
- End If
- Set pinTrigger ' Test-Pin (Kontrolle ISR-Aufruf)
- Waitus 5
- Reset PinTrigger
- End Sub
- Sub ISR_Timer1Overflow()
- ' Pegel der Bewertung als PWM ausgeben:
- 'Compare1A = ISRCountOK
- 'Compare1B = ISRCountFail
- 'Compare1B = ISRCountFail
- End Sub
Das könnte man auch ohne Programm hinbekommen
Aber was stimmt am Programm nicht?
Wird hier der Timer1-Wert nicht im Capture-Register gespeichert?