STM32待機(jī)模式喚醒測試以及獨立看門狗測試
環(huán)境:
主機(jī):WIN7
開發(fā)環(huán)境:MDK4.23
MCU:STM32F103CBT6
說明:
在上篇文章中http://blog.csdn.net/jdh99/article/details/7369844,進(jìn)行了一些STM32待機(jī)模式的測試.其中關(guān)于如何在再次啟動時判斷是否是待機(jī)模式?jīng)]有進(jìn)行測試.另外上篇文章有個問題,鬧鐘中斷在待機(jī)模式下是進(jìn)入不了的.
本文進(jìn)行了獨立看門狗IWDG測試,以及待機(jī)模式更詳細(xì)的測試.
STM32中,復(fù)位分為3種:
1.系統(tǒng)復(fù)位:外部復(fù)位,WWDG,IWDG,SW復(fù)位,低功耗管理復(fù)位.除復(fù)位標(biāo)志寄存器RCC_CSR不被復(fù)位,全部都被復(fù)位
2.電源復(fù)位:上電/掉電復(fù)位,從待機(jī)模式復(fù)位.上電/掉電復(fù)位除備份域外寄存器全部復(fù)位.待機(jī)復(fù)位不會復(fù)位備份域寄存器以及PWR_CSR寄存器.
3.備份域復(fù)位.
寄存器說明:
由圖可以看出,可以通過WUF位來判斷是否由待機(jī)模式喚醒.
RCC_CSR寄存器:
由圖可以看出,RCC_CSR寄存器的IWDGRSTF位可以指示是否發(fā)生獨立看門狗復(fù)位.
因為在看門狗復(fù)位時如果系統(tǒng)不處在待機(jī)模式,PWR_CSR寄存器也會被復(fù)位,所以WUF位也可以指示是否發(fā)生獨立看門狗復(fù)位.
源代碼:
獨立看門狗復(fù)位測試:
//檢查喚醒標(biāo)志是否設(shè)置
if(PWR_GetFlagStatus(PWR_FLAG_WU)==RESET)
{
//首次啟動,或者獨立看門狗復(fù)位
//初始化備份寄存器
//BKP_DeInit();
//RTC功能開啟
//使能外部晶振
RCC_LSEConfig(RCC_LSE_ON);
//等待外部晶振準(zhǔn)備好
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);
//設(shè)置RTC時鐘為外部晶振
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
//使能RTC時鐘
RCC_RTCCLKCmd(ENABLE);
//等待RTC_CTL寄存器中的RSF位(寄存器同步標(biāo)志)被硬件置1
RTC_WaitForSynchro();
RTC_WaitForLastTask();
//使能鬧鐘中斷
RTC_ITConfig(RTC_IT_ALR,ENABLE);
RTC_WaitForLastTask();
//分頻系數(shù)為1,即最小時間單位1/2^15=30.5us
RTC_SetPrescaler(RTC_PRESCALE);
RTC_WaitForLastTask();
//啟動獨立看門狗
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//訪問之前要首先使能寄存器寫
IWDG_SetPrescaler(IWDG_Prescaler_64);//64分頻一個周期1.6ms
IWDG_SetReload(1250);//最長12位[0,4096]1250*1.6=2s
IWDG_ReloadCounter();//喂狗
//使能開門狗
IWDG_Enable();
if(BKP_ReadBackupRegister(BKP_DR6)==0xabcd)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_11);
BKP_WriteBackupRegister(BKP_DR6,0);
}
else
{
GPIO_SetBits(GPIOA,GPIO_Pin_11);
BKP_WriteBackupRegister(BKP_DR6,0xabcd);
}
}
else
{
//從待機(jī)模式中退出
//清除喚醒標(biāo)志
RCC_ClearFlag();
if(BKP_ReadBackupRegister(BKP_DR7)==0xabcd)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_8);
BKP_WriteBackupRegister(BKP_DR7,0);
}
else
{
GPIO_SetBits(GPIOA,GPIO_Pin_8);
BKP_WriteBackupRegister(BKP_DR7,0xabcd);
}
}
while(1);
測試結(jié)果PA11引腳所連的LED不斷閃爍,PA8所連的LED常亮,這說明不斷進(jìn)入看門狗復(fù)位.
待機(jī)模式RTC鬧鐘喚醒測試:
//檢查喚醒標(biāo)志是否設(shè)置
if(PWR_GetFlagStatus(PWR_FLAG_WU)==RESET)
{
//首次啟動,或者獨立看門狗復(fù)位
//初始化備份寄存器
//BKP_DeInit();
//RTC功能開啟
//使能外部晶振
RCC_LSEConfig(RCC_LSE_ON);
//等待外部晶振準(zhǔn)備好
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);
//設(shè)置RTC時鐘為外部晶振
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
//使能RTC時鐘
RCC_RTCCLKCmd(ENABLE);
//等待RTC_CTL寄存器中的RSF位(寄存器同步標(biāo)志)被硬件置1
RTC_WaitForSynchro();
RTC_WaitForLastTask();
//使能鬧鐘中斷
RTC_ITConfig(RTC_IT_ALR,ENABLE);
RTC_WaitForLastTask();
//分頻系數(shù)為1,即最小時間單位1/2^15=30.5us
RTC_SetPrescaler(RTC_PRESCALE);
RTC_WaitForLastTask();
//啟動獨立看門狗
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//訪問之前要首先使能寄存器寫
IWDG_SetPrescaler(IWDG_Prescaler_64);//64分頻一個周期1.6ms
IWDG_SetReload(1250);//最長12位[0,4096]1250*1.6=2s
IWDG_ReloadCounter();//喂狗
//使能開門狗
//IWDG_Enable();
if(BKP_ReadBackupRegister(BKP_DR6)==0xabcd)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_11);
BKP_WriteBackupRegister(BKP_DR6,0);
}
else
{
GPIO_SetBits(GPIOA,GPIO_Pin_11) ;