当前位置: 首页 > news >正文

stm32l4系列启用看门狗后,调用HAL_IWDG_Refreh()就复位

问题描述:在stm32L431cct6芯片上想启用看门狗,但配置完后发现一调用喂狗函数,就会导致单片机复位,调用一次复位一次。

问题背景:在原有HAL库工程上添加看门狗时,采用手动配置来初始化看门狗,并没有使用CubeMX生成的看门狗初始化函数,手动配置时缺少一个参数的配置,导致问题出现。

 1. 手动配置代码如下

void MX_IWDG_Init(void)
{hiwdg.Instance = IWDG;hiwdg.Init.Prescaler = IWDG_PRESCALER_64;hiwdg.Init.Reload = 4095;if (HAL_IWDG_Init(&hiwdg) != HAL_OK){Error_Handler();}
}

2. CubeMX生成的代码如下

static void MX_IWDG_Init(void)
{/* USER CODE END IWDG_Init 1 */hiwdg.Instance = IWDG;hiwdg.Init.Prescaler = IWDG_PRESCALER_64;hiwdg.Init.Window = 4095;    //CubeMX多配置的参数hiwdg.Init.Reload = 4095;if (HAL_IWDG_Init(&hiwdg) != HAL_OK){Error_Handler();}
}

可以看出区别就是CubeMX多配置了hiwdg.Init.Window,那么这是什么东西呢?

在回答这个问题之前,我们可以先看看数据手册(图1)如何描述L4系列的IWDG功能,主要注意红框内的内容,复位条件有两点:

1. 向下计数器的计数值到达0及0以下(看门狗计时溢出)

2. 向下计数器在窗口外被重置计数值(在窗口外喂狗)

图1 数据手册所描述IWDG的主要特点

根据第二点,我们就可以推断出`hiwdg.Init.Window`该参数是用来限制喂狗时机的,效果如下图:

图2 IWDG之Window功能效果图

数据手册里的说明更加详细:

图3 窗口选项说明

在我手动初始化IWDG_WINR寄存器之后,喂狗便不再发生复位。

问题已解决,但仍有一点无法解释的地方,IWDG_WINR寄存器的复位值默认是4095(如上图3所示),理论上来讲即使我不手动配置它,喂狗也不会导致单片机复位,正如数据手册中所描述的,如果不更新该寄存器,那么window option是被禁用的。那么有没有可能是因为该值被更新了呢?

我们接着往下阅读参考手册,发现有禁用状态下配置IWDG的流程如下:

为了一探究竟,这里查看一下HAL库是如何初始化IWDG的,与上述描述有何异同

/*** @brief  Initialize the IWDG according to the specified parameters in the*         IWDG_InitTypeDef and start watchdog. Before exiting function,*         watchdog is refreshed in order to have correct time base.* @param  hiwdg  pointer to a IWDG_HandleTypeDef structure that contains*                the configuration information for the specified IWDG module.* @retval HAL status*/
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
{uint32_t tickstart;/* Check the IWDG handle allocation */if (hiwdg == NULL){return HAL_ERROR;}/* Check the parameters */assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance));assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler));assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload));assert_param(IS_IWDG_WINDOW(hiwdg->Init.Window));/* Enable IWDG. LSI is turned on automatically */__HAL_IWDG_START(hiwdg);/* Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers by writing0x5555 in KR */IWDG_ENABLE_WRITE_ACCESS(hiwdg);/* Write to IWDG registers the Prescaler & Reload values to work with */hiwdg->Instance->PR = hiwdg->Init.Prescaler;hiwdg->Instance->RLR = hiwdg->Init.Reload;/* Check pending flag, if previous update not done, return timeout */tickstart = HAL_GetTick();/* Wait for register to be updated */while (hiwdg->Instance->SR != 0x00u){if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT){return HAL_TIMEOUT;}}/* If window parameter is different than current value, modify windowregister */if (hiwdg->Instance->WINR != hiwdg->Init.Window){/* Write to IWDG WINR the IWDG_Window value to compare with. In any case,even if window feature is disabled, Watchdog will be reloaded by writingwindows register */hiwdg->Instance->WINR = hiwdg->Init.Window;}else{/* Reload IWDG counter with value defined in the reload register */__HAL_IWDG_RELOAD_COUNTER(hiwdg);}/* Return function status */return HAL_OK;
}

 可以看出在初始化过程中,第6点有所不同(上述代码第50行)。HAL库在初始化时,先判断了下寄存器中的WINR值与句柄中Window的值,如果不同,那么会将句柄中的值赋值给寄存器。问题便出现在这里。

问题的根本原因:我们在定义iwdg句柄时一般为全局变量,导致hiwdg->Init.Window值为0,而寄存器中的值默认复位时为4065,由于两者不相等,所以寄存器中的值被赋值为0,再根据注释中所描述,写入window寄存器后会触发喂狗,而喂狗的时机一定是在窗口之外(窗口为0),进而导致单片机不断复位。

至此问题已彻底找到。

解决方案:在初始化有IWDG_WINR寄存器的单片机时应手动初始化hiwdg->Init.Window为4095

参考资料链接:IWDG部分在第33章节STM32L41xxx/42xxx/43xxx/44xxx/45xxx/46xxx advanced Arm®-based 32-bit MCUs - Reference manualhttps://www.st.com/resource/en/reference_manual/rm0394-stm32l41xxx42xxx43xxx44xxx45xxx46xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

http://www.lqws.cn/news/597043.html

相关文章:

  • HakcMyVM-Arroutada
  • java生成word文档
  • 飞算JavaAI:重构软件开发范式的智能引擎
  • ABB驱动系列SCYC51213 63911607C驱动板
  • java微服务-linux单机CPU接近100%优化
  • Python应用指南:利用高德地图API获取公交+地铁可达圈(二)
  • 再见 RAG?Gemini 2.0 Flash 刚刚 “杀死” 了它!
  • 学习面向对象
  • 第TR3周:Pytorch复现Transformer
  • 快速手搓一个MCP服务指南(九): FastMCP 服务器组合技术:构建模块化AI应用的终极方案
  • 【仿muduo库实现并发服务器】Poller模块
  • 基于中国印尼会计准则差异,中国企业在印尼推广ERP(SAP、Oracle)系统需要注意的细节
  • Pycharm命令行能运行,但绿色三角报错?
  • mac重复文件清理,摄影师同款清理方案
  • nosql项目:基于 Redis 哨兵模式的鲜花预订配送系统
  • 设计模式之组合模式
  • 将实时流的 H.264(视频)与 G.711A(音频)封装成 MP4 文件
  • 关于量子计算的一份介绍
  • 12【进程间通信——管道】
  • Vue 响应式数据传递:ref、reactive 与 Provide/Inject 完全指南
  • 基于 Three.js 与 WebGL 的商场全景 VR 导航系统源码级解析
  • 遥感云大数据在灾害、水体与湿地领域案例及GPT应用
  • 第八章:LeRobot摄像头配置与应用指南
  • 使用GeoServer发布地图shapefi(.shp)数据
  • Spring Bean的生命周期与作用域详解
  • Vue-17-前端框架Vue之应用基础集中式状态管理pinia(二)
  • AI智能体在用户行为数据分析中有哪些应用?
  • Android 网络全栈攻略(四)—— TCPIP 协议族与 HTTPS 协议
  • Linux基本命令篇 —— grep命令
  • 基于ApachePOI实现百度POI分类快速导入PostgreSQL数据库实战