[STM32H5] 【STM32 Nucleo-64测评】2 ADC单端 采集电位器信号 测试

[复制链接]
 楼主| 尹小舟 发表于 2024-7-31 14:12 | 显示全部楼层 |阅读模式
<
本帖最后由 尹小舟 于 2024-7-31 14:23 编辑

STM32H533xx 系列有 2 个 ADC,都可以独立工作
5578666a9d5c8c9697.png



  STM32H533,作为STM32系列的高端微控制器之一,继承了ST在模拟信号处理方面的强大能力。
      STM32H533支持模拟看门狗功能。模拟看门狗是一种用于监控模拟输入信号的安全机制,当被监控的模拟信号超出预设的阈值(高阈值或低阈值)时,可以触发中断或复位信号。这对于保护系统免受过压、欠压或其他潜在危险条件的影响至关重要。
       STM32H533还支持硬件过采样功能,以进一步提高ADC的精度和性能。硬件过采样是一种通过增加采样次数并对结果进行平均来降低噪声和量化误差的技术。在STM32H533中,这种功能可能通过ADC的配置寄存器来启用和配置。通过硬件过采样,STM32H533能够在不增加CPU负担的情况下,提高ADC的分辨率和测量精度。这对于需要高精度模拟信号处理的应用程序来说非常有用,如传感器读数、精密测量和控制系统等。
API 介绍:
HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc)
      在使用ADC之前,必须先配置ADC的时钟。这通常在RCC(复位和时钟控制)的顶层进行配置。RCC配置ADC的具体细节可以在该文件的头注释中找到。ADC的正确时钟配置是ADC正常工作的基础。
      HAL_ADC_Init()函数在ADC从复位状态启动时,会调用HAL_ADC_MspInit()来初始化ADC的MSP(微控制器特定包)部分。但是,如果在ADC已经初始化之后再次调用HAL_ADC_Init(),它不会重新调用HAL_ADC_MspInit(),除非ADC被重置。这意味着你可以在ADC运行时动态地更新ADC_InitTypeDef结构体中的某些参数,而不需要重新配置MSP。
HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, const ADC_ChannelConfTypeDef *pConfig)
调用函数HAL_ADC_Init配置了基础功能后,就可以调用此函数配置ADC的具体通道了。

HAL_StatusTypeDef HAL_ADCEx_Calibration_Start (ADC_HandleTypeDef * hadc, uint32_t SingleDiff)
在使用ADC之前,需要对其进行校准以提高精度,这个函数用于启动ADC校准过程。
校准前提:ADC必须禁用(在HAL_ADC_Start()之前或在HAL_ADC_Stop()之后执行此函数).



HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig (const RCC_PeriphCLKInitTypeDef * pPeriphClkInit)
外设时钟初始化函数,当选择RTC时钟源时,需要注意:在这种情况下,会使能对Backup域的访问。

硬件分配


9321966a9d4e7c242a.png 4209766a9d54a98c33.png
采集电位器信号,GPIO口PA0




代码实现


结构体与变量定义
  1. ADC_HandleTypeDef hadc1;
  2. uint32_t                 uhADCxConvertedData;
  3. int32_t                  uhADCxConvertedData_Voltage_mVolt;


