这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » NUCLEO-U083RC学习历程28-模拟看门狗监测内部ADC功能

共2条 1/1 1 跳转至

NUCLEO-U083RC学习历程28-模拟看门狗监测内部ADC功能

助工
2025-02-16 10:00:14     打赏

今天和大家分享一下使用内部的模拟看门口监测内部ADC阈值的方法。

首先简单和大家分享一下,STM32内部几种看门狗的知识和区别;

STM32微控制器中的看门狗(Watchdog)用于监控系统运行状态,防止程序跑飞或死锁。STM32提供了三种看门狗:独立看门狗(IWDG)、窗口看门狗(WWDG)和模拟看门狗(Analog Watchdog)。它们的主要区别如下:

1. 独立看门狗(IWDG)

功能:独立看门狗是一个简单的定时器,用于检测系统是否正常运行。如果系统未在规定时间内刷新看门狗,看门狗将复位系统。

时钟源:使用独立的低速内部时钟(LSI),频率通常为32kHz,不受主时钟影响。

配置:可设置超时时间,超时后复位系统。

应用场景:适用于需要高可靠性的系统,确保系统在异常情况下复位。

2. 窗口看门狗(WWDG)

功能:窗口看门狗不仅要求在规定时间内刷新,还要求在特定时间窗口内刷新。过早或过晚刷新都会导致复位。

时钟源:使用APB1总线时钟,频率较高。

配置:可设置窗口的上限和下限,刷新时间必须在窗口内。

应用场景:适用于需要精确监控任务执行时间的系统,确保任务按时完成。

3. 模拟看门狗(Analog Watchdog)

功能:模拟看门狗用于监控模拟信号(如ADC输入),当信号超出设定范围时触发中断或事件。

时钟源:无独立时钟,依赖ADC模块。

配置:可设置上下限阈值,监控模拟信号是否在范围内。

应用场景:适用于需要监控模拟信号的应用,如电池电压、温度传感器等。

总结:

独立看门狗:简单可靠,适用于系统复位。

串口看门狗:精确监控任务执行时间,适用于时间敏感任务。

模拟看门狗:监控模拟信号,适用于模拟信号监控。

根据具体需求选择合适的看门狗类型。

今天重点和大家分享模拟看门狗的知识;我们可以在STM32cube MX 中开启模拟看门狗功能;如下所示:

0216-1.png

配置一下ADC1的基本参数,如下所示:

0216-2.png

软件代码如下所示:

初始化ADC参数,开始模拟看门狗的功能,配置ADC引脚功能,这里需要注意一下,ADC引脚需要配置成输入模式;

static void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_AnalogWDGConfTypeDef AnalogWDGConfig = {0};
  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.LowPowerAutoPowerOff = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;
  hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
  hadc1.Init.OversamplingMode = DISABLE;
  hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Analog WatchDog 1
  */
  AnalogWDGConfig.WatchdogNumber = ADC_ANALOGWATCHDOG_1;
  AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_ALL_REG;
  AnalogWDGConfig.ITMode = ENABLE;
  AnalogWDGConfig.HighThreshold = ADC_AWD_THRESHOLD_HIGH;
  AnalogWDGConfig.LowThreshold = ADC_AWD_THRESHOLD_LOW;
  if (HAL_ADC_AnalogWDGConfig(&hadc1, &AnalogWDGConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

软件代码监控ADC值的代码监测:

/**
  * @brief  Rearm ADC analog watchdog to make it ready another trig
  *         (ADC handle: hadc1, analog watchdog instance: AWD1).
  * @param  None
  * @retval None
  */
void ADC_AnalogWatchdog_Rearm(void)
{
  /* Clear flag ADC analog watchdog 1 */
  __HAL_ADC_CLEAR_FLAG(&hadc1, ADC_FLAG_AWD1);

  /* Enable ADC analog watchdog 1 interruption */
  __HAL_ADC_ENABLE_IT(&hadc1, ADC_IT_AWD1);
}

/******************************************************************************/
/*   USER IRQ HANDLER TREATMENT                                               */
/******************************************************************************/

/**
  * @brief  Analog watchdog callback in non blocking mode.
  * @param  hadc: ADC handle
  * @retval None
  */
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
{
  /* Disable ADC analog watchdog 1 interruption */
  /* Note: ADC analog watchdog 1 interruption rearmed afterwards after
           event processing completion */
  __HAL_ADC_DISABLE_IT(hadc, ADC_IT_AWD1);

  /* Retrieve ADC conversion data */
  /* Note: data scale corresponds to ADC resolution */
  uhADCxConvertedData = HAL_ADC_GetValue(hadc);

  /* Update status variable of ADC analog watchdog 1 */
  ubAnalogWatchdog1Status = 1;

  /* Change LED toggle frequency depending on voltage below or above
     analog watchdog window */
  if (uhADCxConvertedData > ADC_AWD_THRESHOLD_HIGH)
  {
    led_toggle_period_ms = LED_BLINK_VERY_FAST;
  }
  else /* (uhADCxConvertedData < ADC_AWD_THRESHOLD_LOW) */
  {
    led_toggle_period_ms = LED_BLINK_FAST;
  }

  /* Set ADC analog watchdog rearm delay iterations count */
  adc_awd_rearm_delay_iterations_count = (ADC_AWD_REARM_DELAY_MS / led_toggle_period_ms);
}

主程序代码如下所示:

    if(ubAnalogWatchdog1Status == 1)
    {
      /* Wait for ADC analog watchdog rearm */
      adc_awd_rearm_delay_iterations_count--;
      if(adc_awd_rearm_delay_iterations_count == 0)
      {
        led_toggle_period_ms = LED_BLINK_SLOW;

        /* Reset status variable of ADC analog watchdog 1 */
        ubAnalogWatchdog1Status = 0;

        /* Rearm ADC analog watchdog to make it ready for another trig */
        ADC_AnalogWatchdog_Rearm();
      }
    }

    BSP_LED_Toggle(LED4);
    HAL_Delay(led_toggle_period_ms);

实物验证如下: 

如下图所示:将电位器模块接入到STM32U083RC的开发板上,旋转电位器可以看到LED灯不同效果的闪烁过程。

整个测试的试验流程:从主程序执行开始,ADC连续转化所选的通道4,当内部ADC监测到超出模拟看门狗窗口时,CPU产生ADC中断,并调用模拟看门狗回调函数来处理事件,处理时间间隔5秒,ADC模拟看门口重新准备,为下次产生ADC中断做好准备。

为了方便看到ADC的检测值的数据,这里i用LED灯的闪烁频率间接显示数据:

LED4 用于监控程序执行状态:

正常工作:可以通过 LED 切换频率观察 ADC 通道监控通道窗口与模拟看门狗窗口的电压:模拟看门狗窗口内的电压:切换频率慢 (2Hz)

电压低于模拟看门狗窗口:快速切换频率 (10Hz)

电压高于模拟看门狗窗口:切换频率非常快 (20Hz)

错误:LED 指示灯仍亮起

0216-1.jpg




关键词: NUCLEO-U083RC     模拟看门口     ADC监测    

专家
2025-02-16 20:02:15     打赏
2楼

感谢分享


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]