口天土立口 发表于 2025-9-6 16:59

APM32E030的IWDT驱动

本帖最后由 口天土立口 于 2025-9-7 18:32 编辑



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

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

/*
* @brief       独立看门狗初始化
*
* @param       timeout_ms: 看门狗超时时间
*            is_debug_stop: 调试是否停止
*
* @retval      None
*
*/
void bsp_iwdt_init(uint16_t timeout_ms, uint8_t is_debug_stop)
{
    uint32_t iwdt_clk = 40000;      /* 独立看门狗时钟为LSI 40KHz */
    IWDT_DIV_T div = IWDT_DIV_4;
    uint16_t reload = 0;
    float tmp = 0.0f;
   
    /* 最大26s超时时间 */
    if (timeout_ms > 26000) {
      return ;
    }
   
    /* 800ms以内 */
    if (timeout_ms <= 800) {
      div = IWDT_DIV_8;
      tmp = (float)iwdt_clk / 8;      /* 计数频率 */
      tmp = 1000.0f / tmp;            /* ms */
      reload = (float)timeout_ms / tmp;
    /* 3s以内 */
    } else if (timeout_ms <= 3000) {
      div = IWDT_DIV_32;
      tmp = (float)iwdt_clk / 32;   /* 计数频率 */
      tmp = 1000.0f / tmp;            /* ms */
      reload = (float)timeout_ms / tmp;
    /* 26s以内 */
    } else {
      div = IWDT_DIV_256;
      tmp = (float)iwdt_clk / 256;    /* 计数频率 */
      tmp = 1000.0f / tmp;            /* ms */
      reload = (float)timeout_ms / tmp;
    }
   
    /* 清独立看门狗复位标志 */
    if (RCM_ReadStatusFlag(RCM_FLAG_IWDTRST) != RESET) {
      RCM_ClearStatusFlag();
    }
    IWDT_EnableWriteAccess();
    IWDT_ConfigDivider(div);
    IWDT_ConfigReload(reload);
    IWDT_Refresh();
    IWDT_Enable();
   
    /* 调试时看门狗计数器是否停止工作 */
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_DBGMCU);
    if (is_debug_stop != 0) {
      DBG_EnableAPB1Periph(DBG_APB1_PER_IWDT_STOP);
    } else {
      DBG_DisableAPB1Periph(DBG_APB1_PER_IWDT_STOP);
    }
}/*
* @brief       看门狗喂狗
*
* @param       None
*
* @retval      None
*
*/
void bsp_iwdt_feed(void)
{
    IWDT_Refresh();
}

测试代码如下:
void gpio_test(void)
{
    GPIO_Config_T gpioConfig;
   
    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOB);
    GPIO_ConfigStructInit(&gpioConfig);
    gpioConfig.pin   = GPIO_PIN_6;
    gpioConfig.mode    = GPIO_MODE_OUT;
    gpioConfig.outtype = GPIO_OUT_TYPE_PP;
    gpioConfig.speed   = GPIO_SPEED_50MHz;
    gpioConfig.pupd    = GPIO_PUPD_NO;   
    GPIO_Config(GPIOB, &gpioConfig);
    GPIO_SetBit(GPIOB, GPIO_PIN_6);
}

// 应用初始化
void app_init(void)
{
    bsp_iwdt_init(100, 1);
    gpio_test();
}

// 应用任务
void app_task(void)
{
}


详细代码,请查看附件!




心跳回响 发表于 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

代码中对于看门狗的配置和喂狗操作都很清楚,但是有没有考虑到异常情况下的处理,比如看门狗计数器溢出?
页: [1]
查看完整版本: APM32E030的IWDT驱动