MSP430 - Eingänge der parallelen Schnittstelle
Einlesen der Eingangsregisters
- Die Register PxIN und PxREN werden verwendet, um Eingänge des MSP430 zu benutzen.
- Detaillierte Informationen über alle MSP430 Register sind im sogenannten Family Guide nachzuschlagen.
- Der passende Family Guide des MSP430G2553 kann unter folgender URL gefunden werden: https://www.ti.com/lit/ug/slau144j/slau144j.pdf
- Detaillierte Informationen zu den Registern PxIN und PxREN sind ab Seite 328 zu finden.
Register der parallelen Schnittstelle
Input Register PxIN
Each bit in each PxIN register reflects the value of the input signal at the corresponding I/O pin when the pin is configured as I/O function.
Bit = 0: The input is low
Bit = 1: The input is high
Output Registers PxOUT
Each bit in each PxOUT register is the value to be output on the corresponding I/O pin when the pin is configured as I/O function, output direction, and the pullup/down resistor is disabled.
Bit = 0: The output is low
Bit = 1: The output is high
If the pin's pullup/pulldown resistor is enabled, the corresponding bit in the PxOUT register selects pullup or pulldown.
Bit = 0: The pin is pulled down
Bit = 1: The pin is pulled up
Direction Registers PxDIR
Each bit in each PxDIR register selects the direction of the corresponding I/O pin, regardless of the selected function for the pin. PxDIR bits for I/O pins that are selected for other functions must be set as required by the other function.
Bit = 0: The port pin is switched to input direction
Bit = 1: The port pin is switched to output direction
Pullup/Pulldown Resistor Enable Registers PxREN
Each bit in each PxREN register enables or disables the pullup/pulldown resistor of the corresponding I/O pin. The corresponding bit in the PxOUT register selects if the pin is pulled up or pulled down.
Bit = 0: Pullup/pulldown resistor disabled
Bit = 1: Pullup/pulldown resistor enabled
Source: Family Guide, S. 328f
Abfragen von Pin-Zuständen
Initialisierung des Taster-Pins, Aktivieren des zusätzlichen Pullup-Widerstand
Verwenden des Pin-Pegels in einer Bedingung
Warte, bis Pin einen Pegel annimmt
Einlesen der Eingangsregisters - Beispiel 1
#include <msp430.h>
#include <stdint.h>
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
P1DIR |= BIT0;
P1DIR &= ~BIT3;
P1OUT |= BIT3;
P1REN |= BIT3;
while (1) {
if (!(P1IN & BIT3)) {
P1OUT |= BIT0;
} else {
P1OUT &= ~ BIT0;
}
}
}
Einlesen der Eingangsregisters - Beispiel 2
#include <msp430.h>
#include <stdint.h>
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
P1DIR |= BIT0;
P1DIR &= ~BIT3;
P1OUT |= BIT3;
P1REN |= BIT3;
while (1) {
while (P1IN & BIT3) {
}
P1OUT ^= BIT0;
while (!(P1IN & BIT3)) {
}
}
}
Aufgabe
Testen Sie die beiden Programme. Worin unterscheidet sich die Funktionsweise?
Aufgabe
Veränderen Sie Ihre Lösung der RGB-Anzeige, sodass die LED-Farbe sich auf Tastendruck ändert.
Interrupts und Low-Power-Modi
Programmierung
Interrupt-Register der parallelen Schnittstelle
Interrupt Flag Registers P1IFG, P2IFG
Each PxIFGx bit is the interrupt flag for its corresponding I/O pin and is set when the selected input signal edge occurs at the pin. All PxIFGx interrupt flags request an interrupt when their corresponding PxIE bit and the GIE bit are set. Each PxIFG flag must be reset with software. Software can also set each PxIFG flag, providing a way to generate a software initiated interrupt.
Bit = 0: No interrupt is pending
Bit = 1: An interrupt is pending
Only transitions, not static levels, cause interrupts. If any PxIFGx flag becomes set during a Px interrupt service routine, or is set after the RETI instruction of a Px interrupt service routine is executed, the set PxIFGx flag generates another interrupt. This ensures that each transition is acknowledged.
Interrupt Edge Select Registers P1IES, P2IES
Each PxIES bit selects the interrupt edge for the corresponding I/O pin.
Bit = 0: The PxIFGx flag is set with a low-to-high transition
Bit = 1: The PxIFGx flag is set with a high-to-low transition
Interrupt Enable P1IE, P2IE
Each PxIE bit enables the associated PxIFG interrupt flag.
Bit = 0: The interrupt is disabled.
Bit = 1: The interrupt is enabled.
Source: Family Guide, S. 331f
Umschalten der LED auf Tastendruck mit Interrupts
#include <msp430.h>
#include <stdint.h>
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
P1DIR |= BIT0;
P1DIR &= ~BIT3;
P1OUT |= BIT3;
P1REN |= BIT3;
P1IES |= BIT3;
P1IFG &= ~BIT3;
P1IE |= BIT3;
__enable_interrupt();
while (1) {
__low_power_mode_4();
P1OUT ^= BIT0;
}
}
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR() {
if (P1IFG & BIT3) {
P1IFG &= ~BIT3;
__low_power_mode_off_on_exit();
}
}
Low Power Modes
Basic Clock Module
- Drei verschiedenen Taktgeber, die durch das BCM+ generiert werden:
- Auxillary Clock (ACLK)
- Main System Clock (MCLK)
- Sub System Clock (SMCLK)
- Der DCO (Digitally Controlled Oscillator) erzeugt die Systemtakte (MCLK, SMCLK).
- Die Standard-Frequenz des DCO beträgt circa 1 MHz. Der DCO kann auf vorkalibrierte Werte von 1, 8, 12 or 16 MHz gesetzt werden.
- Zusätzliche Teiler können für MCLK und SMCLK konfiguriert werden.
- Der low frequency oscillator (LFXT1) erzeugt den Takt für die ACLK.
- Hierfür wird der Quarz-Oszillator an Pins P2.6 und P2.7 verwendet.
- Die Frequenz der ACLK beträgt daher 32.768 kHz
Strombedarfsmessung
Aufgabe
Messen Sie den Strombedarf des MSP430. (Weitere Hinweise siehe Launchpad MSP-EXP430G2ET, S. 11)
Aufgabe
Der Strombedarf des MSP430 ist stark abhängig von Pins mit uneindeutigen Pegel. Fügen Sie die folgenden Befehle hinzu, um an allen nicht verwendeten Pins den Pulldown-Widerstand zu aktivieren.
Vergleichen Sie den Wert mit dem Datenblatt auf Seite 23.
Detektieren verschiedener Interrupt-Quellen
- Verwenden eines zweiten Taster an P1.4.
- Wenn kein Taster zur Verfügung steht, kann ein Kabel der Pin P1.4 über ein Kabel mit Masse verbunden werden.
Programmierung von ISRs
- Während das Hauptprogramm läuft können ISR jederzeit ausgeführt werden.
- Aber während eine ISR läuft kann keine zweite ausgeführt werden.
- Um Programmkollision, -stopps oder Überspringen von Interrupts zu vermeiden, sollte eine ISR so kurz und schnell wie möglich gehalten werden!
- Typischer Ablauf:
- In der ISR: Löschen der Interrupt Flags,
- abspeichern der Information, welches Ereignis ausgelöst wurde.
- Verlassen des LPM.
- Im Hauptprogramm: Entscheiden anhand der abgespeicherten Informationen, welche Aktionen ausgeführt werden müssen.
Detektieren mehrerer Taster mit Interrupts
#include <msp430.h>
#include <stdint.h>
volatile uint8_t pressed_button;
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
P1DIR |= BIT0 + BIT6;
P1DIR &= ~(BIT3 + BIT4);
P1OUT |= BIT3 + BIT4;
P1REN |= BIT3 + BIT4;
P1IES |= BIT3 + BIT4;
P1IFG &= ~(BIT3 + BIT4);
P1IE |= BIT3 + BIT4;
__enable_interrupt();
pressed_button = 0;
while (1) {
if (pressed_button & BIT0) {
P1OUT ^= BIT0;
pressed_button &= ~BIT0;
}
else if (pressed_button & BIT1) {
P1OUT ^= BIT6;
pressed_button &= ~BIT1;
} else {
__low_power_mode_4();
}
}
}
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR() {
if (P1IFG & BIT3) {
pressed_button |= BIT0;
P1IFG &= ~BIT3;
__low_power_mode_off_on_exit();
}
if (P1IFG & BIT4) {
pressed_button |= BIT1;
P1IFG &= ~BIT4;
__low_power_mode_off_on_exit();
}
}
Aufgabe
Passen Sie Ihre Programm von Aufgabe 2 an, sodass dieses nun mit Interrupts funktioniert. Verwenden Sie einen zweiten Taster, um eine Farbwert zurückzuschalten. Halten Sie die ISR so kurz wie möglich!