![]() ![]() INFO - FAQ - CC2-Forum - CCPro-Forum |
|
Hallo! Bei Amazon stieß ich auf preiswerte Ultraschallmodule HC-SR04. Das Stück für rund 3 Euro. Sie können Entfernungen von 2 bis etwa 300 cm mit einer Auslösung von 3 mm bestimmen. Die Handhabung ist einfach. Zum Auslösen eines Messintervalls muss man einen Triggerimpuls senden. Mit dem darauf folgenden Puls des Moduls im ms-Bereich kann man die Entfernung bestimmen. Als Grundlage diente mir das Programm "Tastverhältnis eines Rechtecksignals an PORT[2] ermitteln" von Dietmar Harlos, das ich auch für die Maxi an TPM2 modifizierte. Bei der Maxi fällt ein Jitter im Messergebnis auf, diese Schwankungen verfälschen den Wert um bis zu neun Prozent. Die Ursache könnte mit den Interrupts des OS an TPM1 zusammenhängen. Vielleicht kann jemand das genauer ergründen. Bei der Berechnung muss man berücksichtigen, dass die verarbeiteten Werte gerundet sind. Diese Abweichungen kann man im Nahbereich, wie erläutert wird, minimieren. Nachfolgend das Programm. Freundliche Grüße Norbert ' ---------------------------------------------------------------------------- ' Tastverhältnis eines Rechtecksignals an PORT[2] ermitteln. ' In OCBASIC 1.09a für Open-Macro von Dietmar Harlos am 22. September 2015. ' modifiziert für die Berechnung von Ultraschall-Laufzeiten ' Messergebnis * 1/3200*34,3/2 = Messergebnis * 0.00343 = Messergebnis / 186.5889212827988 ' nach Dietmar Harlos ' für das Beispiel mit der Maxi gilt: ' Messergebnis * 1/5000*34,3/2 = Messergebnis * 0.00343 = Messergebnis / 291.5451895 ' ---------------------------------------------------------------------------- ' Dieses Programm mißt die ON-Zeit eines an PORT[2] (genauer: TCH1) einer ' Open-Macro angeschlossenen Rechtecksignals in 312.5-ns-Einheiten. Es können ' Frequenzen größer 48.8 Hz und kleiner ca. 25 kHz erfaßt werden. Der interne ' Pull-Up-Widerstand an PORT[2] wird während der Messung (leider) deaktiviert. ' Bei Bedarf muß also ein externer verwendet werden. ' Die gemessende ON-Zeit ist: tastver_ergebnis * 312.5E-9 s. ' Tastverhältnis: Frequenz_des_Rechtecksignals * tastver_ergebnis / 3.2E6 ' In diesem Demoprogramm können Störungen auftreten, weil die Ausgabe eines ' Zeichens über die an PORT[1] liegende Serielle Schnittstelle zu lange ' dauert. Der Controller 'verschläft' dann eine Flanke des Signals. Das ' gleiche kann bei hohen Frequenzen in Kombination mit niedrigem ' Tastverhältnis passieren ' ---------------------------------------------------------------------------- INCLUDE "omac.def" 'Definitionen für die Open-Macro DIM tastver_ergebnis WORD 'Ergebnis der Tastverhältnis-Messung DIM tastver_letzter WORD 'die letzte steigende Flanke merken define Zahl Word define Taste Port[3] 'stösst Messung an define Trigger Port[4] 'löst Messung aus PROCEDURE iiar_tim1 INLASM ! cbeqa #iTIM1,iiar_tim1_1 'Falls kein Aufruf durch TIM1-Interrupt, ! jmp iiar_tim1_ende+2 'dann zur nächsten IIAR in der Kette. #iiar_tim1_1 ! ldhx TCH1H ! brset bELS1A,TSC1,iiar_tim1_rising 'steigende oder fallende Flanke? ! txa 'tastver_ergebnis = TCH1 - tastver_letzter ! sub tastver_letzter+1 ! sta tastver_ergebnis+1 ! pushh ! popa ! sbc tastver_letzter ! sta tastver_ergebnis ! mov #&b01000100,TSC1 'Input capture, Capture on rising edge only ! clc ! rts 'Rücksprung ins Betriebssystem #iiar_tim1_rising ! sthx tastver_letzter ! mov #&b01001000,TSC1 'Input capture, Capture on falling edge only ! clc ! rts 'Rücksprung ins Betriebssystem END PROCEDURE PROCEDURE init_tim1 INLASM 'Before changing a channel function by writing to the MSxB or MSxA bit, 'set the TSTOP and TRST bits in the TIM status and control register (TSC). ! mov #&b00110000,TSC 'TSC: TOF TOIE TSTOP TRST 0 PS2 PS1 PS0 ! mov #&b01000100,TSC1 'Input capture, Capture on rising edge only ! ldhx #&hffff ! sthx TMODH 'Modulo-Register auf Standardwert $ffff 'After initially enabling a TIM channel register for input capture operation 'and selecting the edge sensitivity, clear CHxF to ignore any erroneous 'edge detection flags. ! bclr bCH1F,TSC1 ! mov #&b01000000,TSC 'Timer wieder starten ! rts END PROCEDURE ' Timer Interface Module (TIM) wieder so setzen, wie vom OS erwartet PROCEDURE reset_tim1 INLASM ! mov #&b00110000,TSC 'TSC: TOF TOIE TSTOP TRST 0 PS2 PS1 PS0 ! clr TSC1 'TIM Channel Status and Control Register ! ldhx #999 'Modulo-Register zurück auf OS-Wert ! sthx TMODH ! mov #&b01000110,TSC 'Timer wieder starten ! rts END PROCEDURE #iiar_tim1_ende 'hier hinter folgt die nächste IIAR '(sofern vorhanden) ' --- Das Hauptprogramm ----------------------------------------------------- #main 'Label für Hauptprogramm UIRTim1=ON 'User-Assemblerroutine für TIM1 aktivieren init_tim1 'Timer-Modul passend initialisieren 'PrintSpc=ON 'SPACE vor einem dezimalen PRINT WHILE true if Taste=off then Trigger=on Pause 15 Trigger=off PAUSE 5 Zahl=tastver_ergebnis*10/187 'geht bis 16 cm, Pulsbreite 900 us PRINT Zahl/10;",";Zahl MOD 10;" cm" 'Zahl=tastver_ergebnis/19 'ohne Nachkomma ab 16 cm 'Print Zahl/10; " cm" Trigger=on end if WEND reset_tim1 'Timer-Modul wieder auf Defaultkonfiguration End2Host=ON 'nach dem Programmende in den Host-Modus END 'Programmende ' ---------------------------------------------------------------------------- 'Die Routinen für die Maxi (IR an DA2) INCLUDE "omax.def" 'Definitionen für die Open-Maxi DIM OnZeit WORD 'Ergebnis der Tastverhältnis-Messung DIM tastver_letzter WORD 'die letzte steigende Flanke merken define Zahl Word define Taste Port[9] define Trigger Port[41] 'Beep PROCEDURE iiar_tim1 INLASM ! cbeqa #iTPM2C1,isiTPM2C1 ! jmp iiar_tim1_ende+2 'dann zur nächsten IIAR in der Kette. #isiTPM2C1 ! ldhx TPM2C1VH ! brset bELS1A,TPM2C1SC,iiar_tim21_rising 'steigende oder fallende Flanke? ! txa 'OnZeit = TCH1 - tastver_letzter ! sub tastver_letzter+1 ! sta OnZeit+1 ! pushh ! popa ! sbc tastver_letzter ! sta OnZeit ! mov #&b01000100,TPM2C1SC 'Input capture, Capture on rising edge only ! clc ! rts 'Rücksprung ins Betriebssystem #iiar_tim21_rising ! sthx tastver_letzter ! mov #&b01001000,TPM2C1SC 'Input capture, Capture on falling edge only ! clc ! rts 'Rücksprung ins Betriebssystem END PROCEDURE PROC inittpm2 INLASM ! BSET bCH1IE,TPM2C1SC 'IR freischalten '! mov #%00000000,TPM2SC 'TPM stop ist nicht notwendig ! clr TPM2MODH ! clr TPM2MODL ! lda #%01000100 'Input capture, Capture on rising edge only, IR frei ! sta TPM2C1SC 'Timer 2 Channel 1 Status and Control Register '! mov #%01001000,TPM2SC 'TPM clock input = BUSCLK/1 = 20000kHz, 50ns (geht bis Pulsbreite 5us) ! mov #%01001010,TPM2SC 'TPM clock input = BUSCLK/4 = 5000kHz, 200ns ! rts END PROC ' Timer Interface Module (TIM) wieder so setzen, wie vom OS erwartet PROCEDURE reset_tim21 INLASM ! mov #%00000000,TPM2SC 'TPM stop ! ldhx #$00ff 'Timer 2 Counter Modulo Registers (TPMxMODH:TPMxMODL) ! sthx TPM2MODH 'von 0 bis inklusive 255 zählen (also Modulo 256) - (kein 100% duty cycle) ! lda #%00101000 ! sta TPM2C1SC 'Timer 2 Channel 1 Status and Control Register / High-true pulses ! mov #%00001101,TPM2SC 'TPM clock input = 20E6/32 = 625 kHz -> PWM-Frequenz 2441 Hz ! clc ! rts 'Rücksprung ins Betriebssystem end proc #iiar_tim1_ende 'hier hinter folgt die nächste IIAR '(sofern vorhanden) ' --- Das Hauptprogramm ----------------------------------------------------- #main 'Label für Hauptprogramm UIRTPM2C1=ON 'User-Assemblerroutine für Timer 2, Kanal 1, DA2 aktivieren inittpm2 'Timer-Modul passend initialisieren WHILE true if Taste=off then Trigger=on Pause 5 Trigger=off PAUSE 5 Zahl=OnZeit*10/291 'geht nur bis 10 cm Entfernung, ansonsten siehe Beispiel Macro PRINT Zahl/10;",";Zahl MOD 10;" cm" end if WEND UIRTPM2C1=off reset_tim21 'Timer-Modul wieder auf Defaultkonfiguration End2Host=ON 'nach dem Programmende in den Host-Modus END 'Programmende ' ---------------------------------------------------------------------------- |
Antwort schreiben |