ARM-Baugruppe - Basic-Interrupt-Handling
Ich bin derzeit Herumspielen mit einigen ARM-Assembler auf dem lpc2378, ich habe geschrieben eine Schleife zu Steuern, ein Ofen die Temperatur hat, aber ich glaube, ich brauche, um zu implementieren eine Art von interrupt-handling, um meine komplette Projekt.
Wenn die Anwendung ausgeführt wird, tritt es in eine Schleife, die wartet, bis Button_1 Eingang, die Schleife führt dann auf und geht durch verschiedene Phasen, aber es nicht erreichen können, warten Sie, bis Button_2 input für die Funktion der Anwendung.
So ein paar Fragen hier, wie genau funktioniert der interrupt-handler arbeiten? und wie könnte ich es umsetzen in meine Anwendung.
Hier ist mein Button_1 code:
;=========================================================================
; Wait for BUT1 to be pressed
;=========================================================================
WaitBUT1
STMFD r13!,{r0,r5,r14} ; Push r0, r5 and LR
WaitForBUT1Pressed
ldr r0, = IO0PIN ; Address of FIO0PIN register
ldr r1, [r0] ; Read FIO0PIN in to r1
ands r1, r1, # B1_MASK ; Mask out BUT1
beq BUT1Pressed ; Exit LED toggle loop if button is pressed
B WaitForBUT1Pressed
BUT1Pressed
LDMFD r13!,{r0,r5,r14} ; Pop r0, r5 and LR
mov pc, r14 ; Put link register back into PC
und meine Button_2 code:
;=========================================================================
; Wait for BUT2 to be pressed
;=========================================================================
WaitBUT2
STMFD r13!,{r0,r5,r14} ; Push r0, r5 and LR
WaitForBUT2Pressed
ldr r0, = IO0PIN ; Address of FIO0PIN register
ldr r1, [r0] ; Read FIO0PIN in to r1
ands r1, r1, # B2_MASK ; Mask out BUT1
beq BUT2Pressed ; Exit LED toggle loop if button is pressed
B WaitForBUT2Pressed
BUT2Pressed
LDMFD r13!,{r0,r5,r14} ; Pop r0, r5 and LR
mov pc, r14 ; Put link register back into PC
und auch mein Ofen Regelkreis:
LoopStart
BL WaitBUT1 ; wait until button 1 is pressed
BL heaterOn ; turn heater on
BL systemLedOn ; turn system LED on
BL readTemp ; Check ADC for temp
BL checkTemp ; Count down, check ADC for temp
CMP r3, #5 ; Compare timer with delay
BGT errorVal
SUBS r4, r2, r7 ;Performs r7 = r4 - r2 and sets condition register
BEQ LoopStart ; if equal nothing to do
BGT overTemp ; r7 < 0 case
BL errorLedOn
BL heaterOn
BL FanOff
B LoopStart
overTemp
BL errorLedOn
BL heaterOff
BL FanOn
B LoopStart
BL WaitBUT2
BL FanOff
BL errorLedOff
BL systemLedOff
BL heaterOff
B LoopStart
Vielen Dank im Voraus.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie nicht bereits haben, die Sie brauchen, um den ARM zu ARM (ARM-Architektur-Referenzhandbuch). früher gab es nur einen, aber es gibt so viele Kerne, jetzt hatten Sie, um es zu teilen für die unterschiedlichen Architekturen. http://infocenter.arm.com auf der linken Seite ARM-Architektur, dann die Referenz-Handbücher, dann ARMv5, ja, ich weiß, Sie haben einen ARMv4 (ARM7TDMI). Die ARMv5-Handbuch ist, was verwendet werden, ist DAS Handbuch.
Er behandelt die exception-Vektoren und so.
Wahrscheinlich wissen Sie bereits, dass beim Booten, wird die Instruktion an Adresse 0x00000000 ausgeführt wird.
Für interrupts, die die Instruktion an der Adresse 0x00000018 genannt wird.
Vom ARM ARM Sie sollten auch sehen, dass die Register sind überhöht, insbesondere r13 der stack-pointer, es gibt einen separaten stack-Zeiger, wenn in den interrupt-Modus. Also nach dem Booten, wenn Sie beim einrichten Ihres normalen stapeln, die Sie auch einrichten möchten etwas Raum für die interrupt-stack.
irgendwann müssen Sie zum aktivieren des Interrupts in das cpsr. Sie könnte warten, bis Sie aktiviert haben, was auch immer unterbrechen, was auch immer-Peripherie (in der chip, die außerhalb des Kerns).
Lesen Sie das Handbuch für die lpc-Teil zu verstehen, wie aktiviert man den interrupt, als auch, wie zu deaktivieren Sie die Unterbrechung, wenn es passiert.
Das erste, was Sie tun müssen, um in den interrupt-handler (den code, den Sie verzweigen zur Adresse 0x18) ist die Erhaltung der gemeinsamen (nicht überhöht) Register auf dem stack, so dass Sie nicht Durcheinander, Sie oben. Wenn Sie nicht zurückkehren, wenn Sie auf den code, der unterbrochen wurde, die Register gewechselt ist, und dieser code kann nicht funktionieren. Da Ihr Projekt zu sein scheint, in ASM ist es möglich, dass Sie einige Register in der Anwendung und reservieren regsiters nur für die isr und nicht haben, um den setup-stack. Wenn Sie verwenden, bl überall in den handler, den Sie brauchen, um zu retten lr auf den stack.
Irgendwann Ihr handler muss klar den interrupt in den peripheren, so dass es nicht wieder Feuer, bis der nächste interrupt, ich muss Lesen Sie die lpc-Handbuch. Ja, wenn ich sage, lpc-ich meine, NXP, ehemals Philips...
Das Letzte, was ist, wenn Sie haben geschoben, lr, pop, und pop anderen Registern, wenn Sie hatte, schob Sie, dann verwenden Sie diese genaue Anweisung und den arm zurück und wechseln den Modus wieder auf den Modus, die unterbrochen wurde (der Wechsel zu der Verwendung dieser banked Register).
Hinweis: Sie müssen möglicherweise auch, und es ist generell eine gute Idee, mit der ARM, um die TRM (Technical Reference Manual) für den spezifischen Kern, in Ihrem Fall die ARM7TDMI-S. Auf der infocenter-Seite, linke Seite, gehen Sie auf ARM7-Prozessoren, die nicht ARMv7 unter die Architektur, sondern die unteren, wo es ARM11, ARM9, ARM7.
Tasten kann unordentlich mit interrupts, wie Sie hüpfen und zu viele Kanten auf der I/O-pin. Blick auf Ihren anderen Beitrag ich sehe nicht, wo würden Sie brauchen einen interrupt. Sollte man im Allgemeinen vermeiden, unterbricht, sofern nicht anders erforderlich. Sie sind chaotisch im Allgemeinen. Es sind Entwürfe, die Sie kann nicht vermeiden, mit einem, sicherlich. Und gibt es event-driven-designs, wo alle Ihre code ist ein interrupt-handler, und es gibt nichts in der Anwendung, sondern auch startup-code und unendlich-Schleife (oder eine andere Art von Schlaf).
Können Sie interrupts debounce, zum Beispiel, wenn Sie setup ein timer-interrupt und probieren Sie die I/O-pins für die Taster im interrupt, vermeiden Sie eine ganze Menge von dem springenden, aber auch das Risiko, die chance fehlt eine Taste drücken. Nur weil der Knopf I/O-pin geltend gemacht beiden interrupts in eine Zeile, nicht zwei Pressen, ändern Sie eine state-variable irgendwo, und wenn die Taste losgelassen wird, ändern Sie den Zustand der variable. Kante Veränderungen auf, die state-variable von Interesse für die Anwendung. wenn der Knopf geht aus ungepressten betätigt werden, etwas zu tun, wenn es geht aus-Taste gedrückt, um ungepressten, dont nichts tun, warten, bis es zu ändern, aus ungepressten, um gedrückt als Beispiel.
Können Sie auch mit dem gleichen timer-interrupt zu starten, oder die Probe des adc.
Da Sie nicht gelöst haben zu deinen anderen problem, das auch hier erwähnt, würde ich nicht gehen in der Nähe von interrupts. Abbildung dieses problem zuerst, dann entscheiden, ob es eine Funktion gibt, die Sie benötigen, erfordert einen interrupt. Wie auch/regelmäßige Abtastung des adc.
dass sollte mehr als genug sein, zum du zu erhalten begannen. Wenn Sie versuchen, unterbricht versuchen Sie NICHT, Sie als Teil dieser Anwendung, erstellen Sie eine komplett separate Anwendung, beispielsweise ein led-blinker. ändern Sie den Status der led im interrupt-handler, und/oder ändern Sie eine Globale variable oder ein register, in dem die handler und die forground Uhr für, die, und ändern Sie die led als ein Ergebnis. Immer teilen Ihre Probleme/lernaufgaben in einzelne Stücke, lösen diese dann kleben Sie zusammen, fügen Sie eine Stück, testen, fügen Sie ein Stück, testen.
In diesem Fall einen interrupt-handler scheint überflüssig, man könnte einfach Umfrage Taste 2 in der main-Schleife anstatt mit der "warten" - Funktion. Fügen Sie diese am Ende der Schleife:
wo STOP ist ein Ziel, führt eine sichere Ofen heruntergefahren (also nicht verlassen, es läuft auf unbestimmte Zeit).
Beachten Sie, dass Ihre Schleife beinhaltet eine Wartezeit für button1 - sicherlich sollte vor
LoopStart
? Ansonsten ist der Regelkreis warten auf eine Schaltfläche drücken, die bei jeder iteration ohne Ausführung jeglicher Steuerung von Aktionen - vielleicht in einer gefährlichen situation, wenn Sie die Letzte Aktion war einheaterOn
!Darüber hinaus beachten Sie, dass vor der ARM-Cortex-Kerne (LPX2378 ist ein ARM7TDMI-S core), ARM-core definiert nur zwei interrupt-Quellen IRQ und FIQ, die meisten Teile haben eine separate interrupt-controller-extern ARM-Kern selbst, und dieses interrupt-controller ist herstellerspezifisch. Daher, um zu bestimmen, wie die GPIO-interrupts zum Beispiel behandelt werden, auf Ihrem Teil, Sie müssen finden Sie auf dem Gerät im reference manual eher als ARM-Dokumentation.
ARM-Cortex-M-basierte Geräte sind schnell ersetzt ARM7-Geräte, und Sie könnten besser mit so einem Gerät. Insbesondere die Behandlung von Interrupts ist weit mehr einfach, flexibel und effizient. Sehen dieser Artikel wie Cortex-M, verbessert auf ARM7.