1)实验平台:正点原子stm32f103战舰开发板V4
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html#
本章介绍APM32F407独立看门狗(IWDT)的使用,独立看门狗能够帮助CPU在进入错误状态或程序跑飞时进行复位。通过本章的学习,读者将学习到IWDT的使用。
本章分为如下几个小节:
14.1 硬件设计
14.2 程序设计
14.3 下载验证
14.1 硬件设计
14.1.1 例程功能
表14.2.1.1 函数IWDT_Enable()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
无 无
表14.2.1.2 函数IWDT_Enable()返回值描述
该函数的使用示例,如下所示:
#include "apm32f4xx.h"
#include "apm32f4xx_iwdt.h"
void example_fun(void)
{
/* 使能IWDT */
IWDT_Enable();
}
②:使能访问IWDT相关寄存器
该函数用于使能访问IWDT相关寄存器,只有使能访问了IWDT相关的寄存器,才能配置其预分频系数和重装载值,其函数原型如下所示:
void IWDT_EnableWriteAccess(void);
该函数的形参描述,如下表所示:
形参 描述
无 无
表14.2.1.3 函数IWDT_EnableWriteAccess()形参描述
该函数的返回值描述,如下表所示:
表14.2.1.4 函数IWDT_EnableWriteAccess()返回值描述
该函数的使用示例,如下所示:
#include "apm32f4xx.h"
#include "apm32f4xx_iwdt.h"
void example_fun(void)
{
/* 使能访问IWDT相关寄存器 */
IWDT_EnableWriteAccess();
}
③:配置IWDT预分频系数
该函数用于配置IWDT的预分频系数,预分频系数决定了IWDT计数的频率,其函数原型如下所示:
void IWDT_ConfigDivider(uint8_t div);
该函数的形参描述,如下表所示:
形参 描述
div IWDT的预分频系数
例如:IWDT_DIVIDER_4、IWDT_DIVIDER_8等(在apm32f4xx_iwdt.h文件中有定义)
表14.2.1.5 函数IWDT_ConfigDivider()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
无 无
表14.2.1.6 函数IWDT_ConfigDivider()返回值描述
该函数的使用示例,如下所示:
#include "apm32f4xx.h"
#include "apm32f4xx_iwdt.h"
void example_fun(void)
{
/* 配置IWDT的预分频系数为32 */
IWDT_ConfigDivider(IWDT_DIVIDER_32);
}
④:配置IWDT的重装载值
该函数用于配置IWDT的重装载值,重装载值用于决定IWDT从“喂狗”到溢出时计数的个数,其函数原型如下所示:
void IWDT_ConfigReload(uint16_t reload);
该函数的形参描述,如下表所示:
表14.2.1.7 函数IWDT_ConfigReload()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
无 无
表14.2.1.8 函数IWDT_ConfigReload()返回值描述
该函数的使用示例,如下所示:
#include "apm32f4xx.h"
#include "apm32f4xx_iwdt.h"
void example_fun(void)
{
/* 配置IWDT的重装载值为875 */
IWDT_ConfigReload(875);
}
⑤:重装载IWDT
该函数用于重装载IWDT,也就是所谓的“喂狗”,其函数原型如下所示:
void IWDT_Refresh(void);
该函数的形参描述,如下表所示:
形参 描述
无 无
表14.2.1.9 函数IWDT_Refresh()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
无 无
表14.2.1.10 函数IWDT_Refresh()返回值描述
该函数的使用示例,如下所示:
#include "apm32f4xx.h"
#include "apm32f4xx_iwdt.h"
void example_fun(void)
{
/* 重装载IWDT(喂狗) */
IWDT_Refresh();
}
14.2.2 看门狗驱动
本章实验的看门狗驱动主要负责向应用层提供IWDT初始化和喂狗的操作函数,本章实验中,看门狗的驱动代码包括wdt.c和wdt.h两个文件。
看门狗驱动中,IWDT的初始化函数,如下所示:
/**
* @brief 独立看门狗初始化
* @param prer: 独立看门狗定时器预分频系数,
* IWDT_DIVIDER_4~IWDT_DIVIDER_256对应预分频系数为4~256
* @param rlr : 自动重装载值,范围:0~0xFFF
* @note 时间计算(大概):Tout=((4 * 2^prer) * rlr) / 28 (ms)
* 28数值来自独立看门狗时钟源LSICLK的频率
* @retval 无
*/
void iwdt_init(uint8_t prer, uint32_t rlr)
{
IWDT_Enable(); /* 启动独立看门狗 */
IWDT_EnableWriteAccess(); /* 使能访问独立看门狗相关寄存器 */
IWDT_ConfigDivider(prer); /* 配置预分频系数 */
IWDT_ConfigReload(rlr); /* 配置重装载值 */
IWDT_Refresh(); /* 重装载独立看门狗计数器 */
}
IWDT的初始化函数中使能了IWDT并配置其预分频系数和重装载值,并进行了一次“喂狗”防止IWDT一使能就溢出引发复位。
看门狗驱动中,IWDT的“喂狗”函数,如下所示:
/**
* @brief 喂独立看门狗
* @param 无
* @retval 无
*/
void iwdt_feed(void)
{
IWDT_Refresh(); /* 重装载独立看门狗计数器 */
}
该函数很简单,就是重装载IWDT的计数值。
14.2.3 实验应用代码
本章实验的应用代码,如下所示:
int main(void)
{
NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_3); /* 设置中断优先级分组为组3 */
sys_apm32_clock_init(336, 8, 2, 7); /* 配置系统时钟 */
delay_init(168); /* 初始化延时功能 */
usart_init(115200); /* 初始化串口 */
led_init(); /* 初始化LED */
key_init(); /* 初始化按键 */
delay_ms(100);
iwdt_init(IWDT_DIVIDER_32, 875); /* 独立看门狗初始化,溢出时间为1秒 */
LED0(0);
while (1)
{
if (key_scan(0) == WKUP_PRES)
{
iwdt_feed();
}
delay_ms(10);
}
}
可以看到应用代码中,LED初始化后,LED0会处于默认的熄灭状态100毫秒,随后初始化IWDT并点亮LED0,接着在while循环中重复判断KEY_UP按键是否被按下,若按下则进行“喂狗”操作,若在IWDT溢出前都为按下KEY_UP按键,则IWDT会触发复位,复位会导致LED0熄灭大约100毫秒(便于观察)。
14.3 下载验证
在完成编译和烧录操作后,可以看到板子上的LED0每间隔一段时间(大约1秒)就闪烁一次,这是因为IWDT不断地溢出,导致的复位。接下来若以时间间隔小于1秒(大约)的速度频繁地按下KEY_UP按键,则可以在IWDT溢出前及时“喂狗”,具体的现象为LED0不再闪烁。