1704|8

25

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【STM32H5开发板】5. 使用精密可调电位器与LED测试ADC采集转换 [复制链接]

这个试验之前很早就做过,因为操作不慎所拍照片和视频丢失。所以很多原始的资料素材丢失了。这次刚好有时间,再重新做一下这个试验。

 

1. STM32H5开发板 ADC资源

首先查看 STM32H5开发板 上ADC资源情况 ,

 可以看出它有两组独立的ADC转换器,支持12bit 采样,并且采样速度可达到 5Msps

可以使用PC0~5 引脚

 

2.测试连线图

这里使用一个精密可调电阻器,电阻器固定端阻值是1K,通过多圈旋钮调节中间输出的位置,电阻器接3.3V,可调端则可以得到 0 ~3.3v 电压范围。

这是试验电路图如下,

 

3.测试代码实现

为了使得ADC 在外部点位器调节时可以看到,这里使用 LED1 的闪烁频率来标识其外部的电压大小,方法是当输入电压值大时,LED闪烁频率变高,ADC测量值低时,LED闪烁频率变低

实现代码如下:

#include "main.h"


  #define VDDA_APPLI                       (3300UL)

/* Definitions of data related to this example */
  /* Definition of ADCx analog watchdog window thresholds */
  #define ADC_AWD_THRESHOLD_HIGH           (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B) / 2) /* Value of ADC analog watchdog threshold high */
  #define ADC_AWD_THRESHOLD_LOW            (   0UL) /* Value of ADC analog watchdog threshold low */

  /* Init variable out of expected ADC conversion data range */
  #define VAR_CONVERTED_DATA_INIT_VALUE    (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B) + 1)
  #define ADC_AWD_REARM_DELAY_MS           (5000UL) /* ADC analog watchdog rearm delay (unit: ms) */

ADC_HandleTypeDef hadc1;

__IO uint16_t uhADCxConvertedData = VAR_CONVERTED_DATA_INIT_VALUE; /* ADC group regular conversion data */
                                 */
__IO uint8_t ubAnalogWatchdog1Status = 0U; 

uint32_t led_toggle_period_ms = LED_BLINK_SLOW; /* LED toggle period (unit: ms) */
uint32_t adc_awd_rearm_delay_iterations_count; 

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ICACHE_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN PFP */

void ADC_AnalogWatchdog_Rearm(void);
void LED_On(void);
void LED_Off(void);
void LED_Toggle(void);

/* USER CODE END PFP */

int main(void)
{
   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ICACHE_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */

  /* Initialize LED on board */
  BSP_LED_Init(LED1);

  /* Perform ADC calibration */
  if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK)
  {
    /* Calibration Error */
    Error_Handler();
  }

  /* Start ADC group regular conversion */
  if (HAL_ADC_Start(&hadc1) != HAL_OK)
  {
   
    Error_Handler();
  }

  while (1)
  {
    /* Process analog watchdog out of window event */
    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(LED1);
    HAL_Delay(led_toggle_period_ms);

  }
  /* USER CODE END 3 */
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS_DIGITAL;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 250;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_1;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_PCLK3;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_ADC1_Init(void)
{

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

 
  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.ContinuousConvMode = ENABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.SamplingMode = ADC_SAMPLING_MODE_NORMAL;
  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure the ADC multi-mode
  */
  multimode.Mode = ADC_MODE_INDEPENDENT;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != 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;
  AnalogWDGConfig.FilteringConfig = ADC_AWD_FILTERING_NONE;
  if (HAL_ADC_AnalogWDGConfig(&hadc1, &AnalogWDGConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_10;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
 
}

static void MX_ICACHE_Init(void)
{

  if (HAL_ICACHE_Enable() != HAL_OK)
  {
    Error_Handler();
  }
 
}

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : LED1_Pin */
  GPIO_InitStruct.Pin = LED1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct);

}
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);
}

void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
{
   __HAL_ADC_DISABLE_IT(hadc, ADC_IT_AWD1);
   uhADCxConvertedData = HAL_ADC_GetValue(hadc);

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

  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;
  }

 
  adc_awd_rearm_delay_iterations_count = (ADC_AWD_REARM_DELAY_MS / led_toggle_period_ms);
}

