El programa consiste en enviar un pulso por un pin al pulsar el botón sw1 del Launchpad. El MCU permanece en LPM0 todo el tiempo hasta que se pulsa el interruptor. El bucle principal envía el pulso y regresa a LPM0.
En el programa se compara la utilización de LPM0 frente a un bucle infinito. También se muestran dos maneras de entrar en LPM0
MAP_PCM_gotoLPM0();
MAP_PCM_setPowerState(PCM_LPM0_DCDC_VCORE0);
La manera de salir de LPM0 al ejecutar la interrupción es mediante la instrucción al inicio del programa:
MAP_Interrupt_disableSleepOnIsrExit();
Algunos valores de consumo: | |
---|---|
Sin entrar en LPM0 | 1.88 mA |
MAP_PCM_gotoLPM0() | 1.70 mA |
MAP_PCM_setPowerState(PCM_LPM0_DCDC_VCORE0) | 1.65 mA |
1. Cabecera y unas definiciones de pines:
#include "driverlib.h" #define PIN_CH1 GPIO_PORT_P4, GPIO_PIN3 #define PIN_CH2 GPIO_PORT_P4, GPIO_PIN4 #define PIN_SW1 GPIO_PORT_P1, GPIO_PIN1
2. Setup de los pines
void setup_GPIO () { // salidas P4.3 y P4.4 MAP_GPIO_setAsOutputPin (PIN_CH1); MAP_GPIO_setAsOutputPin (PIN_CH2); // P1.1 - input con interrupción MAP_GPIO_setAsInputPinWithPullUpResistor (PIN_SW1); MAP_GPIO_clearInterruptFlag (PIN_SW1); MAP_GPIO_enableInterrupt (PIN_SW1); // Activar interrupción y despertar al salir de la interrupción MAP_Interrupt_enableInterrupt (INT_PORT1); MAP_Interrupt_disableSleepOnIsrExit(); MAP_Interrupt_enableMaster(); }
3. Función main(). Compilación condicional con o sin LPM0
#define USE_LPM0 #ifndef USE_LPM0 volatile int continua = 1; #endif int main(void) { WDT_A_holdTimer(); setup_GPIO(); int i; while(1){ MAP_GPIO_setOutputLowOnPin (PIN_CH1); for(i=1000; i>0; i--); MAP_GPIO_setOutputHighOnPin (PIN_CH1); for(i=1000; i>0; i--); #ifdef USE_LPM0 MAP_PCM_gotoLPM0(); //MAP_PCM_setPowerState(PCM_LPM0_DCDC_VCORE0); // otra posibilidad #else while (continua) { __no_operation(); } continua = 1; #endif } // del while } // del main
4. Interrupción. Si se utiliza LPM0 la rutina de la interrupción no hace nada excepto limpiar la bandera de la propia interrupción.
/* GPIO ISR */ void PORT1_IRQHandler(void) { uint32_t status; status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status); #ifndef USE_LPM0 continua = 0; #endif } // de la fn
5. El programa completo
/* * Programa para pruebas de interrupciones del GPIO, LPM0. * Utilización de driverlib. * * El buche principal en main() es un blink que pasa a lpm0. * La pulsación de sw1 del launchpad lanza la interrupción que * despierta la mcu * */ #include "driverlib.h" #define PIN_CH1 GPIO_PORT_P4, GPIO_PIN3 #define PIN_CH2 GPIO_PORT_P4, GPIO_PIN4 #define PIN_SW1 GPIO_PORT_P1, GPIO_PIN1 void setup_GPIO () { // salidas P4.3 y P4.4 MAP_GPIO_setAsOutputPin (PIN_CH1); MAP_GPIO_setAsOutputPin (PIN_CH2); // P1.1 - input con interrupción MAP_GPIO_setAsInputPinWithPullUpResistor (PIN_SW1); MAP_GPIO_clearInterruptFlag (PIN_SW1); MAP_GPIO_enableInterrupt (PIN_SW1); // Activar interrupción y despertar al salir de la interrupción MAP_Interrupt_enableInterrupt (INT_PORT1); MAP_Interrupt_disableSleepOnIsrExit(); MAP_Interrupt_enableMaster(); } // MAP_PCM_gotoLPM0(); // 1.88 mA sin lpm0; 1.70 mA en lpm0 // MAP_PCM_setPowerState(PCM_LPM0_DCDC_VCORE0); // 1.65 mA en lpm0 #define USE_LPM0 #ifndef USE_LPM0 volatile int continua = 1; #endif int main(void) { WDT_A_holdTimer(); setup_GPIO(); //----MAP_PCM_setPowerMode(PCM_LDO_MODE); int i; while(1){ MAP_GPIO_setOutputLowOnPin (PIN_CH1); for(i=1000; i>0; i--); MAP_GPIO_setOutputHighOnPin (PIN_CH1); for(i=1000; i>0; i--); #ifdef USE_LPM0 MAP_PCM_gotoLPM0(); //MAP_PCM_setPowerState(PCM_LPM0_DCDC_VCORE0); #else while (continua) { __no_operation(); } continua = 1; #endif } // del while } // del main /* GPIO ISR */ void PORT1_IRQHandler(void) { uint32_t status; status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status); #ifndef USE_LPM0 continua = 0; #endif } // de la fn