INFO - FAQ - CC2-Forum - CCPro-Forum |
|
' =========================================================================== ' Demoprogramm: "TPM1 Channel 1"-Interrupt (TPM1CH1) nutzen - Single Shot ' In OCBASIC 1.12a_e1 für Open-Maxi von Dietmar Harlos am 27. September 2024 ' =========================================================================== ' In diesem Beispielprogramm wird demonstriert, wie eine Assemblerinterrupt- ' routine in den "TPM1 Channel 1"-Interrupt eingebunden werden kann. Die ' WORD-Variable "intervall1" gibt vor, nach welcher Zeit die Interruptroutine ' gestartet werden soll. Im Gegensatz zum vorherigen Programm wird der ' Interrupt nur einmal ausgelöst ("Single Shot"). Der Timer TPM1 läuft ' standardmäßig mit einer Frequenz von BUSCLK/32 = 625 kHz. Deshalb wird der ' Interrupt nach der Zeit "intervall1/(20e6/32)" gestartet. Die Timer-Register ' haben eine Breite von 16 Bit. Deshalb ist im hier vorliegenden Fall die ' maximale Zeitverzögerung, nach der der Interrupt auftreten kann, auf ' "65536/(20e6/32)" gleich 0.1048576 Sekunden begrenzt. ' --- Definitionen ---------------------------------------------------------- INCLUDE "omax.def" 'Definitionen für die Open-Maxi DIM zaehler1 WORD 'Zähler DIM intervall1 WORD 'Aufruf-Zeitintervall festlegen ' --- Unsere eigene Assembler-Interruptroutine ------------------------------ ' Die folgende Assembler-Interruptroutine befindet sich im "TPM1 Channel 1"- ' Interrupt und wird gestartet, wenn ein Intervall vorüber ist. ' Sobald der Interrupt auftritt, wird die Assemblerroutine aufgerufen, wobei ' im Akkumulator der Wert #iTIM1 und im X-Register die Adresse von FREERAM ' übergeben wird. Beendet werden muß die Routine mit RTS. Falls mit ' gelöschtem Carry-Bit ("CLC") beendet wird, führt das Betriebssystem ' die Systemfunktionen zum Interrupt weiter aus. Wird dagegen mit gesetztem ' Carry-Bit ("SEC", bzw. "STC") beendet, ignoriert das System den Interrupt. ' Die folgende Subroutine muß am Anfang des Programms, vor dem ersten Befehl ' stehen und sollte zusammen mit den anderen Subroutinen bis inklusive ' UIRTim1_iiar_next 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 UIRTim1_iiar INLASM ! cbeqa #iTIM1,tim1_is 'Unterscheidung der Interruptquellen ! jmp UIRTim1_iiar_next+2 'zur nächsten IIAR in der Kette springen #tim1_is ! ldhx zaehler1 'Debugging-Zähler inkrementieren ! aix #1 ! sthx zaehler1 ! mov #%00000000,TPM1C1SC 'Deaktivieren ! clc 'Carry-Flag löschen (Betriebssystem verarbeitet den Interrupt) ! rts 'Rücksprung zum Betriebssystem END PROCEDURE ' Den TPM1C1-Interrupt aktivieren und den nächsten Aufrufzeitpunkt festlegen ' Der TPM1C1 ist standardmäßig deaktiviert. Hier wird er als "Output Compare - ' Software compare only" aktiviert. PROCEDURE nextTPM1C1 INLASM ! mov #%00010000,TPM1C1SC 'Output Compare ("Software compare only") ! bclr bCH1F,TPM1C1SC 'Channel 1 Flag Bit (CH1F) im TPM1C1SC löschen ! lda TPM1CNTL 'nächsten Aufrufzeitpunkt festlegen ! add intervall1+1 ! sta TPM1C1VL ! lda TPM1CNTH ! adc intervall1 ! sta TPM1C1VH ! bset bCH1IE,TPM1C1SC 'Channel 1 Interrupt Enable (CH1IE) ! rts END PROCEDURE #UIRTim1_iiar_next 'hier hinter folgt die nächste IIAR '(sofern vorhanden) ' --- Hauptprogramm --------------------------------------------------------- #main 'durch die IIAR am Programmbeginn wird ein "GOTO main" erzeugt PrintSpc=ON 'Bei PRINT dezimale Zahlen mit führendem Leerzeichen ausgeben End2Host=ON 'Bei Programmende (siehe END) gleich in den Host-Modus wechseln ' Titel: PRINT "TPM1CH1-Interrupt (Single Shot)" PRINT "===============================" IF NOT IiarFnd THEN ?"INLINE-Interrupt-Assemblerroutine nicht gefunden!" : END ' Initialisierungen: UIRTim1=ON 'User-Assemblerroutine für TIM1 (TPM1CH1) aktivieren intervall1=50000 '50000/(20e6/32)= 0.08 Sekunden (gleich 4 Timer-Ticks) nextTPM1C1 'Interrupt aktivieren ' Hauptschleife des Programms: WHILE TRUE IF zaehler1 THEN ?timer;zaehler1 zaehler1=0 'Zähler resetten PAUSE 10 '10 Timer-Ticks warten vor Reaktivierung (Demo) intervall1=50000 '50000/(20e6/32)= 0.08 Sekunden (gleich 4 Timer-Ticks) nextTPM1C1 'Interrupt reaktivieren END IF WEND ?:?"Programmende." END 'Zurück in den Hostmodus. Neustart mit RETURN-Taste. ' --- Programmende --------------------------------------------------------- Passender Link: Infosite zu den OM-Mikrocontrollern Meine Homepage: http://ccintern.dharlos.de |
Antwort schreiben |