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

STM32F4+RT-Thread IWDG 看门狗 开发实战:从驱动编写到“喂狗、超时复位”指南

目录

  • 一、工程环境搭建
  • 二、程序编写
  • 三、实验与分析

一、工程环境搭建

  1. 创建一个新工程
    在这里插入图片描述
  2. 打开CubeMX 进行工程配置
    在这里插入图片描述
  3. 打开IWDG看门狗
    在这里插入图片描述
  4. 时钟选择外部晶振
    在这里插入图片描述
  5. 配置下载调试口
    在这里插入图片描述
  6. 打开串口一
    在这里插入图片描述
  7. 配置时钟线
    在这里插入图片描述
  8. 选择工具链,我这里用的是MDK-ARM
    在这里插入图片描述
  9. 生成.c和.h文件
    在这里插入图片描述
  10. 生成代码
    在这里插入图片描述
  11. 打开WDT设备驱动程序
    在这里插入图片描述
  12. 在构建配置里增加Src/iwdg.c,不然咱在Src目录下看不到该.c文件
    在这里插入图片描述
  13. 重新生成一下代码
    在这里插入图片描述
  14. 现在就能看到iwdg.c文件了
    在这里插入图片描述
  15. 新建system_deal文件夹,再在该文件夹下新建system_deal.c和system_deal.h文件
    在这里插入图片描述
  16. 把这个宏定义改一下,改成小写,我发现rtthread5.1.0版本有这个问题,我之前用的是4.1.1版本没这个问题,更新后把宏定义改成小写了不知道为什么,这里我们需要自己手动改一下。
    在这里插入图片描述
  17. 改成小写后,我们编译一下,编译通过,环境配置到此为止(那个警告也是更新版本后出现的,暂时不用管)
    在这里插入图片描述

二、程序编写

  1. main.c文件主函数里写如下代码
/** Copyright (c) 2006-2025, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2025-09-25     RT-Thread    first version*/
#include "system_deal.h"int main(void)
{SystemStartInit();return RT_EOK;
}

在这里插入图片描述
2. 在system_deal.文件里写入如下代码