ADC 初始化
  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url] ADC1 Initialization Function
  3.   * @param None
  4.   * @retval None
  5.   */
  6. static void MX_ADC1_Init(void)
  7. {

  8.   /* USER CODE BEGIN ADC1_Init 0 */

  9.   /* USER CODE END ADC1_Init 0 */

  10.   ADC_ChannelConfTypeDef sConfig = {0};

  11.   /* USER CODE BEGIN ADC1_Init 1 */

  12.   /* USER CODE END ADC1_Init 1 */

  13.   /** Common config
  14.   */
  15.   hadc1.Instance = ADC1;
  16.   hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  17.   hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  18.   hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  19.   hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  20.   hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  21.   hadc1.Init.LowPowerAutoWait = DISABLE;
  22.   hadc1.Init.ContinuousConvMode = ENABLE;
  23.   hadc1.Init.NbrOfConversion = 1;
  24.   hadc1.Init.DiscontinuousConvMode = DISABLE;
  25.   hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  26.   hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  27.   hadc1.Init.DMAContinuousRequests = DISABLE;
  28.   hadc1.Init.SamplingMode = ADC_SAMPLING_MODE_NORMAL;
  29.   hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  30.   hadc1.Init.OversamplingMode = DISABLE;
  31.   if (HAL_ADC_Init(&hadc1) != HAL_OK)
  32.   {
  33.     Error_Handler();
  34.   }

  35.   /** Configure Regular Channel
  36.   */
  37.   sConfig.Channel = ADC_CHANNEL_0;
  38.   sConfig.Rank = ADC_REGULAR_RANK_1;
  39.   sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
  40.   sConfig.SingleDiff = ADC_SINGLE_ENDED;
  41.   sConfig.OffsetNumber = ADC_OFFSET_NONE;
  42.   sConfig.Offset = 0;
  43.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  44.   {
  45.     Error_Handler();
  46.   }
  47.   /* USER CODE BEGIN ADC1_Init 2 */
  48.   if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_DIFFERENTIAL_ENDED) != HAL_OK)
  49.   {
  50.     Error_Handler();
  51.   }

  52.   if (HAL_ADC_Start(&hadc1) != HAL_OK)
  53.   {
  54.     Error_Handler();
  55.   }
  56.   /* USER CODE END ADC1_Init 2 */

  57. }



  1. /* USER CODE BEGIN 1 */

  2.   /* USER CODE END 1 */

  3.   /* MCU Configuration--------------------------------------------------------*/

  4.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  5.   HAL_Init();

  6.   /* USER CODE BEGIN Init */

  7.   /* USER CODE END Init */

  8.   /* Configure the system clock */
  9.   SystemClock_Config();

  10.   /* USER CODE BEGIN SysInit */

  11.   /* USER CODE END SysInit */

  12.   /* Initialize all configured peripherals */
  13.   MX_GPIO_Init();
  14.   MX_ICACHE_Init();
  15.         MX_ADC1_Init();
  16.   /* USER CODE BEGIN 2 */

  17.   /* USER CODE END 2 */

  18.   /* Initialize leds */
  19.   BSP_LED_Init(LED_GREEN);

  20.   /* Initialize USER push-button, will be used to trigger an interrupt each time it's pressed.*/
  21.   BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);

  22.   /* Initialize COM1 port (115200, 8 bits (7-bit data + 1 stop bit), no parity */
  23.   BspCOMInit.BaudRate   = 115200;
  24.   BspCOMInit.WordLength = COM_WORDLENGTH_8B;
  25.   BspCOMInit.StopBits   = COM_STOPBITS_1;
  26.   BspCOMInit.Parity     = COM_PARITY_NONE;
  27.   BspCOMInit.HwFlowCtl  = COM_HWCONTROL_NONE;
  28.   if (BSP_COM_Init(COM1, &BspCOMInit) != BSP_ERROR_NONE)
  29.   {
  30.     Error_Handler();
  31.   }

  32.   /* USER CODE BEGIN BSP */

  33.   /* -- Sample board code to send message over COM1 port ---- */
  34.   printf("Welcome to STM32 world !\n");

  35.   /* Switch on leds */
  36.   BSP_LED_On(LED_GREEN);

  37.   /* USER CODE END BSP */

  38.   /* Infinite loop */
  39.   /* USER CODE BEGIN WHILE */
  40.   while (1)
  41.   {
  42.     /* -- Sample board code for User push-button in interrupt mode ---- */
  43.     if (BspButtonState == BUTTON_PRESSED)
  44.     {
  45.       /* Update button state */
  46.       BspButtonState = BUTTON_RELEASED;
  47.       /* -- Sample board code to toggle leds ---- */
  48.       BSP_LED_Toggle(LED_GREEN);
  49.       /* ..... Perform your action ..... */

  50.     }
  51.                 if (HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)
  52.     {
  53.       Error_Handler();
  54.     }

  55.     /* Read the converted value */
  56.     uhADCxConvertedData = HAL_ADC_GetValue(&hadc1);

  57.     /* Computation of ADC conversions raw data to physical values             */
  58.     /* using helper macro.                                                    */
  59.     uhADCxConvertedData_Voltage_mVolt = __HAL_ADC_CALC_DIFF_DATA_TO_VOLTAGE(VDDA_APPLI, uhADCxConvertedData, ADC_RESOLUTION_12B);
  60.                 printf("A0 Value = %d,Voltage = %d",uhADCxConvertedData,uhADCxConvertedData_Voltage_mVolt);
  61.                 HAL_Delay(300);
  62.    
  63.   }




8055066a9d6cd05df1.png 6156366a9d832e03cb.png

有好大误差,后面看看,出在那里





评论

2383/4095*3.3=1.92  发表于 2024-8-14 13:42
FranklinUNK 发表于 2024-8-14 09:47 来自手机 | 显示全部楼层
是不是没执行校准函数啊
MessageRing 发表于 2024-8-14 09:52 来自手机 | 显示全部楼层
ADC怎么配置同时采集数据啊?
OliviaSH 发表于 2024-8-14 09:58 来自手机 | 显示全部楼层
FranklinUNK 发表于 2024-8-14 09:47
是不是没执行校准函数啊

看着程序里执行校准了
呐咯密密 发表于 2024-8-14 13:42 | 显示全部楼层
你这采集的值没问题啊,你没做转换
 楼主| 尹小舟 发表于 2024-8-14 14:51 | 显示全部楼层
1815366bc53e8d953a.png
相差好多呢
狄克爱老虎油 发表于 2024-8-17 23:45 来自手机 | 显示全部楼层
应该执行校准了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

94

帖子

2

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