STM32H743-ARM例程10-WWDG
目录
- 实验平台
- 实验介绍
- WWDG
- WWDG框图
- WWDG寄存器
- 控制寄存器(WWDG_CR
- 配置寄存器 (WWDG_CFR)
- 状态寄存器 (WWDG_SR)
- # STM32CubeMX生成工程
- 实验代码
- 实验现象
实验平台
硬件:银杏科技GT7000双核心开发板-ARM-STM32H743XIH6,银杏科技iToolXE仿真器
软件:最新版本STM32CubeH7固件库,STM32CubeMX v6.10.0,开发板环境MDK v5.35,串口工具putty
实验介绍
本章实验我们将通过串口发送"test"指令,当没有输入“test”时正常喂狗,计数不断增加;当输入“test”后停止喂狗,计数重置从0开始。
WWDG
数字列表项目IWDG看门狗存在这样一个问题,如果在喂狗的间隔期间,程序跑飞后又正确归位,独立看门狗无法发现这样的错误,程序将存在很大的危险。与IWDG看门狗不同,窗口看门狗(WWDG)看门狗需要在一个规定的时间范围内喂狗才有效,这样可以较为有效的解决IWDG看门狗存在的问题。可以根据WWDG看门狗通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。
窗口看门狗(WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位(WWDG→CR的第六位)变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口配置寄存器(WWDG→CFR)数值之前,如果7位的递减计数器数值(在控制寄存器中)被刷新,那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。他们的关系可以用下图说明。
图中,T[6:0]就是WWDG_CR的低七位,W[6:0]即是WWDG→CFR的低七位。T[6:0]就是窗口看门狗的计数器,而W[6:0]则是窗口看门狗的上窗口,下窗口值是固定的(0X40)。当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。上窗口值(W[6:0])是由用户自己设定的,根据实际要求来设计窗口值,但是一定要确保窗口值大于0X40,否则窗口就不存在了。
窗口看门狗的超时公式如下:
其中:
TWWDG:WWDG 超时时间
PCLK1:PCLK1 的时钟频
WDGTB:WWDG 的预分频系数
T[5:0]:窗口看门狗的计数器低 6 位
WWDG框图
WWDG有一个输入(时钟pclk),经过一个除4096的分频器,再经过一个分频系数可选(1、2、4、8…128)的可编程预分频器提供时钟给一个7位递减计数器,这里有两个输出信号。具体如下表:
WWDG寄存器
控制寄存器(WWDG_CR
位 31:8保留,必须保持复位值。 位7 WDGA:激活位 (Activation bit)
此位由软件置 1,只有复位后才由硬件清零。当 WDGA = 1 时,看门狗可产生复位。
普通列表项目0:禁止看门狗
普通列表项目1:使能看门狗
位 6:0 T[6:0]:7位计数器 (7-bit counter)(MSB到LSB)
这些位用来存储看门狗计数器的值,每隔 (4096 x 2WDGTB[2:0]) PCLK个周期递减一次。当它从0x40递减到 0x3F(T6清零)时会产生复位。
配置寄存器 (WWDG_CFR)
位 31:14 保留,必须保持复位值。
位 13:11 WDGTB[2:0]: 定时器时基 (Timer base) 可按如下方式修改预分频器的时基:
000: CK 计数器时钟 (PCLK div 4096) 分频器 1
001: CK 计数器时钟 (PCLK div 4096) 分频器 2
010: CK 计数器时钟 (PCLK div 4096) 分频器 4
011: CK 计数器时钟 (PCLK div 4096) 分频器 8
100: CK 计数器时钟 (PCLK div 4096) 分频器 16
101: CK 计数器时钟 (PCLK div 4096) 分频器 32
110: CK 计数器时钟 (PCLK div 4096) 分频器 64
111: CK 计数器时钟 (PCLK div 4096) 分频器 128
位 10 保留,必须保持复位值。
位 9 EWI: 提前唤醒中断 (Early wakeup interrupt)
置 1 后,只要计数器值达到 0x40 就会产生中断。此中断只有在复位后才由硬件清零。
位 8:7 保留,必须保持复位值。
位 6:0 W[6:0]: 7 位窗口值 (7-bit window value)
这些位包含用于与递减计数器进行比较的窗口值。
状态寄存器 (WWDG_SR)
位 31:1 保留,必须保持复位值。
位 0 EWIF: 提前唤醒中断标志 (Early wakeup interrupt flag)
当计数器值达到 0x40 时此位由硬件置 1。它必须由软件通过写入 0 来清零。写入 1 不起作用。如果不使能中断,此位也会被置 1。
# STM32CubeMX生成工程
我们参考前面章节STM32H743-结合CubeMX新建HAL库MDK工程,打开CubeMX软件,重复步骤不再展示,我们来看配置WWDG部分如下图所示:
实验代码
1. 主函数
int main(void)
{char buffer[UART_BUFFER_SIZE];int i;int n=0;int cnt = 0;MPU_Config();HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART6_UART_Init();MX_WWDG1_Init();uart6.initialize(115200);uart6.printf(". 输入 test 并敲回车进行测试 .\r\n");while (1){if(uart6.receive_ok_flag == 1){uart6.receive_ok_flag = 0;memset(buffer,0,20);memcpy(buffer,uart6.receive_buffer,20);for(i = 0;i < 20;i ++){buffer[i] = tolower(buffer[i]);}if(memcmp(buffer,"test",strlen("test")) == 0){n=1;}else{uart6.printf("\r\n\033[1;31;40mBad Command!\r\n");} }while(n==1){}HAL_Delay(30); //30ms喂狗一次HAL_WWDG_Refresh(&hwwdg1); //喂狗 uart6.printf(". 输入 test 并敲回车进行测试 %d .\r\n",cnt++);}
}
2. 窗口看门狗初始化函数
void MX_WWDG1_Init(void)
{hwwdg1.Instance = WWDG1;hwwdg1.Init.Prescaler = WWDG_PRESCALER_16; //开门狗预分频系数为16hwwdg1.Init.Window = 100; //上限窗口值为100hwwdg1.Init.Counter = 127; //计数器的值为127hwwdg1.Init.EWIMode = WWDG_EWI_ENABLE; //打开提前唤醒if (HAL_WWDG_Init(&hwwdg1) != HAL_OK){Error_Handler();}
}
WWDG配置:
counter:递减减计时器的值,取值范围为:0x7F ~ 0x40
window:窗口值,取值范围为:0x7F ~ 0x40
prescaler:预分频系数
本实验中,GT7000的PCKL1为120Mhz,取WWDG_PRESCALER_16,那么WWDG counter clock = (PCLK1(120MHz)/4096)/16约1831Hz,即546𝜇𝑠。
窗口时间为546 * (127-100) = 14.7ms < 刷新窗口 < 546 * 64 = 34.9ms
也就是说在WWDG被调用后计时开始,在14.7ms前喂狗,系统会复位,在34.9ms后没有喂狗,系统也会复位。需要在刷新窗口的时间内喂狗,系统才不会复位。
3. 喂狗函数
HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg)
4. 看门狗中断处理函数:
HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg)
功能:判断中断是否正常,并进入中断回调函数。
WWDG中断服务程序,如果发生了此中断,表示程序已经出现了故障,这是一个死前中断。在此中断服务程序中应该干最重要的事,比如保存重要的数据等。
5. 提前唤醒中断服务函数:
HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg)
用户可写入代码,在MCU死前,执行重要操作。
实验现象
在没有按输入“test”时,终端输入文本,并且数值不断增大, 当输入“test”,ARM复位,
数值从0开始重新输出。