/** Copyright (c) 2006-2021, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2025-09-25     Administrator       the first version*/#include "system_deal.h"rt_uint32_t timeout = 10;        /* 溢出时间,单位:秒 */
SysDev_t s_tSysDev;/*********************************************************************************************************** Function name:       SysDealInit** Descriptions:        Sys Deal Init** input parameters:    NONE** output parameters:   NONE** Returned value:      pHmiDev_t*********************************************************************************************************/
static pSysDev_t SysDealInit(void)
{rt_err_t ret = RT_EOK;pSysDev_t psys = (pSysDev_t)&s_tSysDev;rt_memset((uint8_t*)&psys->WdgDev, 0, sizeof(SysDev_t));// set pinrt_pin_mode(SYS_LED, PIN_MODE_OUTPUT);rt_pin_write(SYS_LED, PIN_HIGH);   //用来给板子闪灯,观察板子是否正常跑起psys->WdgDev = rt_device_find(WDT_DEVICE_NAME);if (!psys->WdgDev){rt_kprintf("wdt find failed!\n");}rt_device_init(psys->WdgDev);/* 设置看门狗溢出时间 */ret = rt_device_control(psys->WdgDev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);if (ret != RT_EOK){rt_kprintf("set %s timeout failed!\n", WDT_DEVICE_NAME);}ret = rt_device_control(psys->WdgDev, RT_DEVICE_CTRL_WDT_START, RT_NULL);if (ret != RT_EOK){rt_kprintf("wdt conrtol failed!\n");}return psys;
}/*********************************************************************************************************** Function name:       SystemLedRun** Descriptions:        System Led Run** input parameters:    NONE** output parameters:   NONE** Returned value:      NONE*********************************************************************************************************/
static void SystemLedRun(void)
{static uint8_t l_ucmode = 0;if (l_ucmode == 0){rt_pin_write(SYS_LED, PIN_HIGH);l_ucmode = 1;}else if (l_ucmode == 1){rt_pin_write(SYS_LED, PIN_LOW);l_ucmode = 0;}
}/*********************************************************************************************************** Function name:       SystemFeedDog** Descriptions:        System Feed Dog** input parameters:    pSysDev_t** output parameters:   NONE** Returned value:      NONE*********************************************************************************************************/
static void SystemFeedDog(pSysDev_t psys)
{rt_err_t ret = RT_EOK;ret = rt_device_control(psys->WdgDev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);if (ret != RT_EOK){rt_kprintf("feed the dog error!\n ");}
}/*********************************************************************************************************** Function name:       SysDevCheck** Descriptions:        Sys Dev Check** input parameters:    pSysDev_t** output parameters:   NONE** Returned value:      NONE*********************************************************************************************************/
void SysDevCheck(pSysDev_t psys)
{if ((rt_tick_get() - psys->tSysDevMsg.SysFlushCyc) >= SYS_TICK_TIME){psys->tSysDevMsg.SysFlushCyc = rt_tick_get();SystemLedRun();//SystemFeedDog(psys);rt_kprintf("time:%ds\r\n",rt_tick_get()/1000);}
}/*********************************************************************************************************** Function name:       SysDeal_thread** Descriptions:        SysDeal thread** input parameters:    parameter** output parameters:   NONE** Returned value:      NONE*********************************************************************************************************/
static void SysDeal_thread(void* parameter)
{pSysDev_t l_ptsys = SysDealInit();while(1){SysDevCheck(l_ptsys);rt_thread_mdelay(10);}
}/*********************************************************************************************************** Function name:       SystemDealTaskInit** Descriptions:        System Task Init** input parameters:    NONE** output parameters:   NONE** Returned value:      NONE*********************************************************************************************************/
void SystemDealTaskInit(void)
{rt_thread_t SysDeal_tid;SysDeal_tid = rt_thread_create("sys_ctl", SysDeal_thread, RT_NULL, SYS_THREAD_STACK, SYS_THREAD_PRO, SYS_THREAD_TICK);if (SysDeal_tid != RT_NULL){rt_thread_startup(SysDeal_tid);}else{
#if DEBUG_LOG_ENABLErt_kprintf("/--> SysDeal create failed!\n");
#endif}
}/*********************************************************************************************************** Function name:       SystemTaskInit** Descriptions:        System Task Init** input parameters:    NONE** output parameters:   NONE** Returned value:      NONE*********************************************************************************************************/
static void SystemTaskInit(void)
{SystemDealTaskInit();
}/*********************************************************************************************************** Function name:       SystemStartInit** Descriptions:        System Start Init** input parameters:    NONE** output parameters:   NONE** Returned value:      NONE*********************************************************************************************************/
void SystemStartInit(void)
{SystemTaskInit();
}

在这里插入图片描述
3. 在system_deal.h文件下写入如下代码

/** Copyright (c) 2006-2021, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2025-09-25     Administrator       the first version*/
#ifndef APPLICATIONS_SYSTEM_DEAL_SYSTEM_DEAL_H_
#define APPLICATIONS_SYSTEM_DEAL_SYSTEM_DEAL_H_
#include <rtdevice.h>
#include <rtthread.h>
#include "board.h"
#include "stdio.h"/* thread information */
#define SYS_THREAD_STACK 1024
#define SYS_THREAD_PRO 15
#define SYS_THREAD_TICK 10/* system io */
#define SYS_LED             GET_PIN(G, 13)/* system wdt */
#define WDT_DEVICE_NAME     "wdt"/* system info */
#define SYS_TICK_TIME           1 * 1000/* SysDevMsg */
typedef struct
{uint32_t SysFlushCyc;} SysDevMsg_t;typedef struct
{rt_device_t WdgDev;SysDevMsg_t tSysDevMsg;} SysDev_t, *pSysDev_t;#endif /* APPLICATIONS_SYSTEM_DEAL_SYSTEM_DEAL_H_ */

在这里插入图片描述
4. 添加system_deal.h文件路径
在这里插入图片描述
5. 编译一下,编译通过
在这里插入图片描述

三、实验与分析

  1. 将程序下进板子,打开串口,可以看到每秒都有打印
    在这里插入图片描述
  2. 打印的逻辑在这,1s进一次,打印当前系统时间
    在这里插入图片描述
  3. 这个是“喂狗”的函数,我当前是把它注释掉了,也就是说超过一定时间后,系统就会复位
    在这里插入图片描述
  4. 这是喂狗函数内部实现。
    在这里插入图片描述
  5. 可以看到运行到14s的时候,系统进行了重启,那这个14s是在哪里定的呢?
    在这里插入图片描述
  6. 在这个位置,设立了超时时间,如果在14s内没有喂狗,则再超过14s时,系统则会复位
    在这里插入图片描述
    在这里插入图片描述
  7. 我们现在把喂狗的注释打开,验证一下系统是不是就能超过14s的跑下去了
    在这里插入图片描述
  8. 可以看到,如果按时喂狗,系统则能正常运行
    在这里插入图片描述
  9. 如果我在初始化的时候,不去设置超时时间,那系统默认的看门狗超时时间是多少呢?我们来试一下
    在这里插入图片描述
  10. 依旧把喂狗函数注释掉,我们看一下,系统会在多少秒进行复位
    在这里插入图片描述
  11. 可以看到系统在33s的时候进行了复位,那这个33s是在哪里确定的呢?
    在这里插入图片描述
  12. 在这个位置进行的默认配置,对看门狗的时钟进行了256的分频,然后重装载值是4095,我们来算一下是不是33s
    在这里插入图片描述
  13. 首先看门狗的时钟是32KHZ
    在这里插入图片描述

步骤 1:计算分频后的时钟周期(每个计数的时间)
分频后的时钟频率 = 输入时钟频率 / 分频系数f_div = 32000Hz / 256 = 125Hz
每个计数的时间(即分频后的周期)= 1 / 分频后频率T_div = 1 / 125Hz = 0.008 秒 = 8 毫秒
步骤 2:计算总计数次数
计数器从4095递减到0,总计数次数 = 4095 + 1 = 4096 次
步骤 3:计算总复位时间
总复位时间 = 总计数次数 × 每个计数的时间T_reset = 4096 × 0.008 秒 = 32.768 秒

  1. 因此是符合预期的,但是我们在使用时还是要记得设置超时时间,这样对程序的把控会更好一些
http://www.dtcms.com/a/407112.html

相关文章:

  • 视频网站后台模板电影网站html代码
  • 从“黄金公式“到AI内容矩阵:快消品牌如何实现转化率8倍增长
  • Magick.NET库测试
  • 八、OpenCV中的常见滤波方式
  • ReAct与PlanReAct的定义及区别
  • 网站 廉政建设 板块中装建设官网
  • 63.[前端开发-Vue3]Day05-非父子通信-声明周期-refs-混合-额外补充
  • 用CodeBuddy Code CLI构建现代化Vue待办事项应用:从零到部署的完整实战
  • wordpress手机端菜单广州网站优化方案
  • PostgreSQL表分区简单介绍和操作方法
  • 建设网站费用评估浙江省特种作业证查询官网
  • Charles在安全测试中的应用,接口漏洞验证与敏感数据检测
  • NAT、代理服务与内网穿透详解
  • 为什么有时候 reCAPTCHA 通过率偏低,常见原因有哪些
  • 外出也能随时 SSH 访问内网 Linux,ZeroNews 提供公网域名直达
  • 基于vue的咖啡销售系统28zz1(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
  • LoadBalancer完整学习笔记:简介、原理与自定义
  • 网站建设英文怎么说洛阳php网站开发
  • 图片转文字(PDF转word,图片转word等)
  • 网站维护一年多少费北京网站建设培训
  • 让风恒定:在 unordered 的荒原上种下一棵常数级的树
  • 图书网站建设实训总结前端培训心得
  • 【Spring Cloud Alibaba】Seata(一)
  • 仓颉编程语言的stdx包介绍及使用
  • 长沙网站制作方法wordpress获得所有分类
  • 无限空间 网站网站新闻页面无法翻页
  • 民族团结 网站建设wordpress底部版权插件
  • Markdown转PDF工程化实现含图片支持与样式控制
  • Linux下安装Kafka 3.9.1
  • kafka vs rocketmq