独立看门狗 IWDG
一,独立看门狗
二,独立看门狗的时钟源
独立看门狗拥有自己的时钟源,不依赖PLL时钟输出的分频信号,能够独立运行,这样子的好处就是PLL假如受到干扰,
导致运行异常,独立的看门狗还能正常地进行工作,如果没有正常的喂狗动作,就复位CPU。
三、程序设计
1. 添加复位检测代码,有助于观察当前工作的可靠性
/* Check if the system has resumed from IWDG reset,检查当前复位是否有独立看门狗导致 */
if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
{
/* IWDGRST flag set */
printf("iwdt reset cpu\r\n"); /* Clear reset flags */
RCC_ClearFlag();
}
else
{
/* IWDGRST flag is not set */
printf("normal reset cpu\r\n"); }
2.
/* Enable write access to IWDG_PR and IWDG_RLR registers,独立看门狗是受到保护的,现在进行解锁动作 */
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); /* IWDG counter clock: LSI/256 ,设置看门狗的时钟 = 32KHz / 256 =125Hz */
IWDG_SetPrescaler(IWDG_Prescaler_256); /* 设置看门狗的超时时间,也就是设置它的计数值
当前看门狗的时钟为125Hz,然后设置超时时间为1秒,那么重载值为125
当前看门狗的时钟为125Hz,然后设置超时时间为2秒,那么重载值为250
*/
IWDG_SetReload(); /* Reload IWDG counter,重载独立看门狗的计数值,说白了就是喂狗 */
IWDG_ReloadCounter(); /* Enable IWDG (the LSI oscillator will be enabled by hardware),使能独立看门狗 */
IWDG_Enable();
3. 喂狗技巧
1.在裸机代码实现喂狗,放在定时器里面,因为定时器与看门狗是使用不同的时钟源,允许这么做!
2. 如果有实时的操作系统的加持,可以在任务里面添加喂狗动作,如果操作系统崩溃了,能够检测到软件的错误,触发CPU的复位。
在定时器中断服务函数当中,添加喂狗动作!
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_usart.h"
#include "stdio.h" static GPIO_InitTypeDef GPIO_InitStructure;
static USART_InitTypeDef USART_InitStructure;
static NVIC_InitTypeDef NVIC_InitStructure; void delay_us(uint32_t nus)
{
uint32_t temp;
SysTick->LOAD =SystemCoreClock//*nus; //时间加载
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //使能滴答定时器开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(<<))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
} void delay_ms(uint16_t nms)
{
uint32_t temp;
SysTick->LOAD=SystemCoreClock//*nms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //能滴答定时器开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(<<))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
} void LED_Init(void)
{ //使能GPIOE,GPIOF时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF, ENABLE); //GPIOF9,F10初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //LED0和LED1对应IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式,
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出,驱动LED需要电流驱动
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOF, &GPIO_InitStructure); //初始化GPIOF,把配置的数据写入寄存器 //GPIOE13,PE14初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; //LED2和LED3对应IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化GPIOE,把配置的数据写入寄存器 GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10); //GPIOF9,PF10设置高,灯灭
GPIO_SetBits(GPIOE,GPIO_Pin_13 | GPIO_Pin_14);
} void USART1_Init(uint32_t baud)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //使能USART1时钟 //串口1对应引脚复用映射
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1 //USART1端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10 //USART1 初始化设置
USART_InitStructure.USART_BaudRate = baud; //波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1 USART_Cmd(USART1, ENABLE); //使能串口1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启相关中断 //Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=; //抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
} //重定义fputc
int fputc(int ch,FILE *f)
{
USART_SendData(USART1,ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); return ch;
} void usart1_send_bytes(uint8_t *pbuf,uint32_t len)
{
while(len--)
{
USART_SendData(USART1,*pbuf++);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
} void usart1_send_str(char *pbuf)
{
while(pbuf && *pbuf)
{
USART_SendData(USART1,*pbuf++);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
} int main(void)
{ LED_Init(); //系统定时器初始化,时钟源来自HCLK,且进行8分频,
//系统定时器时钟频率=168MHz/8=21MHz
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //设置中断优先级分组2
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //串口1,波特率115200bps,开启接收中断
USART1_Init(); /* Check if the system has resumed from IWDG reset,检查当前复位是否有独立看门狗导致 */
if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
{
/* IWDGRST flag set */
printf("iwdt reset cpu\r\n"); /* Clear reset flags */
RCC_ClearFlag();
}
else
{
/* IWDGRST flag is not set */
printf("normal reset cpu\r\n"); } /* Enable write access to IWDG_PR and IWDG_RLR registers,独立看门狗是受到保护的,现在进行解锁动作 */
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); /* IWDG counter clock: LSI/256 ,设置看门狗的时钟 = 32KHz / 256 =125Hz */
IWDG_SetPrescaler(IWDG_Prescaler_256); /* 设置看门狗的超时时间,也就是设置它的计数值
当前看门狗的时钟为125Hz,然后设置超时时间为1秒,那么重载值为125
当前看门狗的时钟为125Hz,然后设置超时时间为2秒,那么重载值为250
*/
IWDG_SetReload(); /* Reload IWDG counter,重载独立看门狗的计数值,说白了就是喂狗 */
IWDG_ReloadCounter(); /* Enable IWDG (the LSI oscillator will be enabled by hardware),使能独立看门狗 */
IWDG_Enable(); while()
{ //重载计数值,就是喂狗,就是不让计数值变为0
IWDG_ReloadCounter(); }
} void USART1_IRQHandler(void) //串口1中断服务程序
{
uint8_t d; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
//接收数据
d = USART_ReceiveData(USART1); //发送数据
usart1_send_bytes(&d,); } }
---恢复内容结束---
独立看门狗 IWDG的更多相关文章
- stm32 独立看门狗 IWDG
独立看门狗IWDG 独立看门狗简单理解就是一个12位递减计数器,当计数器从某一个值递减到0时,系统就会产生一次复位 独立看门狗由专用低速时钟LSI驱动,其频率一般在30-60KHz之间,通常选择40K ...
- (stm32f103学习总结)—独立看门狗(IWDG)
一.IWDG介绍 1.1 IWDG简介 STM32F1芯片内部含有两个看门狗外设,一个是独立看门狗IWDG,另 一个是窗口看门狗WWDG.两个看门狗外设(独立和窗口)均可用于检测 并解决由软件错误导致 ...
- STM32之独立看门狗(IWDG)与窗口看门狗(WWDG)总结
一.独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路 ...
- STM8L独立看门狗IWDG
简单扼要 void IWDG_Init(void)//初始化 { IWDG->KR = 0xcc;//启动IWDG IWDG->KR = 0x55;//解除PR及RLR的写保护 IWDG- ...
- stm32 独立看门狗学习
STM32F10xxx内置两个看门狗,提供了更高的安全性.时间的精确性和使用的灵活性.两个看门狗设备(独立看门狗和窗口看门狗)可用来检测和解决由软件错误引起的故障. 独立看门狗(IWDG)由专用的低速 ...
- STM32之------独立看门狗(IWDG)和窗体看门狗(WWDG)
一 前沿废语: 之前有很风靡的游戏,名字叫<看门狗>.该游戏用了很新的引擎技术,打造出了一个辽阔庞大的世界,内容是玩家Aiden·Pearce(主角)是一名精通黑客技术的高手,当时 ...
- IWDG—独立看门狗
本章参考资料:<STM32F4XX 中文参考手册> IWDG 章节.学习本章时,配合<STM32F4XX 中文参考手册> IWDG 章节一起阅读,效果会更佳,特别是涉及到寄存器 ...
- 第34章 IWDG—独立看门狗—零死角玩转STM32-F429系列
第34章 IWDG—独立看门狗 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fir ...
- STM32独立看门狗(IWDG)
造成程序跑飞,只是程序的正常运行状态被打断而进入死循环,从而使单片机控制的系统无法正常工作.看门狗就是一种专门用于检测单片机程序运行状态的硬件结构. STM32内部自带了两个看门狗,独立看门狗(IWD ...
随机推荐
- mysql查看表结构命令,如下:
desc 表名; show columns from 表名; describe 表名; show create table 表名;
- 奇妙的算法【6】-WY回文、树、最优化、卷积判断
1,判断一个十进制正整数的二进制数是否为回文 package com.cnblogs.mufasa.answer1; import java.util.Scanner; public class Ma ...
- .Net Core Swagger:Actions require an explicit HttpMethod binding for Swagger 2.0
添加完Swagger包引用后运行报错:Actions require an explicit HttpMethod binding for Swagger 2.0 第一时间想到了父类控制器 没有添加 ...
- C#操作DOS命令,并获取处理返回值
// /*---------------- // // 文件名:Method // // 文件功能描述: // // 使用 ADB 来进行安卓设备与PC端之间的文件交互,具体adb命令操作请百度 ...
- 空a标签在IE下无效之解决方法
过程就不分析了,只说解决方法: 1.给a标签添加样式:background:url(about:blank); 2.给a标签随便添加背景色或者背景图片,然后将a标签的透明度设置为0,不过在IE中需要使 ...
- 关于ECharts甘特图的实现
对于使用ECharts图表的步骤,每种图表都是一致的,相信大家也都了解 此处只分享甘特图的option,代码如下: option: { title: { text: '项目实施进度表', left: ...
- 有选择性的启用SAP UI5调试版本的源代码
在低版本的SAP UI5应用中,我们一旦切换成调试模式,那么应用程序源代码和UI5框架程序的源代码的调试版本都会重新加载,耗时很长. 我最近发现UI5新版本1.66.1提供了选择性加载调试版本的源代码 ...
- 用pythoninstall cefpython打包exe,制作自己的浏览器
cefpython浏览器 介绍 用pythoninstall cefpython打包exe,制作自己的浏览器, 软件架构 PyInstaller: 3.4 Python: 3.5.4 Platform ...
- Spring Boot笔记
@SpringBootApplication中有以下注解:@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Document ...
- Java基于Redis的分布式锁
分布式锁,其实最终还是要保证锁(数据)的一致性,说到数据一致性,基于ZK,ETCD数据一致性中间件做分数是锁,才是王道.但是Redis也能满足最基本的需求. 参考: https://www.cnblo ...