(6) Mikrokontrolery MSP430: porty I/O, obsługa wejść
W programie głównym zatrzymywana jest pracy układu Watchdog :
WDTCTL = WDTPW + WDTHOLD;
Następnie konfigurowane są linie wejścia/wyjścia mikrokontrolera. Wszystkie linie wejścia/wyjścia ustawiane są jako wyjścia w stanie niskim. Najpierw ustawiany jest stan niski na liniach, następnie zmieniany jest kierunek linii z wejścia na wyjście:
P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00; P4OUT = 0x00; PJOUT = 0x00; P1DIR = 0xff; P2DIR = 0xff; P3DIR = 0xff; P4DIR = 0xff; PJDIR = 0xff;
W kolejnych instrukcjach konfigurowana jest praca linii numer 0 portu P4 (jest to linia, do której dołączono przycisk S1). Aktywowany jest rezystor podciągający typu pull-up :
P4OUT |= BIT0; P4REN |= BIT0;
Zmieniany jest kierunek linii z wyjścia na wejście:
P4DIR &=~ BIT0;
Linia P4.0 pracuje jako wejście z rezystorem podciągającym pull-up . W pętli głównej programu sprawdzany jest stan wejścia. Jeśli na wejściu wykryty zostanie stan niski (wciśnięcie przycisku S1), to włączana jest dioda sygnalizacyjna LED1:
if( !(P4IN & BIT0) ) { PJOUT |= BIT0; }
W przeciwnym wypadku (przycisk S1 jest zwolniony) dioda sygnalizacyjna LED1 jest wyłączana:
else { PJOUT &=~ BIT0; }
Tryb przerwań
Kod źródłowy programu z obsługą wejścia w trybie przerwań pokazano na listingu 6.
List. 6 Obsługa wejścia. Tryb przerwań
// "MSP430 z pamięcią FRAM" // konfiguracja "MSP-EXP430FR5739": // Zadanie numer 6.1. Obsługa wejścia. Tryb przerwań. // ( ustawienia fabryczne ) // // w programie wykorzystano // ACLK nieaktywny // zainstalowany w module // MCLK = SMCLK = DCOCLK ~1MHz // przycisk S1, oraz diode LED1 // // // MSP430FR5739 // działanie programu: // ----------------- // wciśnięcie przycisku S1 // | | // włącza diodę LED1 // S1 -> | P4.0 PJ.0 | -> LED1 // zwolnienie przycisku S1 // | | Ł.K.'13 // wyłącza diodę LED1 //------------------------------------------------------------------- // // pliki nagłówkowe #include "io430.h" // rejestry procesora #include "intrinsics.h" // instrukcje procesora // void main( void ) // program główny { // WDTCTL = WDTPW + WDTHOLD; // zatrzymaj układ Watchdog // // konfiguracja linii we/wy P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00; P4OUT = 0x00; // ustaw stan niski na liniach PJOUT = 0x00; // ( wszystkie linie pracują w // trybie we/wy, PxSELx wyzerowane ) P1DIR = 0xff; P2DIR = 0xff; P3DIR = 0xff; P4DIR = 0xff; // ustaw linie w kierunku wyjścia PJDIR = 0xff; // // konfiguracja P4.0 P4OUT |= BIT0; // ( wejście "pull-up" ) P4REN |= BIT0; // włącz rezystor podciągający P4DIR &=~ BIT0; // ustaw linie w kierunku wejścia // ( obsługa przerwań ) P4IES |= BIT0; // ustaw zbocze wyzwalające ( 1->0 ) P4IFG &=~ BIT0; // zeruj flagę przerwania P4IE |= BIT0; // włącz obsługę przerwania // __bis_SR_register(GIE); // odblokowanie przerwań maskowalnych // while(1) // pętla główna programu { // // włącz tryb uśpienia LPM4 __bis_SR_register( LPM4_bits ); // sygnały zegarowe są wyłączone // tylko odświeżanie SRAM // PJOUT |= BIT0; // włącz diodę LED1 while(!(P4IN & BIT0)); // czekaj dopóki S1 jest wciśnięty PJOUT &=~ BIT0; // wyłącz diodę LED1 }; // } // // #pragma vector=PORT4_VECTOR // procedura obsługi przerwania __interrupt void Port_4(void) // port P4 (linie P4.0 oraz P4.1) { // switch(__even_in_range(P4IV,4)) // sprawdź wartość rejestru P4IV { // case 2: // P4.0 // po wyjściu z procedury obsługi __bic_SR_register_on_exit( LPM4_bits ); // przerwania, wyjdź z trybu LPM4 break; // case 4: break; // P4.1 default: break; // brak obsługi } // } //
W programie głównym jest zatrzymywana praca układu Watchdog . Linie wejścia/wyjścia mikrokontrolera ustawiane są jako wyjścia w stanie niskim. Linia P4.0 do której dołączono przycisk S1 jest konfigurowana jako wejście z włączonym rezystorem podciągającym pull-up .
Następnie konfigurowana jest obsługa przerwań dla wejścia P4.0. Ustawiane jest zbocze sygnału, które ustawia flagę przerwania. Ponieważ program ma reagować na wciśnięcie przycisku S1 (zmiana stanu na wejściu z wysokiego na niski), to ustawiane jest zbocze opadające:
P4IES |= BIT0;
Zerowana jest flaga przerwania:
P4IFG &=~ BIT0;
Włączana jest obsługa przerwań dla wejścia P4.0:
P4IE |= BIT0;
Następnie odblokowywana jest obsługa przerwań maskowalnych:
__bis_SR_register(GIE);
W pętli głównej programu mikrokontroler wprowadzany jest w tryb uśpienia LPM4:
__bis_SR_register( LPM4_bits );
W trybie uśpienia LPM4 jednostka centralna CPU mikrokontrolera jest wyłączona. Źródła sygnałów zegarowych są wyłączone. Wszystkie sygnały zegarowe są nieaktywne. Jedynie co robi mikrokontroler to podtrzymuje zawartość pamięci SRAM. Mikrokontroler przebywa w trybie uśpienia LPM4, do momentu wciśnięcia przycisku S1. Wówczas stan sygnału na wejściu P4.0 zmienia się z wysokiego na niski (opadające zbocze sygnału). Ustawiana jest flaga przerwania, a program przechodzi do wykonania procedury obsługi przerwania:
#pragma vector=PORT4_VECTOR __interrupt void Port_4(void) { switch(__even_in_range(P4IV,4)) { case 2: __bic_SR_register_on_exit( LPM4_bits ); break; case 4: break; default: break; } }
W procedurze obsługi przerwania odczytywana jest wartość rejestru P4IV (instrukcja switch). Odczytanie z rejestru wartości 2 oznacza przerwanie od wejścia P4.0. W bloku programu z kodem obsługi przerwania od wejścia P4.0 wydawana jest instrukcja, która nakazuje aby po zakończeniu procedury obsługi przerwania mikrokontroler nie wracał do trybu uśpienia:
__bic_SR_register_on_exit( LPM4_bits );
Następnie procedura obsługi przerwania jest kończona. Po wyjściu z procedury obsługi przerwania mikrokontroler opuszcza tryb uśpienia LPM4 i rozpoczyna wykonanie pętli głównej programu. W pętli głównej programu włączana jest dioda LED1:
PJOUT |= BIT0;
W pętli while sprawdzany jest stan wejścia:
while(!(P4IN & BIT0));
Pracę pętli while przerywa wykrycie stanu wysokiego na wejściu (puszczenie przycisku S1). Wówczas wydawana jest instrukcja wyłączająca diodę LED1:
PJOUT &=~ BIT0;
Następnie mikrokontroler ponownie jest usypiany. W trybie uśpienie LPM4 mikrokontroler MSP430FR5739 pozostaje do momentu ponownego wciśnięcia przycisku S1.
Pobór prądu
W testowanym programie (tryb polling ) mikrokontroler cyklicznie sprawdza stan wejścia, pracując w trybie aktywnym AM. Pobór prądu przez mikrokontroler zastosowany w zestawie LaunchPad wynosi około 222,1 µA. W drugiej wersji programu – z wykorzystaniem przerwań – mikrokontroler korzysta z trybu uśpienia LPM4. W trybie uśpienia pobór prądu modułu LaunchPad wynosi 8,1 µA. W czasie, gdy przycisk S1 jest wciśnięty a dioda LED1 włączona, pobór prądu w obu przypadkach wynosi 2,58 mA.
Pobór prądu zestawu Launchpad mierzony był na złączu J3 (amperomierz wpięty w linię VCC układu). Zestaw był zasilany z portu USB komputera PC. |
Zakładając, że w ciągu doby przycisk będzie wciskany 5 razy i za każdym razem na czas 20 sekund, to w przypadku programu z obsługą przerwań średni pobór prądu moduł będzie 20 razy mniejszy! Zasilając moduł LaunchPad z baterii CR2032 o pojemności 240 mAh, w pierwszym przypadku na jednym komplecie baterii moduł będzie pracować niecałe 45 dni, w drugim przypadku prawie 2,5 roku. W przypadku energooszczędnych aplikacji mikrokontroler powinien korzystać z trybów uśpienia LPMx, a wejścia mikrokontrolera powinny być obsługiwane w trybie przerwań!