这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 后一修订版 两侧同时换到之后的修订记录 | ||
icore3l_9 [2020/11/06 16:26] zgf |
icore3l_9 [2020/11/06 17:25] zgf |
||
---|---|---|---|
行 29: | 行 29: | ||
9.时钟源设置,选择外部高速时钟源,配置为最大主频 | 9.时钟源设置,选择外部高速时钟源,配置为最大主频 | ||
{{ :icore3l:icore3l_cube_9_12.png |}} | {{ :icore3l:icore3l_cube_9_12.png |}} | ||
- | 10.工程文件的设置, 这里就是工程的各种配置 我们只用到有限几个,其他的默认即可,IDE我们使用的是 MDK V5.27 | + | 10.工程文件的设置, 这里就是工程的各种配置 我们只用到有限几个,其他的默认即可,IDE我们使用的是 MDK V5.27 |
{{ :icore3l:icore3l_cube_9_13.png |}} | {{ :icore3l:icore3l_cube_9_13.png |}} | ||
11.点击Code Generator,进行进一步配置 | 11.点击Code Generator,进行进一步配置 | ||
行 52: | 行 52: | ||
\\ | \\ | ||
\\ | \\ | ||
+ | ===== 实验九:WWDG看门狗实验——复位ARM ===== | ||
+ | ==== 一、实验目的与意义 ==== | ||
+ | - 了解STM32 WWDG结构 | ||
+ | - 了解STM32 WWDG特征 | ||
+ | - 掌握WWDG的使用方法 | ||
+ | - 掌握STM32 HAL库中WWDG属性的配置方法 | ||
+ | - 掌握KEIL MDK 集成开发环境使用方法 | ||
+ | ==== 二、实验设备及平台 ==== | ||
+ | * iCore3L 双核心板 | ||
+ | * iCore3L 扩展底板 | ||
+ | * JLINK(或相同功能)仿真器 | ||
+ | * Micro USB线缆 | ||
+ | * Keil MDK 开发平台 | ||
+ | * STM32CubeMX开发平台 | ||
+ | * 装有WIN XP(及更高版本)系统的计算机 | ||
+ | ==== 三、实验原理 ==== | ||
+ | === 1.窗口看门狗WWDG简介 === | ||
+ | * IWDG看门狗存在这样一个问题,如果在喂狗的间隔期间,程序跑飞后又正确归位,独立看门狗无法发现这样的错误,程序将存在很大的危险。与IWDG看门狗不同,WWDG看门狗需要在一个规定的时间范围内喂狗才有效,这样可以较为有效的解决IWDG看门狗存在的问题。可以根据WWDG看门狗通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。 | ||
+ | * WWDG通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位(WWDG->CR的第六位)变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口配置寄存器(WWDG->CFR)数值之前,如果7位的递减计数器数值(在控制寄存器中)被刷新,那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。他们的关系可以用下图说明 | ||
+ | {{ :icore3l:icore3l_arm_hal_9_1.png |}} | ||
+ | * 图中,T[6:0]就是WWDG_CR的低七位,W[6:0]即是WWDG->CFR的低七位。T[6:0]就是窗口看门狗的计数器,而W[6:0]则是窗口看门狗的上窗口,下窗口值是固定的(0X40)。当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。上窗口值(W[6:0])是由用户自己设定的,根据实际要求来设计窗口值,但是一定要确保窗口值大于0X40,否则窗口就不存在了。 | ||
+ | 窗口看门狗的超时公式如下: | ||
+ | {{ :icore3l:icore3l_arm_hal_9_6.png |}} | ||
+ | 其中: | ||
+ | * Twwdg:WWDG 超时时间 | ||
+ | * PCLK1:PCLK1 的时钟频 | ||
+ | * WDGTB:WWDG 的预分频系数 | ||
+ | * T[5:0]:窗口看门狗的计数器低 6 位 | ||
+ | === 2.WWDG框图 === | ||
+ | {{ :icore3l:icore3l_arm_hal_9_2.png |}} | ||
+ | === 3.WWDG寄存器 === | ||
+ | |||
+ | 控制寄存器( WWDG_CR) | ||
+ | {{ :icore3l:icore3l_arm_hal_9_3.png |}} | ||
+ | 位 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) | ||
+ | {{ :icore3l:icore3l_arm_hal_9_4.png |}} | ||
+ | 位 31:13 保留,必须保持复位值。 | ||
+ | 位 12:11 WDGTB[1: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 | ||
+ | 位 10 保留,必须保持复位值。 | ||
+ | 位 9 EWI: 提前唤醒中断 (Early wakeup interrupt) | ||
+ | * 置 1 后,只要计数器值达到 0x40 就会产生中断。此中断只有在复位后才由硬件清零。 | ||
+ | 位 8:7 保留,必须保持复位值。 | ||
+ | 位 6:0 W[6:0]: 7 位窗口值 (7-bit window value) | ||
+ | * 这些位包含用于与递减计数器进行比较的窗口值。 | ||
+ | |||
+ | 状态寄存器 (WWDG_SR) | ||
+ | {{ :icore3l:icore3l_arm_hal_9_5.png |}} | ||
+ | 位 31:1 保留,必须保持复位值。 | ||
+ | 位 0 EWIF: 提前唤醒中断标志 (Early wakeup interrupt flag) | ||
+ | |||
+ | 当计数器值达到 0x40 时此位由硬件置 1。它必须由软件通过写入 0 来清零。写入 1 不起作用。如果不使能中断,此位也会被置 1。 | ||
+ | |||
+ | 本实验中iCore3L使用的是常开带复位按键,当按键没有按下时,ARM芯片的ARM_KEY引脚读取到的值是高电平,按键按下后读取到的值为低电平,按键没有按下时正常喂狗,当按键按下后停止喂狗。 | ||
+ | ==== 四、实验程序 ==== | ||
+ | === 1.主函数 === | ||
+ | <code c> | ||
+ | int main(void) | ||
+ | { | ||
+ | HAL_Init(); | ||
+ | SystemClock_Config(); | ||
+ | HAL_Delay(300); | ||
+ | MX_GPIO_Init(); | ||
+ | MX_WWDG_Init(); | ||
+ | LED_RED_ON; //初始化LED状态,红灯亮 | ||
+ | while (1) | ||
+ | { | ||
+ | while(ARM_KEY_VALUE == KEY_DOWN){ //按键没按下则正常喂狗 | ||
+ | } | ||
+ | HAL_Delay(30); //30ms喂一次狗,19.6ms<喂狗时间<46.5ms | ||
+ | HAL_WWDG_Refresh(&hwwdg); //喂狗 | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | === 2.窗口看门狗初始化函数: === | ||
+ | <code c> | ||
+ | void MX_WWDG1_Init(void) | ||
+ | { | ||
+ | hwwdg1.Instance = WWDG; | ||
+ | hwwdg1.Init.Prescaler = WWDG_PRESCALER_8;//窗口看门狗预分频系数为8 | ||
+ | hwwdg1.Init.Window = 100;//上限窗口值为100 | ||
+ | hwwdg1.Init.Counter = 127;//计数器的值为127 | ||
+ | hwwdg1.Init.EWIMode = WWDG_EWI_ENABLE;//打开提前唤醒 | ||
+ | if (HAL_WWDG_Init(&hwwdg) != HAL_OK) | ||
+ | { | ||
+ | Error_Handler(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | WWDG配置: | ||
+ | * counter:递减减计时器的值, 取值范围为:0x7F ~ 0x40 | ||
+ | * window:窗口值,取值范围为: 0x7F ~ 0x40 | ||
+ | * prescaler:预分频系数 | ||
+ | * 本实验中,iCore3L的PCLK1为45Mhz,取WWDG_PRESCALER_8,那么WWDG counter clock = (PCLK1(45MHz)/4096)/8约1373Hz,即728。 | ||
+ | * 窗口时间为 728 * (127-100) = 19.6ms < 刷新窗口 < 273 * 64 = 46.5ms | ||
+ | * 也就是说在WWDG被调用后计时开始,在19.6ms前喂狗,系统会复位,在46.5ms后没有喂狗,系统也会复位。需要在刷新窗口的时间内喂狗,系统才不会复位。 | ||
+ | 喂狗函数: | ||
+ | <code c> | ||
+ | HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg) | ||
+ | </code> | ||
+ | === 3.看门狗中断处理函数: === | ||
+ | <code c> | ||
+ | HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg) | ||
+ | </code> | ||
+ | * 功能:判断中断是否正常,并进入中断回调函数。 | ||
+ | * WWDG 中断服务程序,如果发生了此中断,表示程序已经出现了故障,这是一个死前中断。在此中断服务程序中应该干最重要的事,比如保存重要的数据等 | ||
+ | === 4.提前唤醒中断服务函数: === | ||
+ | <code c> | ||
+ | HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg) | ||
+ | </code> | ||
+ | 用户可写入代码,在MCU死前,执行重要操作 | ||
+ | === 五、实验步骤 === | ||
+ | - 把仿真器与iCore3L的SWD调试口相连(直接相连或者通过转接器相连); | ||
+ | - 把iCore3L通过Micro USB线与计算机相连,为iCore3L供电; | ||
+ | - 打开Keil MDK 开发环境,并打开本实验工程; | ||
+ | - 烧写程序到iCore3L上; | ||
+ | - 也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。 | ||
+ | === 六、实验现象 === | ||
+ | 在没有按下ARM_KEY按键时,红灯点亮,当一直按下ARM_KEY按键,ARM不断复位,红灯闪烁。 |