![]() ![]() INFO - FAQ - CC2-Forum - CCPro-Forum |
|
' ---------------------------------------------------------------------------- ' Assemblerkurs für die OM-Mikrocontroller - Teil 2 ' In OCBASIC 1.11a für die Open-Macro von Dietmar Harlos am 9. Februar 2018 ' ---------------------------------------------------------------------------- ' Dieser Teil des Assemblerkurs demonstriert, wie eine Assemblerroutine in ' einen Interrupt eingebunden werden kann. ' Beim Erstellen des Betriebssystems habe ich folgende Erklärung verfaßt: ' Da das Handling von User-Interruptroutinen in der Original-C-Control nicht ' optimal war und auf der OM dadurch viel RAM verloren ginge, versuche ich ' jetzt einen etwas anderen Weg zu gehen. Jede User-Interruptroutine liegt ' an Adresse $fd00 oder wird als Inline-Assemblerroutine in das System einge- ' bunden. Falls mehrere User-Interrupts aktiviert wurden, kann durch Abfragen ' des Akkus festgestellt werden, welche Quelle den Interrupt ausgelöst hat. ' Der Anwender braucht das H-Register nicht zu retten, es ist null. Dafür ' wird ein Byte auf dem Hardware-Stack belegt. User-Interruptroutinen werden ' vom Betriebssystem wie gehabt über JSR, nicht über JMP aufgerufen und ' müssen daher mit RTS (nicht mit RTI) beendet werden. Das belegt weitere ' zwei Bytes auf dem Hardware-Stack. Durch Setzen des Carry-Flags (SEC) kann ' der User signalisieren, daß die Systemroutinen des Interrupts nachfolgend ' nicht aufgerufen werden, sondern der Interrupt unmittelbar mit POPH und RTI ' beendet wird. Andernfalls ist das Flag mit dem Befehl CLC zu löschen. ' ---------------------------------------------------------------------------- INCLUDE "omac.def" 'Definitionen fuer die Open-Macro DIM zaehler BYTE 'Demo: Interrupts zählen ' --- Unsere eigene Assembler-Interruptroutine ------------------------------- ' Die folgende Assembler-Interruptroutine befindet sich im Timer-Overflow- ' Interrupt und wird auf den kleinen OM-Controllern alle 20 ms aufgerufen. ' Auf der Open-Maxi ist der TOFL-Interrupt standardmäßig deaktiviert und ' müßte erst durch "bset bTOIE,TPM1SC" aktiviert werden. Das muß aber hinter ' dem "UIRTofl=ON" geschehen, damit der Interrupt nicht auftritt, bevor die ' Interruptroutine aktiviert ist. Sonst könnte der Controller stehenbleiben. ' Die folgende Subroutine sollte 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. PROCEDURE iiar_TOFL INLASM ! cbeqa #iTOFL,isiTOFL 'Falls kein Aufruf durch TOFL-Interrupt, ! jmp iiar_TOFL_ende+2 ' dann zur nächsten IIAR in der Kette. #isiTOFL ! inc zaehler 'Demo: Zähler um eins erhöhen ' Durch Setzen des Carry-Flags (SEC) kann der User signalisieren, daß die ' Betriebssystemroutinen des Interrupts nachfolgend nicht aufgerufen werden, ' sondern der Interrupt unmittelbar beendet wird. Andernfalls ist das Flag ' mit dem Befehl CLC zu löschen. ! clc 'Betriebssystemfunktion soll aktiviert bleiben ! rts 'Rücksprung zum Betriebssystem END PROC #iiar_TOFL_ende 'hier hinter folgt die nächste IIAR '(sofern vorhanden) ' --- Das Hauptprogramm ------------------------------------------------------ #main UIRTofl=ON 'Userroutine für Timer-Overflow-Interrupt aktivieren '(UIRTofl wurde in OMAC.DEF definiert, siehe dort) WHILE TRUE 'Endlosschleife PAUSE 1 PRINT zaehler 'Variable auf der Seriellen Schnittstelle ausgeben WEND End2Host=ON 'Nach Programmende in den Host-Modus END 'Programmende ' --------------------------------------------------------------------------- Passender Link: Assemblerkurs für die OM-Mikrocontroller (Teil 2) als ZIP-Archiv Meine Homepage: http://ccintern.dharlos.de |
Antwort schreiben |