| **银杏科技有限公司旗下技术文档发布平台** |||| |技术支持电话|**0379-69926675-801**||| |技术支持邮件|Gingko@vip.163.com||| ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | V1.0 | 2020-07-04 | gingko | 初次建立 | ===== 实验七:WWDG看门狗实验——复位ARM ===== ==== 一、 实验目的与意义 ==== - 了解STM32 WWDG结构。 - 了解STM32 WWDG特征。 - 掌握WWDG的使用方法。 - 掌握STM32 HAL库中WWDG属性的配置方法。 - 掌握KEIL MDK 集成开发环境使用方法。 ==== 二、 实验设备及平台 ==== - iCore4 双核心板[[https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22598974120.15.5923532fsFrHiE&id=551864196684|点击购买]]。 - JLINK(或相同功能)仿真器[[https://item.taobao.com/item.htm?id=554869837940|点击购买]]。 - Micro USB线缆。 - Keil MDK 开发平台。 - STM32CubeMX开发平台。 - 装有WIN XP(及更高版本)系统的计算机。 ==== 三、 实验原理 ==== === 1、WWDG看门狗简介 === * IWDG看门狗存在这样一个问题,如果在喂狗的间隔期间,程序跑飞后又正确归位,独立看门狗无法发现这样的错误,程序将存在很大的危险。与IWDG看门狗不同,WWDG看门狗需要在一个规定的时间范围内喂狗才有效,这样可以较为有效的解决IWDG看门狗存在的问题。窗口看门狗(WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位(WWDG->CR的第六位)变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口配置寄存器(WWDG->CFR)数值之前,如果7位的递减计数器数值(在控制寄存器中)被刷新,那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。他们的关系可以用下图来说明: {{ :icore4:icore4_arm_hal_7_1.png?direct |}} * 图中,T[6:0]就是WWDG_CR的低七位,W[6:0]即是WWDG->CFR的低七位。T[6:0]就是窗口看门狗的计数器,而W[6:0]则是窗口看门狗的上窗口,下窗口值是固定的(0X40)。当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。 * 上窗口值(W[6:0])是由用户自己设定的,根据实际要求来设计窗口值,但是一定要确保窗口值大于0X40,否则窗口就不存在了。 * 窗口看门狗的超时公式如下: * **Twwdg=(4096× 2^WDGTB× (T[5:0]+1)) /Fpclk1;** * 其中: * Twwdg:WWDG 超时时间(单位为 ms) * Fpclk1:APB1 的时钟频率(单位为 Khz) * WDGTB: WWDG 的预分频系数 * T[5:0]:窗口看门狗的计数器低6位 === 2、WWDG主要特性 === * (1)可编程的自由运行递减计数器 * (2)复位条件 * 当递减计数器值小于0x40时复位(如果看门狗已激活) * 在窗口之外重载递减计数器时复位(如果看门狗已激活) * (3)提前唤醒中断 (EWI):当递减计数器等于0x40时触发(如果已使能且看门狗已激活) === 3、WWDG功能说明 === * 如果激活看门狗(WWDG_CR寄存器中的WDGA位置1),则当7位递减计数器(T[6:0]位)从0x40滚动到0x3F(T6已清零)时会引发复位。当计数器值大于窗口寄存器中所存储的值时,如果软件重载计数器,则会产生复位。看门狗框图如下: {{ :icore4:icore4_arm_hal_7_2.png?direct |}} * 应用程序在正常运行过程中必须定期地写入WWDG_CR寄存器以防止MCU发生复位。只有当计数器值低于窗口寄存器值时,才能执行此操作。存储在WWDG_CR寄存器中的值必须介于0xFF和0xC0之间。 === 4、WWDG寄存器 === * (1)控制寄存器(WWDG_CR) * 该寄存器的各位描述如图所示: {{ :icore4:icore4_arm_hal_7_3.png?direct |}} * 可以看出,这里我们的WWDG_CR只有低八位有效,T[6:0]用来存储看门狗的计数器值,随时更新的,每个窗口看门狗计数周期(4096×2^WDGTB)减1。当该计数器的值从0X40变为0X3F的时候,将产生看门狗复位。 * WDGA位则是看门狗的激活位,该位由软件置1,以启动看门狗,并且一定要注意的是该位一旦设置,就只能在硬件复位后才能清零了。 * (2)配置寄存器(WWDG_CFR) * 该寄存器的各位及其描述如图所示: {{ :icore4:icore4_arm_hal_7_4.png?direct |}} * 该位中的EWI是提前唤醒中断,也就是在快要产生复位的前一段时(T[6:0]=0X40)来提醒我们,需要进行喂狗了,否则将复位!因此,我们一般用该位来设置中断,当窗口看门狗的计数器值减到0X40的时候,如果该位设置,并开启了中断,则会产生中断,我们可以在中断里面向WWDG_CR重新写入计数器的值,来达到喂狗的目的。注意这里在进入中断后,必须在不大于1个窗口看门狗计数周期的时间(在PCLK1频率为54M且WDGTB为0的条件下,该时间为75.85us)内重新写WWDG_CR,否则,看门狗将产生复位。 * (3)状态寄存器(WWDG_SR) {{ :icore4:icore4_arm_hal_7_5.png?direct |}} * 该寄存器用来记录当前是否有提前唤醒的标志。该寄存器仅有位0有效,其他都是保留位。当计数器值达到40h时,此位由硬件置1。它必须通过软件写0来清除。对此位写1无效。即使中断未被使能,在计数器的值达到0X40的时候,此位也会被置1。 * 本次实验使用的是常开带复位按键,当按键没有按下时,ARM芯片的ARM_KEY引脚读取到的值是高电平,按键按下后读取到的值为低电平,按键没有按下是正常喂狗,当按键按下后停止喂狗,从而产生复位。 ==== 四、 实验程序 ==== === 1、主函数 === int main(void) { /* MCU 配置*/ /* 重置所有外围设备,初始化Flash接口和Systick */ HAL_Init(); /* 配置系统时钟 */ SystemClock_Config(); HAL_Delay(300); /* 初始化所有已配置的外围设备 */ MX_GPIO_Init(); MX_WWDG_Init(); LED_RED_ON; //初始化LED状态,红灯亮 /* 无限循环 */ while (1) { while(ARM_KEY_STATE == KEY_DOWN); HAL_Delay(30); //30ms喂狗一次 HAL_WWDG_Refresh(&hwwdg); //喂狗 } } === 2、WWDG初始化配置函数 === /* WWDG初始化函数 */ void MX_WWDG_Init(void) { hwwdg.Instance = WWDG; hwwdg.Init.Prescaler = WWDG_PRESCALER_8; //选择WWDG的预分频系数。 hwwdg.Init.Window = 100; //窗口值 hwwdg.Init.Counter = 127; //计数器值 hwwdg.Init.EWIMode = WWDG_EWI_DISABLE;//禁用提前唤醒中断 if (HAL_WWDG_Init(&hwwdg) != HAL_OK)//初始化WWDG { _Error_Handler(__FILE__, __LINE__); } } * HAL库中开启WWDG是通过宏定义标识符实现: #define __HAL_WWDG_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR, WWDG_CR_WDGA) * 这里需要说明一下的是,在调用函数 HAL_WWDG_Init之后,该函数会开启窗口看门狗,所以不需要再重复开启。 === 3、喂狗函数 === HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg) { /* 将WWDG计数器值写入WWDG CR以刷新 */ WRITE_REG(hwwdg->Instance->CR, (hwwdg->Init.Counter)); /* 返回函数状态 */ return HAL_OK; } === 4、WWDG中断服务函数 === void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg) { /* 检查是否启用了提前唤醒中断*/ if(__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET) { /* 检查是否发生了WWDG提前唤醒中断 */ if(__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET) { /* 清除WWDG提前唤醒标志 */ __HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF); /* 提前唤醒回调 */ HAL_WWDG_EarlyWakeupCallback(hwwdg); } } } * **功能:**判断中断是否正常,并进入中断回调函数。 * 在HAL库中,每进行完一个中断,并不会立刻退出,而是会进入到中断回调函数中,看门狗中断运行完成之后,便会进入看门狗的中断回调函数。 ==== 五、 实验步骤 ==== - 把仿真器与iCore4的SWD调试口相连(直接相连或者通过转接器相连); - 把iCore4通过Micro USB线与计算机相连,为iCore4供电; - 打开Keil MDK 开发环境,并打开本实验工程; - 烧写程序到iCore4上; - 也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。 ==== 六、 实验现象 ==== * iCore4 双核心板红色LED常亮,当按键一直按下,看门狗一直复位ARM,红灯闪烁。