STM32待機(jī)模式喚醒測(cè)試以及獨(dú)立看門(mén)狗測(cè)試
掃描二維碼
隨時(shí)隨地手機(jī)看文章
環(huán)境:
主機(jī):WIN7
開(kāi)發(fā)環(huán)境:MDK4.23
MCU:STM32F103CBT6
說(shuō)明:
在上篇文章中http://blog.csdn.net/jdh99/article/details/7369844,進(jìn)行了一些STM32待機(jī)模式的測(cè)試.其中關(guān)于如何在再次啟動(dòng)時(shí)判斷是否是待機(jī)模式?jīng)]有進(jìn)行測(cè)試.另外上篇文章有個(gè)問(wèn)題,鬧鐘中斷在待機(jī)模式下是進(jìn)入不了的.
本文進(jìn)行了獨(dú)立看門(mén)狗IWDG測(cè)試,以及待機(jī)模式更詳細(xì)的測(cè)試.
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ù)位不會(huì)復(fù)位備份域寄存器以及PWR_CSR寄存器.
3.備份域復(fù)位.
寄存器說(shuō)明:
由圖可以看出,可以通過(guò)WUF位來(lái)判斷是否由待機(jī)模式喚醒.
RCC_CSR寄存器:
由圖可以看出,RCC_CSR寄存器的IWDGRSTF位可以指示是否發(fā)生獨(dú)立看門(mén)狗復(fù)位.
因?yàn)樵诳撮T(mén)狗復(fù)位時(shí)如果系統(tǒng)不處在待機(jī)模式,PWR_CSR寄存器也會(huì)被復(fù)位,所以WUF位也可以指示是否發(fā)生獨(dú)立看門(mén)狗復(fù)位.
源代碼:
獨(dú)立看門(mén)狗復(fù)位測(cè)試:
//檢查喚醒標(biāo)志是否設(shè)置
if(PWR_GetFlagStatus(PWR_FLAG_WU)==RESET)
{
//首次啟動(dòng),或者獨(dú)立看門(mén)狗復(fù)位
//初始化備份寄存器
//BKP_DeInit();
//RTC功能開(kāi)啟
//使能外部晶振
RCC_LSEConfig(RCC_LSE_ON);
//等待外部晶振準(zhǔn)備好
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);
//設(shè)置RTC時(shí)鐘為外部晶振
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
//使能RTC時(shí)鐘
RCC_RTCCLKCmd(ENABLE);
//等待RTC_CTL寄存器中的RSF位(寄存器同步標(biāo)志)被硬件置1
RTC_WaitForSynchro();
RTC_WaitForLastTask();
//使能鬧鐘中斷
RTC_ITConfig(RTC_IT_ALR,ENABLE);
RTC_WaitForLastTask();
//分頻系數(shù)為1,即最小時(shí)間單位1/2^15=30.5us
RTC_SetPrescaler(RTC_PRESCALE);
RTC_WaitForLastTask();
//啟動(dòng)獨(dú)立看門(mén)狗
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//訪問(wèn)之前要首先使能寄存器寫(xiě)
IWDG_SetPrescaler(IWDG_Prescaler_64);//64分頻一個(gè)周期1.6ms
IWDG_SetReload(1250);//最長(zhǎng)12位[0,4096]1250*1.6=2s
IWDG_ReloadCounter();//喂狗
//使能開(kāi)門(mén)狗
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);
測(cè)試結(jié)果PA11引腳所連的LED不斷閃爍,PA8所連的LED常亮,這說(shuō)明不斷進(jìn)入看門(mén)狗復(fù)位.
待機(jī)模式RTC鬧鐘喚醒測(cè)試:
//檢查喚醒標(biāo)志是否設(shè)置
if(PWR_GetFlagStatus(PWR_FLAG_WU)==RESET)
{
//首次啟動(dòng),或者獨(dú)立看門(mén)狗復(fù)位
//初始化備份寄存器
//BKP_DeInit();
//RTC功能開(kāi)啟
//使能外部晶振
RCC_LSEConfig(RCC_LSE_ON);
//等待外部晶振準(zhǔn)備好
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);
//設(shè)置RTC時(shí)鐘為外部晶振
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
//使能RTC時(shí)鐘
RCC_RTCCLKCmd(ENABLE);
//等待RTC_CTL寄存器中的RSF位(寄存器同步標(biāo)志)被硬件置1
RTC_WaitForSynchro();
RTC_WaitForLastTask();
//使能鬧鐘中斷
RTC_ITConfig(RTC_IT_ALR,ENABLE);
RTC_WaitForLastTask();
//分頻系數(shù)為1,即最小時(shí)間單位1/2^15=30.5us
RTC_SetPrescaler(RTC_PRESCALE);
RTC_WaitForLastTask();
//啟動(dòng)獨(dú)立看門(mén)狗
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//訪問(wèn)之前要首先使能寄存器寫(xiě)
IWDG_SetPrescaler(IWDG_Prescaler_64);//64分頻一個(gè)周期1.6ms
IWDG_SetReload(1250);//最長(zhǎng)12位[0,4096]1250*1.6=2s
IWDG_ReloadCounter();//喂狗
//使能開(kāi)門(mén)狗
//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) ;