一,独立看门狗

二,独立看门狗的时钟源

独立看门狗拥有自己的时钟源,不依赖PLL时钟输出的分频信号,能够独立运行,这样子的好处就是PLL假如受到干扰,

导致运行异常,独立的看门狗还能正常地进行工作,如果没有正常的喂狗动作,就复位CPU。

三、程序设计

1.     添加复位检测代码,有助于观察当前工作的可靠性

  1. /* Check if the system has resumed from IWDG reset,检查当前复位是否有独立看门狗导致 */
  2. if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
  3. {
  4. /* IWDGRST flag set */
  5. printf("iwdt reset cpu\r\n");
  6.  
  7. /* Clear reset flags */
  8. RCC_ClearFlag();
  9. }
  10. else
  11. {
  12. /* IWDGRST flag is not set */
  13. printf("normal reset cpu\r\n");
  14.  
  15. }

2.

  1. /* Enable write access to IWDG_PR and IWDG_RLR registers,独立看门狗是受到保护的,现在进行解锁动作 */
  2. IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
  3.  
  4. /* IWDG counter clock: LSI/256 ,设置看门狗的时钟 = 32KHz / 256 =125Hz */
  5. IWDG_SetPrescaler(IWDG_Prescaler_256);
  6.  
  7. /* 设置看门狗的超时时间,也就是设置它的计数值
  8. 当前看门狗的时钟为125Hz,然后设置超时时间为1秒,那么重载值为125
  9. 当前看门狗的时钟为125Hz,然后设置超时时间为2秒,那么重载值为250
  10. */
  11. IWDG_SetReload();
  12.  
  13. /* Reload IWDG counter,重载独立看门狗的计数值,说白了就是喂狗 */
  14. IWDG_ReloadCounter();
  15.  
  16. /* Enable IWDG (the LSI oscillator will be enabled by hardware),使能独立看门狗 */
  17. IWDG_Enable();

3.     喂狗技巧

1.在裸机代码实现喂狗,放在定时器里面,因为定时器与看门狗是使用不同的时钟源,允许这么做!

2.     如果有实时的操作系统的加持,可以在任务里面添加喂狗动作,如果操作系统崩溃了,能够检测到软件的错误,触发CPU的复位。