void Error_Handler(void)
{
 
  while (1)
  {
    BSP_LED_On(LED1);
  }
 
}

#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)
{
 
  while (1)
  {
  }

}
#endif 

 

4.运行效果

经过调试,达到测试目标,最终测试试验如下图:

 

此帖出自stm32/stm8论坛

最新回复

这精度还挺不错的,挺多场景都能用的上。   详情 回复 发表于 2023-7-11 09:04
点赞 关注
 

回复
举报

2万

帖子

340

TA的资源

版主

沙发
 

“ LED1 的闪烁频率来标识其外部的电压大小”

怎么标识的

 

此帖出自stm32/stm8论坛

点评

一个简单的算法,就是 LED  on 之后delay 的时间,根据输入电压来换算, 50ms = 2.8v  2000 ms=0.1V, 一个线性计算就出来了  详情 回复 发表于 2023-7-10 22:09
估计就能看出个趋势,是电阻变大了还是变小了  详情 回复 发表于 2023-7-8 23:17
 
 

回复

6532

帖子

9

TA的资源

版主

板凳
 

LED的频闪设计是是重点了,太快就和常量一样了 

此帖出自stm32/stm8论坛
 
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 

回复

6532

帖子

9

TA的资源

版主

4
 
qwqwqw2088 发表于 2023-7-8 17:49 “ LED1 的闪烁频率来标识其外部的电压大小” 怎么标识的  

估计就能看出个趋势,是电阻变大了还是变小了

此帖出自stm32/stm8论坛

点评

对,不精确但直观,精确的值靠串口输出,串口是在这个之后调通的。   详情 回复 发表于 2023-7-10 22:10
 
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 

回复

7244

帖子

2

TA的资源

版主

5
 

你这个可调电位器的精度是多少?

此帖出自stm32/stm8论坛

点评

这个可调电阻的范围是  0 ~1000 欧,这个这个范围最小到最大它大概要转 8 圈,也就是  8 * 360 =  2880 度,也就是 旋钮每转1度,可以改变 0.347 欧的阻值。 实际使用时,因为受到温度的影响,环  详情 回复 发表于 2023-7-10 22:14
 
 
 

回复

25

帖子

0

TA的资源

一粒金砂(中级)

6
 
qwqwqw2088 发表于 2023-7-8 17:49 “ LED1 的闪烁频率来标识其外部的电压大小” 怎么标识的  

一个简单的算法,就是 LED  on 之后delay 的时间,根据输入电压来换算, 50ms = 2.8v  2000 ms=0.1V, 一个线性计算就出来了

此帖出自stm32/stm8论坛
 
 
 

回复

25

帖子

0

TA的资源

一粒金砂(中级)

7
 
秦天qintian0303 发表于 2023-7-8 23:17 估计就能看出个趋势,是电阻变大了还是变小了

对,不精确但直观,精确的值靠串口输出,串口是在这个之后调通的。 

此帖出自stm32/stm8论坛
 
 
 

回复

25

帖子

0

TA的资源

一粒金砂(中级)

8
 
本帖最后由 大涂涂 于 2023-7-10 22:17 编辑
wangerxian 发表于 2023-7-10 14:36 你这个可调电位器的精度是多少?

这个可调电阻的范围是  200 ~1000 欧,这个范围最小到最大它大概要转 8 圈,也就是  8 * 360 =  2880 度,也就是 旋钮每转1度,可以改变 0.277 欧的阻值。

实际使用时,因为受到温度的影响,环境温度对它大概有  5% ,(15度变化) 的影响。因此在固定环境温度下可以算是精密电位器了

此帖出自stm32/stm8论坛

点评

这精度还挺不错的,挺多场景都能用的上。  详情 回复 发表于 2023-7-11 09:04
 
 
 

回复

7244

帖子

2

TA的资源

版主

9
 
大涂涂 发表于 2023-7-10 22:14 这个可调电阻的范围是  200 ~1000 欧,这个范围最小到最大它大概要转 8 圈,也就是  8 ...

这精度还挺不错的,挺多场景都能用的上。

此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表