[APM32E0] APM32E030的IWDT驱动

[复制链接]
366|4
口天土立口 发表于 2025-9-6 16:59 | 显示全部楼层 |阅读模式
hz, US, ,
本帖最后由 口天土立口 于 2025-9-7 18:32 编辑

5636468bbf7549d46e.png

APM32E030拥有一个独立看门狗,此看门狗可用于监控程序的运行。

驱动代码如下:
  1. /* LSI理论: 40KHz,实际值有差异 */
  2. /* PSC = 4 -> 10KHz = 100us, CNTRLD = 0 ~ 4095-> 100us ~ 409.6ms */
  3. /* PSC = 8 -> 5KHz = 200us, CNTRLD = 0 ~ 4095-> 200us ~ 819.2ms */
  4. /* PSC = 16 -> 2.5KHz = 400us, CNTRLD = 0 ~ 4095-> 400us ~ 1638.4ms */
  5. /* PSC = 32 -> 1.25KHz = 800us, CNTRLD = 0 ~ 4095-> 800us ~ 3276.8ms */
  6. /* PSC = 64 -> 625Hz = 1600us, CNTRLD = 0 ~ 4095-> 1600us ~ 6553.6ms */
  7. /* PSC = 128 -> 312.5Hz = 3200us, CNTRLD = 0 ~ 4095-> 3200us ~ 13107.2ms */
  8. /* PSC = 256 -> 156.25Hz = 6400us, CNTRLD = 0 ~ 4095-> 6400us ~ 26214.4ms */

  9. /*
  10. * @brief       独立看门狗初始化
  11. *
  12. * @param       timeout_ms: 看门狗超时时间
  13. *              is_debug_stop: 调试是否停止
  14. *
  15. * @retval      None
  16. *
  17. */
  18. void bsp_iwdt_init(uint16_t timeout_ms, uint8_t is_debug_stop)
  19. {
  20.     uint32_t iwdt_clk = 40000;      /* 独立看门狗时钟为LSI 40KHz */
  21.     IWDT_DIV_T div = IWDT_DIV_4;
  22.     uint16_t reload = 0;
  23.     float tmp = 0.0f;
  24.    
  25.     /* 最大26s超时时间 */
  26.     if (timeout_ms > 26000) {
  27.         return ;
  28.     }
  29.    
  30.     /* 800ms以内 */
  31.     if (timeout_ms <= 800) {
  32.         div = IWDT_DIV_8;
  33.         tmp = (float)iwdt_clk / 8;      /* 计数频率 */
  34.         tmp = 1000.0f / tmp;            /* ms */
  35.         reload = (float)timeout_ms / tmp;
  36.     /* 3s以内 */
  37.     } else if (timeout_ms <= 3000) {
  38.         div = IWDT_DIV_32;
  39.         tmp = (float)iwdt_clk / 32;     /* 计数频率 */
  40.         tmp = 1000.0f / tmp;            /* ms */
  41.         reload = (float)timeout_ms / tmp;
  42.     /* 26s以内 */
  43.     } else {
  44.         div = IWDT_DIV_256;
  45.         tmp = (float)iwdt_clk / 256;    /* 计数频率 */
  46.         tmp = 1000.0f / tmp;            /* ms */
  47.         reload = (float)timeout_ms / tmp;
  48.     }
  49.    
  50.     /* 清独立看门狗复位标志 */
  51.     if (RCM_ReadStatusFlag(RCM_FLAG_IWDTRST) != RESET) {
  52.         RCM_ClearStatusFlag();
  53.     }
  54.     IWDT_EnableWriteAccess();
  55.     IWDT_ConfigDivider(div);
  56.     IWDT_ConfigReload(reload);
  57.     IWDT_Refresh();
  58.     IWDT_Enable();
  59.    
  60.     /* 调试时看门狗计数器是否停止工作 */
  61.     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_DBGMCU);
  62.     if (is_debug_stop != 0) {
  63.         DBG_EnableAPB1Periph(DBG_APB1_PER_IWDT_STOP);
  64.     } else {
  65.         DBG_DisableAPB1Periph(DBG_APB1_PER_IWDT_STOP);
  66.     }
  67. }
  1. /*
  2. * @brief       看门狗喂狗
  3. *
  4. * @param       None
  5. *
  6. * @retval      None
  7. *
  8. */
  9. void bsp_iwdt_feed(void)
  10. {
  11.     IWDT_Refresh();
  12. }


测试代码如下:
  1. void gpio_test(void)
  2. {
  3.     GPIO_Config_T gpioConfig;
  4.    
  5.     RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOB);
  6.     GPIO_ConfigStructInit(&gpioConfig);
  7.     gpioConfig.pin     = GPIO_PIN_6;
  8.     gpioConfig.mode    = GPIO_MODE_OUT;
  9.     gpioConfig.outtype = GPIO_OUT_TYPE_PP;
  10.     gpioConfig.speed   = GPIO_SPEED_50MHz;
  11.     gpioConfig.pupd    = GPIO_PUPD_NO;   
  12.     GPIO_Config(GPIOB, &gpioConfig);
  13.     GPIO_SetBit(GPIOB, GPIO_PIN_6);
  14. }

  15. // 应用初始化
  16. void app_init(void)
  17. {
  18.     bsp_iwdt_init(100, 1);
  19.     gpio_test();
  20. }

  21. // 应用任务
  22. void app_task(void)
  23. {
  24. }


详细代码,请查看附件!
IWDT.zip (2.12 MB, 下载次数: 0)



心跳回响 发表于 2025-9-7 23:01 | 显示全部楼层
楼主的代码写得可是真规范。
我的代码就没有边界检查
 楼主| 口天土立口 发表于 2025-9-8 09:06 | 显示全部楼层
心跳回响 发表于 2025-9-7 23:01
楼主的代码写得可是真规范。
我的代码就没有边界检查

在做高安全性的应用时,边界检查是最基本的要求,要养成良好的习惯
心跳回响 发表于 2025-9-20 21:50 | 显示全部楼层
学习了,谢谢楼主了
作业天敌在此 发表于 2025-10-1 10:09 | 显示全部楼层
代码中对于看门狗的配置和喂狗操作都很清楚,但是有没有考虑到异常情况下的处理,比如看门狗计数器溢出?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

45

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部