The fifth course module examines the use of interrupts and the programming of the interrupt handler to improve program and power efficiency. The lab for this module shows how to change the program in Lab4 from using polling to using interrupts.
This module goes over the different types of interrupts and how the Interrupt Handler operates. The Interrupt Handler needs to run in Privileged Mode so that it has access to core functions in the processor. The handler uses the Nested Vector Interrupt Controller (NVIC) and the Interrupt Service Routine to execute the interrupt. It also covers Masks, Priority, and Latency and described how execution is resumed post interrupt.
Lab Exercise - Interrupt and Low power Features
The lab introduces the use of what they call "drivers" but I normally think of as library or auxiliary modules, i.e function definitions are now moved into external files to improve the readability of the main file.
The new program functionality is the setup for interrupt handling which is in the interrupts.c file.
/*---------------------------------------------------------------------------- Interrupts C file *----------------------------------------------------------------------------*/ #include "interrupts.h" #include "stm32f4xx.h" void init_interrupts(void){ //Start clock for the SYSCFG RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; //Enable debug in low-power modes DBGMCU->CR |= DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | DBGMCU_CR_DBG_STANDBY; //Setup interrupt configuration register for interrupts SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI13_PC; EXTI->IMR |= (EXTI_IMR_MR13); //set the interrupt mask EXTI->FTSR |= (EXTI_FTSR_TR13); //trigger on a falling edge __enable_irq(); //Set priority NVIC_SetPriority(EXTI15_10_IRQn, 0); //Clear pending interrupts NVIC_ClearPendingIRQ(EXTI15_10_IRQn); //Enable interrupts NVIC_EnableIRQ(EXTI15_10_IRQn); } // *******************************ARM University Program Copyright (c) ARM Ltd 2014*************************************
The other difference is the Wait For Interrupt (wfi) instruction in the main program to enter low power mode:
/*---------------------------------------------------------------------------- MAIN function *----------------------------------------------------------------------------*/ int main() { // Initialise LEDs and buttons init_led(); init_button(); init_interrupts(); while(1){ __wfi(); //Wait for interrupts } }
Here is the excerpt from the reference manual: (the link on the lab page is broken - http://www.st.com/web/en/resource/technical/document/reference_manual/DM00096844.pdf )
The main apparent difference is that the LED now toggles on each button press rather than turning on for the button press and turning off when the button is released. This is due the interrupt only triggering on the button press (falling edge of GPIO pin). I can measure a difference of about -10mA power supply current between the previous lab's program and the current one..