本帖最后由 xld0932 于 2023-2-19 20:52 编辑
看门狗是用来监测由软件错误引起的系统故障。片上一共有两个看门狗设备:独立看门狗和窗口看门狗,它们提高了安全性、使时间更加精确以及使用变得更加灵活。
独立看门狗是由一个八位预分频器 IWDT_PSC、 12 位递减计数器、 12 位重装载寄存器 IWDT_CNTRLD、键寄存器 IWDT_KEY 和状态寄存器 IWDT_STS 组成。独立看门狗只有在计数器减到 0 时,会复位,在没有减到 0 之前,刷新计数器的值不会发生复位。独立看门狗有独立的时钟源,即使是在主时钟失效的情况下,它仍然有效。独立看门狗适用于需要独立的环境但对精确度要求不高的场所。参考程序如下所示:MultiTimer IWDT_MultiTimer;
/*!
* [url=home.php?mod=space&uid=247401]@brief[/url] IWDT MultiTimer callback
*
* @param None
*
* @retval None
*
*/
void IWDT_MultiTimerCallback(MultiTimer *timer, void *userData)
{
IWDT_Refresh();
MultiTimerStart(&IWDT_MultiTimer, 50, IWDT_MultiTimerCallback, "IWDT");
}
/*!
* [url=home.php?mod=space&uid=247401]@brief[/url] IWDG Init
*
* @param None
*
* @retval None
*
*/
void IWDT_Init(void)
{
IWDT_EnableWriteAccess();
IWDT_ConfigDivider(IWDT_DIVIDER_32);
IWDT_ConfigReload(300);
IWDT_Enable();
MultiTimerStart(&IWDT_MultiTimer, 50, IWDT_MultiTimerCallback, "IWDT");
}
窗口看门狗时钟来自 PCLK1,计数器时钟由 CK 计数器时钟经过预分频分频得到(由配置寄存器配置)。窗口看门狗含有一个 7 位自由运行递减计数器、预分频器、控制寄存器WWDT_CTRL、配置寄存器 WWDT_CFG 和状态寄存器 WWDT_STS。窗口看门狗在计数器减到 0x3F 时会发生复位,当计数器计数的值在配置寄存器的窗口值之前,刷新计数器也会发生复位。窗口看门狗适用于需要精确计时的场合。参考程序如下所示:(中断形式实现)
/*!
* @brief WWDT Init
*
* @param None
*
* @retval None
*
*/
void WWDT_Init(void)
{
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_WWDT);
WWDT_ConfigTimebase(WWDT_TIME_BASE_8);
WWDT_ConfigWindowData(80);
WWDT_Enable(127);
WWDT_ClearFlag();
NVIC_EnableIRQRequest(WWDT_IRQn, 0, 0);
WWDT_EnableEWI();
}
参考main主程序,对上电复位的复位源进行监控,并打印出当前系统运行的相关时钟频率:
/*!
* @brief Main program
*
* @param None
*
* @retval None
*
*/
int main(void)
{
uint32_t PCLK1, PCLK2;
MultiTimerInstall(SysTick_GetTick);
SysTick_Config(SystemCoreClock / 1000);
USART_Init(115200);
if (SET == RCM_ReadStatusFlag(RCM_FLAG_IWDTRST))
{
printf("\r\nIWDT RST");
RCM_ClearStatusFlag();
}
else if (SET == RCM_ReadStatusFlag(RCM_FLAG_WWDTRST))
{
printf("\r\nWWDT RST");
RCM_ClearStatusFlag();
}
else
{
}
printf("\r\nAPM32F107VC MINIBOARD V1.0 %s %s\r\n", __DATE__, __TIME__);
printf("\r\nSYSCLK : %dHz", RCM_ReadSYSCLKFreq());
printf("\r\nHCLK : %dHz", RCM_ReadHCLKFreq());
RCM_ReadPCLKFreq(&PCLK1, &PCLK2);
printf("\r\nPCLK1 : %dHz", PCLK1);
printf("\r\nPCLK2 : %dHz", PCLK2);
printf("\r\nADCCLK : %dHz", RCM_ReadADCCLKFreq());
ADC_Init();
DAC_Init();
IWDT_Init();
KEY_Init();
LED_Init();
WWDT_Init();
while (1)
{
MultiTimerYield();
}
}
运行日志:
软件工程源代码:
Project_IWDT_WWDT.zip
(488.68 KB)
|