在定时器中断服务函数当中,添加喂狗动作!

  1. #include "stm32f4xx.h"
  2. #include "stm32f4xx_gpio.h"
  3. #include "stm32f4xx_rcc.h"
  4. #include "stm32f4xx_usart.h"
  5. #include "stdio.h"
  6.  
  7. static GPIO_InitTypeDef GPIO_InitStructure;
  8. static USART_InitTypeDef USART_InitStructure;
  9. static NVIC_InitTypeDef NVIC_InitStructure;
  10.  
  11. void delay_us(uint32_t nus)
  12. {
  13. uint32_t temp;
  14. SysTick->LOAD =SystemCoreClock//*nus; //时间加载
  15. SysTick->VAL =0x00; //清空计数器
  16. SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //使能滴答定时器开始倒数
  17. do
  18. {
  19. temp=SysTick->CTRL;
  20. }while((temp&0x01)&&!(temp&(<<))); //等待时间到达
  21. SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
  22. SysTick->VAL =0X00; //清空计数器
  23. }
  24.  
  25. void delay_ms(uint16_t nms)
  26. {
  27. uint32_t temp;
  28. SysTick->LOAD=SystemCoreClock//*nms; //时间加载(SysTick->LOAD为24bit)
  29. SysTick->VAL =0x00; //清空计数器
  30. SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //能滴答定时器开始倒数
  31. do
  32. {
  33. temp=SysTick->CTRL;
  34. }while((temp&0x01)&&!(temp&(<<))); //等待时间到达
  35. SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
  36. SysTick->VAL =0X00; //清空计数器
  37. }
  38.  
  39. void LED_Init(void)
  40. {
  41.  
  42. //使能GPIOE,GPIOF时钟
  43. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF, ENABLE);
  44.  
  45. //GPIOF9,F10初始化设置
  46. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //LED0和LED1对应IO口
  47. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式,
  48. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出,驱动LED需要电流驱动
  49. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz
  50. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
  51. GPIO_Init(GPIOF, &GPIO_InitStructure); //初始化GPIOF,把配置的数据写入寄存器
  52.  
  53. //GPIOE13,PE14初始化设置
  54. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; //LED2和LED3对应IO口
  55. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式
  56. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
  57. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz
  58. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
  59. GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化GPIOE,把配置的数据写入寄存器
  60.  
  61. GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10); //GPIOF9,PF10设置高,灯灭
  62. GPIO_SetBits(GPIOE,GPIO_Pin_13 | GPIO_Pin_14);
  63. }
  64.  
  65. void USART1_Init(uint32_t baud)
  66. {
  67. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
  68. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //使能USART1时钟
  69.  
  70. //串口1对应引脚复用映射
  71. GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
  72. GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1
  73.  
  74. //USART1端口配置
  75. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
  76. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
  77. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
  78. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
  79. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
  80. GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10
  81.  
  82. //USART1 初始化设置
  83. USART_InitStructure.USART_BaudRate = baud; //波特率设置
  84. USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
  85. USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位
  86. USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
  87. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
  88. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
  89. USART_Init(USART1, &USART_InitStructure); //初始化串口1
  90.  
  91. USART_Cmd(USART1, ENABLE); //使能串口1
  92.  
  93. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启相关中断
  94.  
  95. //Usart1 NVIC 配置
  96. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //串口1中断通道
  97. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=; //抢占优先级3
  98. NVIC_InitStructure.NVIC_IRQChannelSubPriority =; //子优先级3
  99. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
  100. NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
  101. }
  102.  
  103. //重定义fputc
  104. int fputc(int ch,FILE *f)
  105. {
  106. USART_SendData(USART1,ch);
  107. while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
  108.  
  109. return ch;
  110. }
  111.  
  112. void usart1_send_bytes(uint8_t *pbuf,uint32_t len)
  113. {
  114. while(len--)
  115. {
  116. USART_SendData(USART1,*pbuf++);
  117. while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
  118. }
  119. }
  120.  
  121. void usart1_send_str(char *pbuf)
  122. {
  123. while(pbuf && *pbuf)
  124. {
  125. USART_SendData(USART1,*pbuf++);
  126. while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
  127. }
  128. }
  129.  
  130. int main(void)
  131. {
  132.  
  133. LED_Init();
  134.  
  135. //系统定时器初始化,时钟源来自HCLK,且进行8分频,
  136. //系统定时器时钟频率=168MHz/8=21MHz
  137. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
  138.  
  139. //设置中断优先级分组2
  140. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  141.  
  142. //串口1,波特率115200bps,开启接收中断
  143. USART1_Init();
  144.  
  145. /* Check if the system has resumed from IWDG reset,检查当前复位是否有独立看门狗导致 */
  146. if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
  147. {
  148. /* IWDGRST flag set */
  149. printf("iwdt reset cpu\r\n");
  150.  
  151. /* Clear reset flags */
  152. RCC_ClearFlag();
  153. }
  154. else
  155. {
  156. /* IWDGRST flag is not set */
  157. printf("normal reset cpu\r\n");
  158.  
  159. }
  160.  
  161. /* Enable write access to IWDG_PR and IWDG_RLR registers,独立看门狗是受到保护的,现在进行解锁动作 */
  162. IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
  163.  
  164. /* IWDG counter clock: LSI/256 ,设置看门狗的时钟 = 32KHz / 256 =125Hz */
  165. IWDG_SetPrescaler(IWDG_Prescaler_256);
  166.  
  167. /* 设置看门狗的超时时间,也就是设置它的计数值
  168. 当前看门狗的时钟为125Hz,然后设置超时时间为1秒,那么重载值为125
  169. 当前看门狗的时钟为125Hz,然后设置超时时间为2秒,那么重载值为250
  170. */
  171. IWDG_SetReload();
  172.  
  173. /* Reload IWDG counter,重载独立看门狗的计数值,说白了就是喂狗 */
  174. IWDG_ReloadCounter();
  175.  
  176. /* Enable IWDG (the LSI oscillator will be enabled by hardware),使能独立看门狗 */
  177. IWDG_Enable();
  178.  
  179. while()
  180. {
  181.  
  182. //重载计数值,就是喂狗,就是不让计数值变为0
  183. IWDG_ReloadCounter();
  184.  
  185. }
  186. }
  187.  
  188. void USART1_IRQHandler(void) //串口1中断服务程序
  189. {
  190. uint8_t d;
  191.  
  192. if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
  193. {
  194. //接收数据
  195. d = USART_ReceiveData(USART1);
  196.  
  197. //发送数据
  198. usart1_send_bytes(&d,);
  199.  
  200. }
  201.  
  202. }

---恢复内容结束---

