蓝桥杯的国赛会遇到多路AD采集的情况,这时候之前的单路采集的方式就不可用了,下面介绍两种多路采集的方式。
以第13届国赛为例
设置IN13与IN17为Single-ended
在Parameter Settings中
设置Clock Prescaler为Asynchronous clock mode divided by 2
设置Rank-Sampling Time为640.6 Cycles
- #include "main.h"
-
-
- extern ADC_HandleTypeDef hadc2;
-
-
- void ADC2_Init(void);
-
- uint32_t Get_Adc(void);
-
- uint32_t Get_PA4(void);
- uint32_t Get_PA5(void);
每次进行adc采集之前,重新配置一遍参数
- ADC_ChannelConfTypeDef sConfig = {0};
- sConfig.Channel = ADC_CHANNEL_17;
- sConfig.Rank = ADC_REGULAR_RANK_1;
- sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
- sConfig.SingleDiff = ADC_SINGLE_ENDED;
- sConfig.OffsetNumber = ADC_OFFSET_NONE;
- sConfig.Offset = 0;
- if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
- {
- Error_Handler();
- }
- GPIO_InitTypeDef GPIO_InitStruct = {0};
-
- GPIO_InitStruct.Pin = GPIO_PIN_4;
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
记住不要重复进行RCC的配置,否侧会卡死
- //这两个,不用加了
- __HAL_RCC_ADC12_CLK_ENABLE();
-
- __HAL_RCC_GPIOA_CLK_ENABLE();
- #include "ADC/bsp_adc.h"
- /**
- ******************************************************************************
- * @file adc.c
- * @brief This file provides code for the configuration
- * of the ADC instances.
- ******************************************************************************
- * @attention
- *
- *
© Copyright (c) 2024 STMicroelectronics.
- * All rights reserved.
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
-
- /* Includes ------------------------------------------------------------------*/
-
- /* USER CODE BEGIN 0 */
-
- /* USER CODE END 0 */
-
- ADC_HandleTypeDef hadc2;
-
- /* ADC2 init function */
- void ADC2_Init(void)
- {
-
- /* USER CODE BEGIN ADC2_Init 0 */
-
- /* USER CODE END ADC2_Init 0 */
-
- ADC_ChannelConfTypeDef sConfig = {0};
-
- /* USER CODE BEGIN ADC2_Init 1 */
-
- /* USER CODE END ADC2_Init 1 */
- /** Common config
- */
- hadc2.Instance = ADC2;
- hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
- hadc2.Init.Resolution = ADC_RESOLUTION_12B;
- hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
- hadc2.Init.GainCompensation = 0;
- hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
- hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
- hadc2.Init.LowPowerAutoWait = DISABLE;
- hadc2.Init.ContinuousConvMode = DISABLE;
- hadc2.Init.NbrOfConversion = 1;
- hadc2.Init.DiscontinuousConvMode = DISABLE;
- hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
- hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
- hadc2.Init.DMAContinuousRequests = DISABLE;
- hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;
- hadc2.Init.OversamplingMode = DISABLE;
- if (HAL_ADC_Init(&hadc2) != HAL_OK)
- {
- Error_Handler();
- }
- /** Configure Regular Channel
- */
- sConfig.Channel = ADC_CHANNEL_17;
- sConfig.Rank = ADC_REGULAR_RANK_1;
- sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
- sConfig.SingleDiff = ADC_SINGLE_ENDED;
- sConfig.OffsetNumber = ADC_OFFSET_NONE;
- sConfig.Offset = 0;
- if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN ADC2_Init 2 */
-
- /* USER CODE END ADC2_Init 2 */
-
- }
-
- void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
- {
-
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- if(adcHandle->Instance==ADC2)
- {
- /* USER CODE BEGIN ADC2_MspInit 0 */
-
- /* USER CODE END ADC2_MspInit 0 */
- /* ADC2 clock enable */
- __HAL_RCC_ADC12_CLK_ENABLE();
-
- __HAL_RCC_GPIOA_CLK_ENABLE();
- /**ADC2 GPIO Configuration
- PA4 ------> ADC2_IN17
- PA5 ------> ADC2_IN13
- */
- GPIO_InitStruct.Pin = GPIO_PIN_4;
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- /* USER CODE BEGIN ADC2_MspInit 1 */
-
- /* USER CODE END ADC2_MspInit 1 */
- }
- }
-
- void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
- {
-
- if(adcHandle->Instance==ADC2)
- {
- /* USER CODE BEGIN ADC2_MspDeInit 0 */
-
- /* USER CODE END ADC2_MspDeInit 0 */
- /* Peripheral clock disable */
- __HAL_RCC_ADC12_CLK_DISABLE();
-
- /**ADC2 GPIO Configuration
- PA4 ------> ADC2_IN17
- PA5 ------> ADC2_IN13
- */
- HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4);
-
- /* USER CODE BEGIN ADC2_MspDeInit 1 */
-
- /* USER CODE END ADC2_MspDeInit 1 */
- }
- }
-
- uint32_t Get_Adc(void)
- {
- uint32_t Adc_Value;
-
- HAL_ADC_Start(&hadc2);
- HAL_Delay(1);
- Adc_Value = HAL_ADC_GetValue(&hadc2);
-
- return Adc_Value;
- }
- uint32_t Get_PA4(void)
- {
- ADC_ChannelConfTypeDef sConfig = {0};
- sConfig.Channel = ADC_CHANNEL_17;
- sConfig.Rank = ADC_REGULAR_RANK_1;
- sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
- sConfig.SingleDiff = ADC_SINGLE_ENDED;
- sConfig.OffsetNumber = ADC_OFFSET_NONE;
- sConfig.Offset = 0;
- if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
- {
- Error_Handler();
- }
- GPIO_InitTypeDef GPIO_InitStruct = {0};
-
- /**ADC2 GPIO Configuration
- PA4 ------> ADC2_IN17
- PA5 ------> ADC2_IN13
- */
- GPIO_InitStruct.Pin = GPIO_PIN_4;
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
-
- return Get_Adc();
- }
- uint32_t Get_PA5(void)
- {
- ADC_ChannelConfTypeDef sConfig = {0};
- sConfig.Channel = ADC_CHANNEL_13;
- sConfig.Rank = ADC_REGULAR_RANK_1;
- sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
- sConfig.SingleDiff = ADC_SINGLE_ENDED;
- sConfig.OffsetNumber = ADC_OFFSET_NONE;
- sConfig.Offset = 0;
- if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
- {
- Error_Handler();
- }
- GPIO_InitTypeDef GPIO_InitStruct = {0};
-
- /**ADC2 GPIO Configuration
- PA4 ------> ADC2_IN17
- PA5 ------> ADC2_IN13
- */
- GPIO_InitStruct.Pin = GPIO_PIN_5;
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
-
- return Get_Adc();
- }
-
- /* USER CODE BEGIN 1 */
-
- /* USER CODE END 1 */
-
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
测试结果表明实验成功。
设置IN13与IN17为Single-ended
在Parameter Settings中
设置Clock Prescaler为Synchronous clock mode divided by 2
这里要将Number Of Conversion设置为2
这样就可以采集两个不同的通道了
因为需要循环采集两个ADC值,所以GetADC函数的参数是一个uint32_t指针类型
- #include "main.h"
-
-
- extern ADC_HandleTypeDef hadc2;
-
-
- void ADC2_Init(void);
- void GetADC(uint32_t *ADC_Val);
HAL_ADC_Start之后,在for循环内进行连续的HAL_ADC_GetValue,在这之前先等待一下不然可能出现通道AD对应错误的情况。
- void GetADC(uint32_t *ADC_Val)
- {
- HAL_ADC_Start(&hadc2);
- int i;
- for(i=0;i<2;i++)
- {
- HAL_Delay(1);
- ADC_Val[i] = HAL_ADC_GetValue(&hadc2);
-
- }
- }
- #include "ADC/bsp_adc.h"
- ADC_HandleTypeDef hadc2;
- void ADC2_Init(void)
- {
-
- /* USER CODE BEGIN ADC2_Init 0 */
-
- /* USER CODE END ADC2_Init 0 */
-
- ADC_ChannelConfTypeDef sConfig = {0};
-
- /* USER CODE BEGIN ADC2_Init 1 */
-
- /* USER CODE END ADC2_Init 1 */
- /** Common config
- */
- hadc2.Instance = ADC2;
- hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
- hadc2.Init.Resolution = ADC_RESOLUTION_12B;
- hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
- hadc2.Init.GainCompensation = 0;
- hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE;
- hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
- hadc2.Init.LowPowerAutoWait = DISABLE;
- hadc2.Init.ContinuousConvMode = DISABLE;
- hadc2.Init.NbrOfConversion = 2;
- hadc2.Init.DiscontinuousConvMode = DISABLE;
- hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
- hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
- hadc2.Init.DMAContinuousRequests = DISABLE;
- hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;
- hadc2.Init.OversamplingMode = DISABLE;
- if (HAL_ADC_Init(&hadc2) != HAL_OK)
- {
- Error_Handler();
- }
- /** Configure Regular Channel
- */
- sConfig.Channel = ADC_CHANNEL_17;
- sConfig.Rank = ADC_REGULAR_RANK_1;
- sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
- sConfig.SingleDiff = ADC_SINGLE_ENDED;
- sConfig.OffsetNumber = ADC_OFFSET_NONE;
- sConfig.Offset = 0;
- if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
- {
- Error_Handler();
- }
- /** Configure Regular Channel
- */
- sConfig.Channel = ADC_CHANNEL_13;
- sConfig.Rank = ADC_REGULAR_RANK_2;
- if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN ADC2_Init 2 */
-
- /* USER CODE END ADC2_Init 2 */
-
- }
-
- void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
- {
-
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- if(adcHandle->Instance==ADC2)
- {
- /* USER CODE BEGIN ADC2_MspInit 0 */
-
- /* USER CODE END ADC2_MspInit 0 */
- /* ADC2 clock enable */
- __HAL_RCC_ADC12_CLK_ENABLE();
-
- __HAL_RCC_GPIOA_CLK_ENABLE();
- /**ADC2 GPIO Configuration
- PA4 ------> ADC2_IN17
- PA5 ------> ADC2_IN13
- */
- GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- /* USER CODE BEGIN ADC2_MspInit 1 */
-
- /* USER CODE END ADC2_MspInit 1 */
- }
- }
-
- void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
- {
-
- if(adcHandle->Instance==ADC2)
- {
- /* USER CODE BEGIN ADC2_MspDeInit 0 */
-
- /* USER CODE END ADC2_MspDeInit 0 */
- /* Peripheral clock disable */
- __HAL_RCC_ADC12_CLK_DISABLE();
-
- /**ADC2 GPIO Configuration
- PA4 ------> ADC2_IN17
- PA5 ------> ADC2_IN13
- */
- HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4|GPIO_PIN_5);
-
- /* USER CODE BEGIN ADC2_MspDeInit 1 */
-
- /* USER CODE END ADC2_MspDeInit 1 */
- }
- }
-
-
-
- void GetADC(uint32_t *ADC_Val)
- {
- HAL_ADC_Start(&hadc2);
- int i;
- for(i=0;i<2;i++)
- {
- HAL_Delay(1);
- ADC_Val[i] = HAL_ADC_GetValue(&hadc2);
-
- }
- }
测试结果表明实验成功。
本文介绍了两种不同的AD多通道采集的办法,并实现了相关代码以及进行了验证,效果表明成功实现了多路的AD采集功能。