EFM32片內外設--RMU基本操作
在MCU執行的過程當中,RMU會一直不停的檢測各種復位源,例如POR Power-on Reset上電覆位,BOD Brown-out Detection,以及外部Reset腳復位,看門狗復位,軟體復位,或則是EM4喚醒等等。都可以通過查詢RMU->RSTCAUSE這個來獲知復位的原因。注意的是,有時候復位不是單一原因造成的,例如外部復位和看門狗復位同時發生等。
通過檢視reference manual裡面的表格,可以知道具體那幾位代表的是什麼意思。
初看,你會發現這張表格會稍顯複雜一些,其實很簡單,我們也不需要去記這張表格,請直接使用EMLib中的函RMU_ResetCauseGet() 即可獲知復位的原因。
知道可以獲知復位源之後,您肯定也想到了,如何去清除這個暫存器,為下一次查詢做好準備了。檢視Reference manual,發現這個RMU->RSTCAUSE這個暫存器是個只讀型別,要清除這個暫存器,必須經過如下三個步驟:
往RMU->CMD中的RCCLR寫1,往EMU->AUXCTRL中的bit0寫1,然後再往EMU->AUXCTRL中的bit0寫0.
或則呼叫:RMU_ResetCauseClear()來完成這項複雜的工作。呵呵。各位看官也可以參考如下的這段小程式碼(基於TG STK)。
#include <stdint.h>
#include <stdbool.h>
#include "efm32.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_rmu.h"
#include "em_gpio.h"
#include "segmentlcd.h"
#include "lcdtest.h"
#include "trace.h"
/**************************************************************************//**
* @brief GPIO Interrupt handler (PB11)
*****************************************************************************/
void GPIO_ODD_IRQHandler(void)
{
GPIO_IntClear(1 << 11);
RMU_ResetCauseClear();//使用按鍵來清除復位標誌
}
/**************************************************************************//**
* @brief GPIO Interrupt handler (PD8)
*****************************************************************************/
void GPIO_EVEN_IRQHandler(void)
{
GPIO_IntClear(1 << 8);
RMU_ResetCauseClear(); //使用按鍵來清除復位標誌
}
/**************************************************************************//**
* @brief Main function
*****************************************************************************/
int main(void)
{
/* Chip errata */
CHIP_Init();
/* Enable GPIO in CMU */
CMU_ClockEnable(cmuClock_GPIO, true);
/* Configure PD8 and PB11 as input */
GPIO_PinModeSet(gpioPortD, 8, gpioModeInput, 0);
GPIO_PinModeSet(gpioPortB, 11, gpioModeInput, 0);
/* Set falling edge interrupt for both ports */
GPIO_IntConfig(gpioPortD, 8, false, true, true);
GPIO_IntConfig(gpioPortB, 11, false, true, true);
/* Enable interrupt in core for even and odd gpio interrupts */
NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn);
NVIC_EnableIRQ(GPIO_EVEN_IRQn);
NVIC_ClearPendingIRQ(GPIO_ODD_IRQn);
NVIC_EnableIRQ(GPIO_ODD_IRQn);
/* Enable LCD without voltage boost */
SegmentLCD_Init(false);
SegmentLCD_AllOff();
while(1)
{
unsigned long ulDelay = 500000;
while(ulDelay--);
SegmentLCD_Number(RMU_ResetCauseGet()); //將復位標誌顯示在LCD上
//SegmentLCD_Number(RMU->RSTCAUSE);
}
}