- Warum brauchen wir eine Unterbrechung?
- Arten von Interrupts in MSP430
- Unterbrechen Sie die Programmsteuerung in MSP430
- MSP430-Schaltung zum Testen des GPIO-Interrupts
- Programmieren von MSP430 für Interrupts
- Programm von CCS auf MSP430 hochladen
- Programm auf MSP430 unterbrechen
Stellen Sie sich eine einfache Digitaluhr vor, die so programmiert ist, dass sie nur die Zeit anzeigt. Stellen Sie sich nun vor, Sie möchten ihre Zeitzone ändern. Was würden Sie tun? Sie drücken einfach eine Taste, die zum Menü wechselt, mit dem Sie die Zeitzone ändern können. Hier kann das System Ihren externen Interrupt nicht für seine Zeiterfassungsprozesse vorhersagen und Sie nicht zum Warten auffordern, da es damit beschäftigt ist, den Sekundenwert auf Ihrer Uhr zu erhöhen. Hier kommen die Interrupts zum Einsatz.
Interrupts müssen nicht immer extern sein. es kann auch intern sein. In den meisten Fällen erleichtert ein eingebetteter Interrupt auch die Kommunikation zwischen zwei Peripheriegeräten der CPU. Angenommen, ein voreingestellter Timer wird zurückgesetzt und ein Interrupt wird ausgelöst, wenn die Zeit den Wert im Timer-Register erreicht. Der Interrupt-Handler kann verwendet werden, um die anderen Peripheriegeräte wie DMA zu initiieren.
In diesem Tutorial haben wir die externen Interrupts des MSP430 verwendet, um verschiedene LEDs umzuschalten. Wenn durch die Zustandsänderung per Knopfdruck ein externer Interrupt ausgelöst wird, wird die Steuerung an den ISR übertragen (vorbelegt) und erledigt das Notwendige. Um die Grundlagen wie das Einrichten der CCS-Umgebung für das MSP430G2-Launchpad zu kennen, folgen Sie diesem Link, um mit MSP430 unter Verwendung von CCS zu beginnen, da wir in diesem Lernprogramm nicht näher darauf eingehen werden. Überprüfen Sie auch andere MSP430-basierte Tutorials mit Energia IDE und CCS, indem Sie dem Link folgen.
Warum brauchen wir eine Unterbrechung?
Interrupts werden benötigt, um den Abrufaufwand in einem eingebetteten System zu sparen. Sie werden aufgerufen, wenn die Aufgaben mit höherer Priorität ausgeführt werden müssen, indem die aktuell ausgeführte Aufgabe vorweggenommen wird. Es kann auch verwendet werden, um die CPU aus dem Energiesparmodus zu aktivieren. Wenn es durch den Flankenübergang eines externen Signals über einen GPIO-Port geweckt wird, wird der ISR ausgeführt und die CPU kehrt wieder in den Energiesparmodus zurück.
Arten von Interrupts in MSP430
Die Interrupts in MSP430 fallen unter die folgenden Typen:
- Systemzurücksetzung
- Nicht maskierbarer Interrupt
- Maskierbarer Interrupt
- Vektorisierte und nicht vektorisierte Interrupts
Systemzurücksetzung:
Dies kann aufgrund der Versorgungsspannung (Vcc) und aufgrund eines niedrigen Signals im RST / NMI-Pin bei ausgewähltem Reset-Modus auftreten und auch aufgrund von Gründen wie Überlauf des Watchdog-Timers und Verletzung des Sicherheitsschlüssels.
Nicht maskierbarer Interrupt:
Diese Interrupts können nicht durch die CPU-Anweisungen maskiert werden. Sobald der allgemeine Interrupt aktiviert ist, kann der nicht maskierbare Interrupt nicht mehr von der Verarbeitung umgeleitet werden. Dies wird durch Quellen wie Oszillatorfehler und eine manuell dem RST / NMI zugewiesene Flanke (im NMI-Modus) erzeugt.
Maskierbarer Interrupt:
Wenn ein Interrupt auftritt und durch einen CPU-Befehl maskiert werden kann, handelt es sich um einen maskierbaren Interrupt. Sie müssen nicht immer extern sein. Sie hängen auch von Peripheriegeräten und ihren Funktionen ab. Die hier verwendeten externen Port-Interrupts fallen unter diese Kategorie.
Vektor-Interrupts und nicht-Vektor-Interrupts:
Vektorisiert: In diesem Fall liefern Geräte, die unterbrechen, die Quelle des Interrupts, indem sie die Interrupt-Vektoradresse übergeben. Hier ist die Adresse des ISR festgelegt und die Steuerung wird an diese Adresse übertragen und der ISR kümmert sich um den Rest.
Nicht vektorisiert: Hier haben alle Interrupts eine gemeinsame ISR. Wenn ein Interrupt von einer nicht vektorisierten Quelle auftritt, wird die Steuerung an die gemeinsame Adresse übertragen, an die sich alle nicht vektorisierten Interrupts teilen.
Unterbrechen Sie die Programmsteuerung in MSP430
Wenn der Interrupt auftritt, wird MCLK eingeschaltet und die CPU aus dem AUS-Zustand zurückgerufen. Wenn die Steuerung des Programms nach dem Auftreten des Interrupts an die ISR-Adresse übertragen wird, werden die Werte im Programmzähler und im Statusregister auf den Stapel verschoben.
Konsekutiv, wird Statusregister gelöscht, wodurch die GIE Clearing- und den abschließenden Low - Power - Modus. Ein Interrupt mit der höchsten Priorität wird ausgewählt und ausgeführt, indem die Interruptvektoradresse in den Programmzähler gestellt wird. Bevor wir zu unserem MSP430 GPIO Interrupt-Beispielcode gelangen, ist es wichtig, die Funktionsweise der daran beteiligten Portregister zu verstehen.
Portregister für die GPIO-Steuerung auf dem MSP430:
PxDIR: Es ist ein Portrichtungssteuerregister. Der Programmierer kann seine Funktion durch Schreiben von 0 oder 1 spezifisch auswählen. Wenn ein Pin als 1 ausgewählt ist, fungiert er als Ausgang. Betrachten Sie Port 1 als einen 8-Bit-Port. Wenn die Pins 2 und 3 als Ausgangsports zugewiesen werden sollen, muss das P1DIR-Register auf den Wert 0x0C gesetzt werden.
PxIN: Es ist ein schreibgeschütztes Register und die aktuellen Werte im Port können mit diesem Register gelesen werden.
PxOUT: Dieses spezielle Register kann verwendet werden, um Werte direkt in die Ports zu schreiben. Dies ist nur möglich, wenn das Pullup / Pulldown-Register deaktiviert ist.
PxREN: Dies ist ein 8-Bit-Register, mit dem das Pullup / Pulldown-Register aktiviert oder deaktiviert wird. Wenn ein Pin sowohl im PxREN- als auch im PxOUT-Register auf 1 gesetzt ist, wird der jeweilige Pin nach oben gezogen.
PxDIR |
PxREN |
PxOUT |
E / A-Konfiguration |
0 |
0 |
X. |
Eingang mit deaktivierten Widerständen |
0 |
1 |
0 |
Eingabe mit aktiviertem internen Pulldown |
0 |
1 |
1 |
Eingabe mit aktiviertem internen Pullup |
1 |
X. |
X. |
Ausgabe - PxREN hat keine Auswirkung |
PxSEL und PxSEL2: Da alle Pins in MSP430 gemultiplext sind, muss die jeweilige Funktion ausgewählt werden, bevor sie verwendet wird. Wenn sowohl das PxSEL- als auch das PxSEL2-Register für einen bestimmten Pin auf 0 gesetzt sind, wird die Allzweck-E / A ausgewählt. Wenn PxSEL auf 1 gesetzt ist, wird die primäre Peripheriefunktion ausgewählt und so weiter.
PxIE: Aktiviert oder deaktiviert Interrupts für einen bestimmten Pin in einem Port x.
PxIES: Wählt die Kante aus, an der ein Interrupt generiert wird. Für 0 wird eine ansteigende Flanke ausgewählt und für 1 wird eine abfallende Flanke ausgewählt.
MSP430-Schaltung zum Testen des GPIO-Interrupts
Die MSP430-Schaltung, die zum Testen unseres MSP430-Interrupt-Beispielcodes verwendet wird, ist unten gezeigt.
Mit der Erdung der Platine werden sowohl die LED als auch die Taste geerdet. Die diagonal gegenüberliegenden Seiten des Druckknopfs sind normalerweise offene Anschlüsse und werden verbunden, wenn der Druckknopf gedrückt wird. Vor der LED ist ein Widerstand angeschlossen, um den hohen Stromverbrauch der LED zu vermeiden. Normalerweise werden niedrige Widerstände im Bereich von 100 Ohm - 220 Ohm verwendet.
Wir verwenden 3 verschiedene Codes, um die Port-Interrupts besser zu verstehen. Die ersten beiden Codes verwenden dieselbe Schaltung wie im Schaltplan 1. Lassen Sie uns in den Code eintauchen. Nachdem die Verbindungen hergestellt wurden, sieht mein Setup so aus.
Programmieren von MSP430 für Interrupts
Das vollständige MSP430-Interrupt-Programm finden Sie unten auf dieser Seite. Die Erläuterung des Codes lautet wie folgt.
Die folgende Zeile stoppt den Watchdog-Timer. Der Watchdog-Timer führt normalerweise zwei Operationen aus. Zum einen wird verhindert, dass der Controller Endlosschleifen durch Zurücksetzen des Controllers erhält, und zum anderen werden periodische Ereignisse mithilfe des integrierten Timers ausgelöst. Wenn ein Mikrocontroller zurückgesetzt (oder eingeschaltet) wird, befindet er sich im Timer-Modus und neigt dazu, die MCU nach 32 Millisekunden zurückzusetzen. Diese Zeile hindert den Controller daran.
WDTCTL = WDTPW + WDTHOLD;
Wenn Sie das P1DIR- Register auf den Wert 0x07 setzen, wird die Richtung von Pin0, Pin1 und Pin2 als Ausgang festgelegt. Wenn Sie P1OUT auf 0x30 einstellen, wird ein Eingang mit internen Pullup-Widerständen konfiguriert, die an Pin4 und Pin5 aktiviert sind. Wenn Sie P1REN auf 0x30 setzen, wird das interne Pullup an diesen Pins aktiviert. P1IE aktiviert den Interrupt, wobei P1IES den Übergang von hoch nach niedrig als Interrupt-Flanke an diesen Pins auswählt.
P1DIR - = 0x07; P1OUT = 0x30; P1REN - = 0x30; P1IE - = 0x30; P1IES - = 0x30; P1IFG & = ~ 0x30;
Die nächste Zeile aktiviert den Energiesparmodus und aktiviert die GIE im Statusregister, damit die Interrupts empfangen werden können.
__bis_SR_register (LPM4bits + GIE)
Der Programmzähler wird mit der Adresse des Vektors von Port 1 unter Verwendung des Makros gesetzt.
PORT1_VECTOR . #pragma vector = PORT1_VECTOR __interrupt void Port_1 (void)
Der folgende Code schaltet jede der an Pin0, Pin1, Pin2 angeschlossenen LEDs nacheinander um.
if (count% 3 == 0) { P1OUT ^ = BIT1; P1IFG & = ~ 0x30; count ++; } else if (count% 3 == 1) { P1OUT ^ = BIT1; P1IFG & = ~ 0x30; count ++; } else { P1OUT ^ = BIT2; P1IFG & = ~ 0x30; count ++; }}
Schaltplan 2:
Versuchen wir auch einen anderen Stift, um das Konzept besser zu verstehen. Hier ist also der Druckknopf an Pin 2.0 anstatt an Pin 1.5 angeschlossen. Die modifizierte Schaltung ist wie folgt. Wieder wird diese Schaltung verwendet, um das Interrupt- Programm der MSP430-Taste zu testen.
Hier wird der Port 2 zur Eingabe verwendet. Es muss also ein anderer Interruptvektor verwendet werden. P1.4 und P2.0 übernehmen die Eingänge.
Da Port 2 nur für den Eingang verwendet wird, wird P2DIR auf 0 gesetzt. Um den Pin0 von Port 2 als Eingang mit aktivierten internen Pull-up-Widerständen zu setzen, müssen die Register P2OUT und P2REN auf den Wert 1 gesetzt werden Interrupt an Pin0 von Port 2 und auch um die Flanke des Interrupts auszuwählen, werden P2IE und P2IES mit dem Wert 1 gesetzt. Um das Flag in Port 2 zurückzusetzen, wird P2IFG gelöscht, so dass das Flag auf dem erneut gesetzt werden kann Auftreten des Interrupts.
P2DIR - = 0x00; P2OUT = 0x01; P2REN - = 0x01; P2IE - = 0x01; P2IES - = 0x01; P2IFG & = ~ 0x01;
Wenn die Interruptquelle von Port 1 stammt, leuchtet die an Pin 1 von Port 1 angeschlossene LED. Wenn die Interruptquelle zu Port 2 gehört, leuchtet die an Pin 2 von Port 1 angeschlossene LED.
#pragma vector = PORT1_VECTOR __interrupt void Port_1 (void) { P1OUT ^ = BIT1; P1IFG & = ~ 0x10; für (i = 0; i <20000; i ++) { } P1OUT ^ = BIT1; } #pragma vector = PORT2_VECTOR __interrupt void Port_2 (void) { P1OUT ^ = BIT2; P2IFG & = ~ 0x01; für (j = 0; j <20000; j ++) { } P1OUT ^ = BIT2; }}
Programm von CCS auf MSP430 hochladen
Um das Projekt auf das Launchpad zu laden und zu debuggen, wählen Sie das Projekt aus und klicken Sie auf das Debug-Symbol in der Symbolleiste. Alternativ können Sie F11 drücken oder auf RunàDebug klicken, um in den Debug-Modus zu gelangen.
Sobald der Debug-Modus aufgerufen ist, drücken Sie die grüne Farbtaste, um den geladenen Code in der MCU frei auszuführen. Wenn nun der Druckknopf gedrückt wird, wird durch die Änderung der Flanke ein Interrupt ausgelöst, wodurch der Status der LED geändert wird.
Programm auf MSP430 unterbrechen
Nachdem der Code erfolgreich hochgeladen wurde, können wir ihn einfach mit dem Druckknopf testen. Das LED-Muster ändert sich je nach Programm, wenn mit dem Druckknopf ein Interrupt erfolgt.
Die komplette Arbeit finden Sie im unten verlinkten Video. Ich hoffe, Ihnen hat das Tutorial gefallen und Sie haben etwas Nützliches gelernt. Wenn Sie Fragen haben, lassen Sie diese im Kommentarbereich oder nutzen Sie unsere Foren für andere technische Fragen.