Hallo,
Zitat von
Thegon
...jetzt kommt überhaupt kein Interrupt mehr herein. Naja, immerhin schon mal besser als 16, die nicht sollten.
aber es ist Bewegung drin und das ist immer gut
Ich bin auch weiter und habe meinen gegenwärtigen Code mal eingefügt. Bitte die umständliche Meßwertausgabe nicht weiter beachten Unten dran noch der Simulatorcode.
Zitat von
Besserwessi
In der ISR zu INT0 prüft man ob der Timer-wert klein ist (z.B. kleiner als 128 ) und das Flag für den Overflow Interrupt gesetzt ist.
Die Anregung ist eingeflossen durch Stoppen des Timers und Abfrage des TOV0 Flags in der INT0 ISR. Hatte gestern ähnlich probiert, aber die Timerstand Variable noch analog zum TCNT0 Register als Byte deklariert gehabt. Addieren von 256 brachte da noch irritierende Meßergebnisse.
Nun läuft es aber und die Abweichungen der Messergebnisse betragen nur noch maximal 16µs. Der tatsächliche Fehler muß noch kleiner sein, da ich auf dem mitlaufenden Oszilloskop kleine Veränderungen der Pulsweite auf "Pulse out" gemessen habe, die analog in das Meßergebnis eingingen.
Größenordnungen:
16Pulse mit 41kHz. Simulator schickt sofort Meßbeginn zurück. Meßende nach 3ms. Mit Oszi gemessener Meßpuls vom Simulator zwischen 2968µs und 2974µs, Meßanzeige zwischen 2592µs und 2608.
Das Ganze ist auf Steckbrett aufgebaut und die beiden Signalverbindungen zwischen den µCs über 1k Widerstände gemacht.
Weiter Daumen drückend für die HW und Dank auch Dir und allen Beteiligten für den thread.
Gruß
Searcher
Code:
'###################################################
'File: US-Meßprogramm.bas
'IDE: BASCOM-AVR DEMO Version 2.0.5.0
'Meßprogramm zum Messen von US-Laufzeit mit RN Wiki US-Interface
'Messung wird erst gestartet, wenn der Burst komplett gesendet wurde
'Messung wird gestoppt mit Eintreffen des 0 nach 1 Wechsel auf PB2
'
'ATtiny45
'Mit Taster an PB4 den Burst und Messen starten
'Eingang an PB2 (INT0) - Meßpulsempfang vom Interface
'Ausgang an PB1 - 16 Pulse mit 40kHz zum Interface
'Ausgabe der Meßwerte über PB3 mit SW UART an 4 fach 7-Segmentanzeige
'#######################################################
$regfile = "attiny45.dat"
$framesize = 32
$swstack = 40
$hwstack = 40
$crystal = 8000000 'interner Oszillator
'##### Definitionen für 7segment ausgabe ######
Dim Num_to_disp As Word
Dim Y As Byte
Dim Helperbyte As Byte
Dim Index As Byte
Dim Disp_string As String * 6
Dim Digit_char As String * 1
Declare Sub Display_value(num_to_disp As Word)
Open "comb.3:115200,8,n,1" For Output As #1 'comb.3 -> TX ist Pin PB3
'#### ende Definitionen für 7segmentausgabe #######
Dim Pulsecount As Byte
Dim Timer0_overflows As Word 'kann 65535 overflows zählen
Dim Endtime As Word 'geht bis 65535 µs = 65,535 ms, meine Anzeige bis &D9999
Dim Timerstand As Word
Dim Flag_messung_ende As Byte
Dim Flag_ausgabe_fertig As Byte
Portb = &B11110101 'alle Pullups auf portb einschalten, Ausnahme PB1, PB3
Config Portb.1 = Output
Config Int0 = Rising
On Int0 Isr_stop_messung
Enable Int0
Config Timer0 = Timer , Prescale = 8 'Timer wird hier mit 1Mhz gestartet (8Mhz Systemclk)
On Timer0 Isr_count_overflows
Stop Timer0 'Timer stoppen
Enable Timer0 'overflow interrupts Timer0 erlauben
Portb.1 = 1 'Ausgangsruhezustand auf Burst out Pin
Endtime = 0
Call Display_value(endtime) '7 Segment initialisieren
Call Display_value(endtime) '7 Segment initialisieren
Enable Interrupts
Do 'Beginn Hauptprogramm
Do 'Warten auf Tastendruck (PB4 nach GND)
Debounce Pinb.4 , 0 , Start_mit_burst
Loop
Start_mit_burst:
For Pulsecount = 1 To 16 '16 Pulse erzeugen (Burst mit ca 41kHz)
Reset Portb.1
Waitus 11
Set Portb.1
Waitus 11
Next Pulsecount
Flag_messung_ende = 0
Flag_ausgabe_fertig = 0
Timer0_overflows = 0
Timer0 = 0 'Timerzähler (TCNT0) mit 0 initialisieren
Start Timer0 'Meßzeit beginnt
Do 'Schleife zum Warten auf Meßende
If Flag_messung_ende = 1 Then 'Wenn Messung zu Ende, dann zur Anzeige
Endtime = Timer0_overflows * 256 'Meßzeit in µs ausrechnen
Endtime = Endtime + Timerstand 'Meßzeit in µs ausrechnen
Disable Interrupts 'ohne disable irgendwelche Probleme bei meiner Spezialausgabe
Call Display_value(endtime) 'Meßzeitausgabe über 7 Segmentanzeige
Enable Interrupts
Endtime = 0
Flag_ausgabe_fertig = 1
End If
Loop Until Flag_ausgabe_fertig = 1 'Ende Warterei wenn Anzeige des Meßwertes erfolgt ist
Loop 'Loop Hauptprogramm
Isr_count_overflows: 'Ansprung, wenn Timer0 überläuft
Incr Timer0_overflows
Return
Isr_stop_messung: 'Ansprung bei Eintreffen rising edge an Pb2 über INT0
Stop Timer0 'Meßzeit Ende, Timer anhalten, neuen OVF0 verhindern
Timerstand = Timer0 'Timerstand sichern
If Tifr.tov0 = 1 Then 'Falls bis "Stop Timer0" noch ein OVF0 aufgetreten ->
Timerstand = Timerstand + 256 'hier berücksichtigen
Set Tifr.tov0 'Timeroverflowflag löschen
End If
Flag_messung_ende = 1 'Indikation für Ausführen der Anzeige Meßwert in Hauptprogramm
Return
'############ Folgende Zeilen bis zum Ende nur zur Datenausgabe über 7 Segmentanzeige #############
Sub Display_value(num_to_disp As Word) 'gibt Dezimalzahlen bis 9999 aus
Disp_string = Str(num_to_disp)
For Y = Len(disp_string) To 3
Helperbyte = Lookup(16 , Segmentpattern)
Put #1 , Helperbyte
Next
For Y = 1 To Len(disp_string)
Digit_char = Mid(disp_string , Y , 1 )
Index = Val(digit_char)
Helperbyte = Lookup(index , Segmentpattern)
Put #1 , Helperbyte
Next
End Sub
Segmentpattern: 'darzustellende Zeichen (hex 0..F...)
'Segmente abcdefg: ' ":" = Doppelpunkt in der Mitte
Data &B00000011 'Ziffer "0", 0 = segment ein, 1 = aus
Data &B10011111 'Ziffer "1"
Data &B00100101 'Ziffer "2"
Data &B00001101
Data &B10011001
Data &B01001001
Data &B01000001
Data &B00011111
Data &B00000001
Data &B00001001
Data &B00010001
Data &B11000001
Data &B01100011
Data &B10000101
Data &B01100001 'Ziffer "E"
Data &B01110001 'Ziffer "F"
Data &B11111111 'dunkel
Data &B11111101 'nur Segment g eingeschaltet (-)
'########### ENDE US-Meßprogramm.bas ##############################################
'###################################################
'File: US-Simulator.bas
'IDE: BASCOM-AVR DEMO Version 2.0.5.0
'Ulraschall Interface Simulator nach RN Wiki US-Interface
'
'ATtiny25
'Eingang an PB2 (INT0) - Start in
'Ausgang an PB3 - Pulse out
'#######################################################
$regfile = "attiny25.dat"
$framesize = 32
$swstack = 40
$hwstack = 40
$crystal = 8000000 'interner Oszillator
Portb = &B11110111 'alle Pullups auf portb einschalten, Ausnahme PB3
Config Portb.3 = Output
Config Int0 = Falling 'INT0 bei Wechsel von 1 auf 0 an port PB2 "Start in"
On Int0 Isr_simulate_us_messung
Portb.3 = 1 'Wiki US Interface "Pulse out" Ruhezustand
Enable Int0
Enable Interrupts
Do
'Hauptschleife: INT0 macht schon die ganze Arbeit
Loop
Isr_simulate_us_messung: 'Ansprung Bei Eintreffen Von Pulsen An Pb2
Portb.3 = 0 'Pulse out auf 0 zeigt Meßbeginn
Waitms 3 'simulieren von 3ms Gesmatlaufzeit des Schalls
Portb.3 = 1 '"Echo" eingetroffen
Set Gifr.intf0 'durch empfangenen Burst neues anstehendes INTF0 Flag löschen
Return
'########## ENDE US-Simulator.bas #######################
Lesezeichen