32单片机——独立看门狗
1、IWDG的简介
IWDG:Independent watchdog,即独立看门狗
独立看门狗本质上是一个定时器,该定时器是一个12位的递减计数器,当计数器的值减到0的时候,就会产生一个复位信号
如果在计数没减到0之前,重置计数器的值的话,那么就不会产生复位信号,这个动作我们称为喂狗
(1)本质:能产生系统复位信号的计数器
(2)特性:12位的递减的计数器,时钟由独立的RC振荡器提供(可在待机和停止模式下运行),看门狗被激活后,当递减计数器计数到0x000时产生复位
(3)喂狗:在计数器计数到0之前,重装载计数器的值,防止复位
(4)作用:主要用于检测外界电磁干扰或硬件异常导致的程序跑飞问题,即检测异常
什么是异常?
外界电磁干扰或者自身系统(硬件或软件)异常,造成程序跑飞,如:陷入某个不正常的死循环,打断正常的程序运行
(5)应用:在一些需要高稳定性的产品中,并且对时间精度要求较低的场合
2、IWDG框图
简图如下所示:
3、IWDG溢出时间计算
:看门狗溢出时间
:看门狗的时钟源频率(30~60Khz),一般以40Khz来计算
prer:IWDG_PR的值(000~111)
rlr:看门狗重装载值(0~4095)
4、IWDG的配置步骤
(1)取消PR/RLR寄存器写保护,设置IWDG,预分频系数和重装载值,启动IWDG
HAL_IWDG_Init();
(2)及时喂狗,即写入0xAAAA到IWDG_KR
HAL_IWDG_Refresh();
IWDG配置:
IWDG_HandleTypeDef iwdg_handle; //iwdg句柄
//初始化iwdg
void iwdg_init(uint8_t psc,uint16_t alr){
iwdg_handle.Instance=IWDG; //寄存器基地址
iwdg_handle.Init.Prescaler=psc; //预分频系数
iwdg_handle.Init.Reload=alr; //重装载值
HAL_IWDG_Init(&iwdg_handle); //取消写保护
}//喂狗
void iwdg_refresh(void){
HAL_IWDG_Refresh(&iwdg_handle);
}
HAL_IWDG_Init
功能:使能IWDG,设置预分频系数和重装载值等
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
typedef struct{
IWDG_TypeDef *Instance; /* 寄存器基地址 */IWDG_InitTypeDef Init; /* IWDG必需参数 */
} IWDG_HandleTypeDef;
typedef struct{
uint32_t Prescaler; /* 预分频系数 */uint32_t Reload; /* 重装载值(0~0x0FFF) */
} IWDG_InitTypeDef;
Prescaler预分频系数如下所示:
#define IWDG_PRESCALER_4 0x00000000U /* 4 */
#define IWDG_PRESCALER_8 IWDG_PR_PR_0 /* 8 */
#define IWDG_PRESCALER_16 IWDG_PR_PR_1 /* 16 */
#define IWDG_PRESCALER_32 (IWDG_PR_PR_1 | IWDG_PR_PR_0) /* 32 */
#define IWDG_PRESCALER_64 IWDG_PR_PR_2 /* 64 */
#define IWDG_PRESCALER_128 (IWDG_PR_PR_2 | IWDG_PR_PR_0) /* 128 */
#define IWDG_PRESCALER_256 (IWDG_PR_PR_2 | IWDG_PR_PR_1) /* 256 */
HAL_IWDG_Refresh
功能:把重装载寄存器的值重载到计数器中,喂狗
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
5、实现喂狗操作
int main(void){
uint8_t key;
HAL_Init();
sys_stm32_clock_init(RCC_PLL_MUL9); //设置系统时钟
delay_init(72);
led_init();
beep_init();
key_init();
usart_init(115200); //串口
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);
iwdg_init(IWDG_PRESCALER_64,625); //初始化iwdg 设置预分频系数64 重装值625 溢出时间1s
while (1){
key=scan(0);
if(key==4){ //当按下KEY_UP键时喂狗
iwdg_refresh();
}
}
}