![]() ![]() INFO - FAQ - CC2-Forum - CCPro-Forum |
|
' ---------------------------------------------------------------------------- ' Entfernungen per Ultraschall-Modul HC-SR04 auf der Open-Maxi ermitteln. ' In OCBASIC 1.12a von Norbert Klein und Dietmar Harlos am 20. Januar 2020 ' ---------------------------------------------------------------------------- ' Das Ultraschall-Modul kann über Amazon bezogen werden und kostet im Dreier- ' pack zur Zeit nur 6,29 EUR bei kostenlosem Versand: ' https://www.amazon.de/dp/B072N473HD ' In diesem Programm wird die ON-Zeit eines an DA[2] (genauer: TPM2CH1) einer ' Open-Maxi angeschlossenen Rechtecksignals gemessen. Das ist nützlich, um ' mittels Ultraschall-Modul HC-SR04 Entfernungen zu messen. ' Der 'Echo'-Ausgang des Moduls muß mit DA[2] verbunden werden. ' ---------------------------------------------------------------------------- ' Berechnung der Entfernung in Zentimetern bei 2.5 MHz Timertakt: ' OnZeit * 1/2500*34.3/2 = OnZeit * 0.00686 = OnZeit / 145.7725948 ' Mit Nachkommastelle geht nur bis ca. 22 cm Entfernung. ' Es kann bis 450 cm gemessen werden. Das Modul kann bis ca. 3 Meter. ' ---------------------------------------------------------------------------- ' Berechnung der Entfernung in Zentimetern bei 5 MHz Timertakt: ' OnZeit * 1/5000*34.3/2 = OnZeit * 0.00343 = OnZeit / 291.5451895 ' Mit Nachkommastelle geht nur bis ca. 11 cm Entfernung. ' Es kann bis 225 cm gemessen werden. Das Modul kann bis ca. 3 Meter. ' ---------------------------------------------------------------------------- INCLUDE "omax.def" 'Definitionen für die Open-Maxi DIM OnZeit WORD 'Ergebnis der Messung des HIGH-Impulses an DA[2] DIM letzte_flanke WORD 'die letzte steigende Flanke merken DIM entfernung WORD 'Entfernung in cm DEFINE Trigger PORT[1] 'mit 'Trig'-Eingang vom Modul verbinden ' --- Unsere eigene Assembler-Interruptroutine ------------------------------- ' Die folgende Assembler-Interruptroutine befindet sich im Timer/PWM-2- ' Channel-1-Interrupt und wird gestartet, wenn eine Flanke an DA[2] ' detektiert wird. ' Die folgenden Subroutinen sollten sinnvollerweise in einer INCLUDE-Datei ' untergebracht werden. ' Das Schlüsselwort INLASM kennzeichnet die folgende PROCEDURE als ' Assemblerroutine (IAR). Dadurch, und daß sie unmittelbar am Anfang ' des Programms steht, wird sie zu einer IIAR, also zu einer Assembler- ' Interruptroutine, die bei einem aktivierten User-Interrupt gestartet wird. ' Der OCBASIC-Compiler setzt automatisch ein "GOTO main" vor diese Routine. PROCEDURE iiar_tpm2c1 INLASM ! cbeqa #iTPM2C1,iiar_tpm2c1_is 'Falls kein Aufruf durch TPM2C1-Interrupt, ! jmp iiar_tpm2c1_ende+2 'dann zur nächsten IIAR in der Kette. #iiar_tpm2c1_is ! ldhx TPM2C1VH ! brset bELS1A,TPM2C1SC,iiar_tpm2c1_rising 'steigende oder fallende Flanke? ! txa 'OnZeit = TPM2C1V - letzte_flanke ! sub letzte_flanke+1 ! sta OnZeit+1 ! pushh ! popa ! sbc letzte_flanke ! sta OnZeit ! mov #&b01000100,TPM2C1SC 'Input capture, Capture on rising edge only ! clc ! rts 'Rücksprung ins Betriebssystem #iiar_tpm2c1_rising ! sthx letzte_flanke 'Position der letzten steigenden Flanke festhalten ! mov #&b01001000,TPM2C1SC 'Input capture, Capture on falling edge only ! clc ! rts 'Rücksprung ins Betriebssystem END PROCEDURE ' Mit der folgenden Assemblerroutine wird das TPM2-Modul vom Controller ' passend umkonfiguriert. PROC init_tpm2 INLASM ! mov #%00000000,TPM2SC 'TPM stop ! 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 -> Divisor=291 ! mov #%01001011,TPM2SC 'TPM clock input = BUSCLK/8 = 2500kHz, 400ns -> Divisor=146 ! rts END PROC ' Das TPM2-Modul wieder so setzen, wie vom OS erwartet. PROCEDURE reset_tpm2 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 ! rts END PROC #iiar_tpm2c1_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, DA[2] aktivieren init_tpm2 'Timer-Modul passend initialisieren WHILE TRUE OnZeit=0 'ON-Zeit auf 0 setzen Trigger=ON 'Trigger zum Modul senden PAUSE 5 Trigger=OFF PAUSE 5 PRINT OnZeit 'ON-Zeit an DA[2] IF OnZeit<0 THEN 'bei einem Überlauf entfernung=450+OnZeit/146 'es kann bis 450 cm gemessen werden PRINT entfernung;" cm" '65536/145.7725948 = 449.5769599 ELSE IF OnZeit<=3276 THEN entfernung=OnZeit*10/146 'mit Nachkommastelle geht nur bis ca. 22 cm Entfernung PRINT entfernung/10;",";entfernung MOD 10;" cm" ELSE entfernung=OnZeit/146 'ansonsten ohne Nachkomma PRINT entfernung;" cm" END IF PAUSE 25 WEND reset_tpm2 'Timer-Modul wieder auf Defaultkonfiguration UIRTpm2C1=OFF 'User-Assemblerroutine deaktivieren End2Host=ON 'nach dem Programmende in den Host-Modus END 'Programmende ' --- Programmende ---------------------------------------------------------- Passender Link: Ultraschall-Modul HC-SR04 bei Amazon Meine Homepage: http://ccintern.dharlos.de |
Antwort schreiben |