REF:
https://blog.csdn.net/A_Peaceful_Place/article/details/148075041
STM32cubeMX
IO 配置




Clock

Projects




Code
main.c
cpp
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "fdcan.h"
#include "i2c.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "usb.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
// ADC数据缓冲区 - DMA将数据直接写入这里
volatile uint16_t adc_buffer[ADC_BUFFER_SIZE];
volatile uint8_t adc_conversion_complete = 0;
// 处理后的电压值
float adc_voltage[ADC_CHANNEL_COUNT];
// 当前转换计数
volatile uint32_t adc_conversion_count = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
__IO uint32_t uhADCxConvertedValue = 0;
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_FDCAN1_Init();
MX_UART4_Init();
MX_USB_PCD_Init();
MX_I2C1_Init();
MX_SPI1_Init();
MX_TIM2_Init();
MX_USART1_UART_Init();
MX_USART3_UART_Init();
MX_SPI2_Init();
MX_ADC2_Init();
/* USER CODE BEGIN 2 */
//未执行校准可能导致偏移误差和增益误差。
//解决方法: 在初始化时调用校准函数:
HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);
//HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);
//HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);
//HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);
//HAL_ADC_Start_DMA(&hadc1,(uint32_t *)My_adcData,adc_max);
//HAL_ADC_Start_DMA(&hadc2,(uint32_t *)My_adcData2,adc_max2);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
ADC_Multich_Sample ();
//ADC_Multich_Sample2();
uint8_t text[30];
int text_lenth;
uint8_t text_ADC2[30];
int text_lenth_ADC2;
uint8_t text_ADC3[100]; //使用数组则OK,使用指针则异常。
int text_lenth_ADC3;
{
//// if (HAL_ADC_Start(&hadc2) != HAL_OK)
// if (HAL_ADC_Start(&hadc1) != HAL_OK)
// {
// /* Start Conversation Error */
// Error_Handler();
// }
//// if (HAL_ADC_PollForConversion(&hadc2, 10) != HAL_OK)
// if (HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)
// {
// /* End Of Conversion flag not set on time */
// Error_Handler();
// }
//// if ((HAL_ADC_GetState(&hadc2) & HAL_ADC_STATE_EOC_REG) == HAL_ADC_STATE_EOC_REG)
// if ((HAL_ADC_GetState(&hadc1) & HAL_ADC_STATE_EOC_REG) == HAL_ADC_STATE_EOC_REG)
// {
//// uhADCxConvertedValue = HAL_ADC_GetValue(&hadc2);
// uhADCxConvertedValue = HAL_ADC_GetValue(&hadc1);
// }
//
//// text_lenth = sprintf((char *) &text,"adc value: %d %dmV\r\n",uhADCxConvertedValue,(uhADCxConvertedValue*3300*11)>>16);
// //text_lenth = sprintf((char *) &text,"G431 adc value: %d %dmV\r\n",((uhADCxConvertedValue*16)>>4),(uhADCxConvertedValue*3300*10)>>16); //PA0
//
// printf("G431 adc value: %d, %dmV\r\n",((uhADCxConvertedValue*16)>>4),(uhADCxConvertedValue*3300*10)>>16);
//
//
}
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_6,GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_Delay(1000);
printf("Hello, World!\n\r");
printf("My_adcData = %d\n\r",My_adcData[4]);
// printf("My_adcData = %d\n\r",My_adcData[8]);
// printf("My_adcData = %d\n\r",My_adcData[12]);
// printf("My_adcData = %d\n\r",My_adcData[16]);
HAL_Delay(1000);
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
RCC_OscInitStruct.PLL.PLLN = 85;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV8;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
// DMA传输完成回调
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if (hadc->Instance == ADC1)
{
adc_conversion_complete = 1;
adc_conversion_count++;
}
}
// DMA传输半完成回调(如果使用循环缓冲)
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
// 可选:处理半缓冲区数据
}
int fputc(int ch, FILE *f)//fputc函数的定义。它接受两个参数:一个整数ch(代表要输出的字符),和一个FILE指针f(代表输出流)
{
HAL_UART_Transmit(&huart4, (uint8_t *)&ch, 1, 0xFFFF);//通过串口1将字符ch的地址转换为一个指向uint8_t的指针作为要发送数据的地址,发送一个字节,发送的有效时间为0xFFFF
return ch;//返回发送的字符。在标准的fputc实现中,通常返回写入的字符,或者在发生错误时返回EOF。在这里,它总是返回发送的字符ch,没有错误处理
}
//------------------------------------------------
//版权声明:本文为CSDN博主「小酒丸子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
//原文链接:https://blog.csdn.net/m0_69119438/article/details/136789290
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart4, &ch, 1, 0xffff);
return ch;
}
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
main.h
cpp
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.h
* @brief : Header for main.c file.
* This file contains the common defines of the application.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32g4xx_hal.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);
/* USER CODE BEGIN EFP */
int fputc(int ch, FILE *f);
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
adc.c
cpp
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file adc.c
* @brief This file provides code for the configuration
* of the ADC instances.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "adc.h"
/* USER CODE BEGIN 0 */
uint16_t My_adcData[adc_max]={0};
uint16_t My_adcData2[adc_max2]={0}; //这里一定要定义的uint16_t 的数据,因为我们在Cube选择的就是Half Word 类型的数据
struct adcValue_type adcValue ;
//------------------------------------------------
//版权声明:本文为CSDN博主「A_Peaceful_Place」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
//原文链接:https://blog.csdn.net/A_Peaceful_Place/article/details/148075041
/* USER CODE END 0 */
ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2;
DMA_HandleTypeDef hdma_adc1;
/* ADC1 init function */
void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.GainCompensation = 0;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 3;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = ENABLE;
hadc1.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_128;
hadc1.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_3;
hadc1.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
hadc1.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
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 Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_2;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
/* ADC2 init function */
void MX_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_DIV4;
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_4;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_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 */
}
static uint32_t HAL_RCC_ADC12_CLK_ENABLED=0;
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if(adcHandle->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspInit 0 */
/* USER CODE END ADC1_MspInit 0 */
/** Initializes the peripherals clocks
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12;
PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* ADC1 clock enable */
HAL_RCC_ADC12_CLK_ENABLED++;
if(HAL_RCC_ADC12_CLK_ENABLED==1){
__HAL_RCC_ADC12_CLK_ENABLE();
}
__HAL_RCC_GPIOA_CLK_ENABLE();
/**ADC1 GPIO Configuration
PA0 ------> ADC1_IN1
PA1 ------> ADC1_IN2
PA2 ------> ADC1_IN3
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* ADC1 DMA Init */
/* ADC1 Init */
hdma_adc1.Instance = DMA1_Channel1;
hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}
else if(adcHandle->Instance==ADC2)
{
/* USER CODE BEGIN ADC2_MspInit 0 */
/* USER CODE END ADC2_MspInit 0 */
/** Initializes the peripherals clocks
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12;
PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* ADC2 clock enable */
HAL_RCC_ADC12_CLK_ENABLED++;
if(HAL_RCC_ADC12_CLK_ENABLED==1){
__HAL_RCC_ADC12_CLK_ENABLE();
}
__HAL_RCC_GPIOA_CLK_ENABLE();
/**ADC2 GPIO Configuration
PA7 ------> ADC2_IN4
*/
GPIO_InitStruct.Pin = GPIO_PIN_7;
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==ADC1)
{
/* USER CODE BEGIN ADC1_MspDeInit 0 */
/* USER CODE END ADC1_MspDeInit 0 */
/* Peripheral clock disable */
HAL_RCC_ADC12_CLK_ENABLED--;
if(HAL_RCC_ADC12_CLK_ENABLED==0){
__HAL_RCC_ADC12_CLK_DISABLE();
}
/**ADC1 GPIO Configuration
PA0 ------> ADC1_IN1
PA1 ------> ADC1_IN2
PA2 ------> ADC1_IN3
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2);
/* ADC1 DMA DeInit */
HAL_DMA_DeInit(adcHandle->DMA_Handle);
/* USER CODE BEGIN ADC1_MspDeInit 1 */
/* USER CODE END ADC1_MspDeInit 1 */
}
else if(adcHandle->Instance==ADC2)
{
/* USER CODE BEGIN ADC2_MspDeInit 0 */
/* USER CODE END ADC2_MspDeInit 0 */
/* Peripheral clock disable */
HAL_RCC_ADC12_CLK_ENABLED--;
if(HAL_RCC_ADC12_CLK_ENABLED==0){
__HAL_RCC_ADC12_CLK_DISABLE();
}
/**ADC2 GPIO Configuration
PA7 ------> ADC2_IN4
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_7);
/* USER CODE BEGIN ADC2_MspDeInit 1 */
/* USER CODE END ADC2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/*
*adc数据处理
*
*/
void ADC_Multich_Sample (void)
{
printf(" %s==== ,%d \n\r",__func__,__LINE__);
// 函数减速,用来防止程序阻塞
static uint32_t ADC_Tick1;
if(uwTick - ADC_Tick1 < 5)
return;
ADC_Tick1 = uwTick;
// 函数减速结束
adcValue .value1=0;
adcValue .value2=0;
adcValue .value3=0;
adcValue .value4 =0;
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)My_adcData,adc_max);//因为你选择的软件触发,所以每次采集都需要开启一次
printf(" %s==== ,%d \n\r",__func__,__LINE__);
static uint8_t i;
adcValue .value1 = (My_adcData[0]>>4)*3300/4096; // data alignment = right alignment; ADC 12 bit; 16 bit data length. so need be removed 4 bit to right for 12 bit ADC;
adcValue .value2 = (My_adcData[4]>>4)*3300/4096;
adcValue .value3 = (My_adcData[8]>>4)*3300/4096;
printf("adcValue .value1 = %d\n\r",adcValue .value1);
printf("adcValue .value2 = %d\n\r",adcValue .value2);
printf("adcValue .value3 = %d\n\r",adcValue .value3);
//函数消除干扰,舍去微小电压
if(adcValue .value1<5)adcValue .value1=0;
if(adcValue .value2<5)adcValue .value2=0;
if(adcValue .value3<5)adcValue .value3=0;
//if(adcValue .value4<5)adcValue .value4=0;
// printf(" %s==== ,%d \n\r",__func__,__LINE__);
}
void ADC_Multich_Sample2(void)
{
printf("ADC_Multich_Sample2 %s==== ,%d \n\r",__func__,__LINE__);
static uint32_t ADC_Tick2;
if(uwTick - ADC_Tick2 < 10)
return;
ADC_Tick2 = uwTick;
adcValue .value5=adcValue .value6=adcValue .value7=adcValue .value8 =0;
HAL_ADC_Start_DMA(&hadc2, (uint32_t *)My_adcData2,adc_max2);
static uint8_t m;
for(m=1;m<=8;m++){ //遍历8次,进行滤波
adcValue .value5 += My_adcData2[0+4*m]*330/4096;
adcValue .value6 += My_adcData2[1+4*m]*330/4096;
adcValue .value7 += My_adcData2[2+4*m]*330/4096;
//adcValue .value8 += My_adcData2[3+4*m]*330/4096;
}
adcValue .value5 = adcValue .value5/8 ;
adcValue .value6 = adcValue .value6/8 ;
adcValue .value7 = adcValue .value7/8 ;
//adcValue .value8 = adcValue .value8/8 ;
if(adcValue .value5<5)adcValue .value5=0;
if(adcValue .value6<5)adcValue .value6=0;
if(adcValue .value7<5)adcValue .value7=0;
//if(adcValue .value8<5)adcValue .value8=0;
}
//------------------------------------------------
//版权声明:本文为CSDN博主「A_Peaceful_Place」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
//原文链接:https://blog.csdn.net/A_Peaceful_Place/article/details/148075041
/* USER CODE END 1 */
adc.h
cpp
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file adc.h
* @brief This file contains all the function prototypes for
* the adc.c file
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __ADC_H__
#define __ADC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern ADC_HandleTypeDef hadc1;
extern ADC_HandleTypeDef hadc2;
/* USER CODE BEGIN Private defines */
// ADC相关定义
#define ADC_CHANNEL_COUNT 4
#define ADC_BUFFER_SIZE ADC_CHANNEL_COUNT * 10
// 外部变量声明
extern ADC_HandleTypeDef hadc1;
extern DMA_HandleTypeDef hdma_adc1;
// ADC数据缓冲区
extern volatile uint16_t adc_buffer[ADC_BUFFER_SIZE];
extern volatile uint8_t adc_conversion_complete;
// 处理后的数据
extern float adc_voltage[ADC_CHANNEL_COUNT];
/* USER CODE END Private defines */
void MX_ADC1_Init(void);
void MX_ADC2_Init(void);
/* USER CODE BEGIN Prototypes */
#define adc_max 40
#define adc_max2 40
extern uint16_t My_adcData[adc_max];
extern uint16_t My_adcData2[adc_max2];
struct adcValue_type
{
uint16_t value1;
uint16_t value2;
uint16_t value3;
uint16_t value4;
uint16_t value5;
uint16_t value6;
uint16_t value7;
uint16_t value8;
};
extern struct adcValue_type adcValue;
void ADC_Multich_Sample (void);
void ADC_Multich_Sample2(void);
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __ADC_H__ */
log printf
ADC PA0\PA1\PA2.
PA0 连接3.3V,其他两个悬空。
cpp
ADC_Multich_Sample==== ,336
ADC_Multich_Sample==== ,350
adcValue .value1 = 3295
adcValue .value2 = 14
adcValue .value3 = 0