独立看门狗 IWDG的更多相关文章

  1. stm32 独立看门狗 IWDG

    独立看门狗IWDG 独立看门狗简单理解就是一个12位递减计数器,当计数器从某一个值递减到0时,系统就会产生一次复位 独立看门狗由专用低速时钟LSI驱动,其频率一般在30-60KHz之间,通常选择40K ...

  2. (stm32f103学习总结)—独立看门狗(IWDG)

    一.IWDG介绍 1.1 IWDG简介 STM32F1芯片内部含有两个看门狗外设,一个是独立看门狗IWDG,另 一个是窗口看门狗WWDG.两个看门狗外设(独立和窗口)均可用于检测 并解决由软件错误导致 ...

  3. STM32之独立看门狗(IWDG)与窗口看门狗(WWDG)总结

    一.独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路 ...

  4. STM8L独立看门狗IWDG

    简单扼要 void IWDG_Init(void)//初始化 { IWDG->KR = 0xcc;//启动IWDG IWDG->KR = 0x55;//解除PR及RLR的写保护 IWDG- ...

  5. stm32 独立看门狗学习

    STM32F10xxx内置两个看门狗,提供了更高的安全性.时间的精确性和使用的灵活性.两个看门狗设备(独立看门狗和窗口看门狗)可用来检测和解决由软件错误引起的故障. 独立看门狗(IWDG)由专用的低速 ...

  6. STM32之------独立看门狗(IWDG)和窗体看门狗(WWDG)

    一     前沿废语: 之前有很风靡的游戏,名字叫<看门狗>.该游戏用了很新的引擎技术,打造出了一个辽阔庞大的世界,内容是玩家Aiden·Pearce(主角)是一名精通黑客技术的高手,当时 ...

  7. IWDG—独立看门狗

    本章参考资料:<STM32F4XX 中文参考手册> IWDG 章节.学习本章时,配合<STM32F4XX 中文参考手册> IWDG 章节一起阅读,效果会更佳,特别是涉及到寄存器 ...

  8. 第34章 IWDG—独立看门狗—零死角玩转STM32-F429系列

    第34章     IWDG—独立看门狗 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fir ...

  9. STM32独立看门狗(IWDG)

    造成程序跑飞,只是程序的正常运行状态被打断而进入死循环,从而使单片机控制的系统无法正常工作.看门狗就是一种专门用于检测单片机程序运行状态的硬件结构. STM32内部自带了两个看门狗,独立看门狗(IWD ...

随机推荐

  1. redis 缓存对象、列表

    在spring boot环境下有个StringRedisTemplate对象,默认已经为我们配置好了,只需要自动注入过来就能用,但是使用它只能在Redis中存放字符串.具体操作如下: @RunWith ...

  2. PHP运行机制和原理

    以echo "Hello World";为例 经历五个步骤:1.扫描(scanning):先进行语法分析和词法分析,然后将index.php内容变成一个个语言片段(token ar ...

  3. Eclipse syntax coloring java xml 语法 样式

    自定义java源文件的编码样式,包括关键词等等的样式和颜色等,可以一边调下面就能看到样式效果,这是我自己一个个设置好的如图 自定义xml文件编辑器的样式格式,其实我装了sublime 但是 eclip ...

  4. 恺撒密码 I

    恺撒密码 I ‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭ ...

  5. vue-filters(过滤器)

    局部过滤器: <html> <head> <title>vue</title> <meta charset="utf-8"&g ...

  6. ARC模式下获取retainCount的方法

    _objc_rootRetainCount(obj)可以获取obj的retainCount,不过不清楚是不是私有api,因此建议调试时使用.

  7. C++ 项目和资源导引

    值得学习的C语言开源项目 注意:本文转载自:https://blog.csdn.net/a110658684/article/details/78862348 - 1. Webbench Webben ...

  8. linux文件系统初学

    Linux磁盘分区和目录 Linux发行版之间的差别很小,差别主要表现在系统管理的特色工具以及软件包管理方式的不同. Windows的文件结构是多个并列的树状结构,最顶部是不同的磁盘(分区),如C,D ...

  9. vue组件间的传值方式及方法调用汇总

    1.传值 a.父组件传子组件 方法一: 父页面: <myReportContent v-if="contentState==1" :paramsProps='paramsPr ...

  10. Spark学习笔记2——RDD(上)

    目录 Spark学习笔记2--RDD(上) RDD是什么? 例子 创建 RDD 并行化方式 读取外部数据集方式 RDD 操作 转化操作 行动操作 惰性求值 Spark学习笔记2--RDD(上) 笔记摘 ...