tpgf 发表于 2025-1-7 10:51

stm32G474的使用STM32CubeMX生成代码进行ADC DMA连续采集

一、背景介绍   

   stm32G474VET6含有5个12bit分辨率的ADC,可以采集单端或差分模拟信号。联合DMA使用,可以有效降低系统资源占用。

二、STM32CubeMX配置

第一步:选择时钟来源



第二步:选择ADC3的通道1至通道4,10通道,14通道为单端输入信号



第三步:设置ADC参数,ADC设置为12位分辨率,数据右对齐,连续转换模式使能、扫描模式使能、数据循环覆盖



第四步:配置每排对应的通道、采样时间



第五步:配置DMA参数,循环采集,数据宽度为Half Word,DMA的传输方向为从Peripheral to Memory



第六步​:开启DMA全局中断,并配置优先级​。优先级需要再System Core中的NVIC中修改



第七步​:根据自身的需求修改时钟树,配置ADC的时钟​。注意:ADC的最大工作频率是有限制的



第八步​:生成代码,开启ADC的采集​。STM32cubmx只是对外设进行了初始化​。

/** Common config
*/
hadc3.Instance = ADC3;
hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
hadc3.Init.Resolution = ADC_RESOLUTION_12B;
hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc3.Init.GainCompensation = 0;
hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc3.Init.LowPowerAutoWait = DISABLE;
hadc3.Init.ContinuousConvMode = ENABLE;
hadc3.Init.NbrOfConversion = 6;
hadc3.Init.DiscontinuousConvMode = DISABLE;
hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc3.Init.DMAContinuousRequests = ENABLE;
hadc3.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc3.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc3) != HAL_OK)
{
    Error_Handler();
}

/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc3, &multimode) != HAL_OK)
{
    Error_Handler();
}

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

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
    Error_Handler();
}



DMA的参数设置
   /* ADC3 DMA Init */
    /* ADC3 Init */
    hdma_adc3.Instance = DMA1_Channel1;
    hdma_adc3.Init.Request = DMA_REQUEST_ADC3;
    hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc3.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_adc3.Init.Mode = DMA_CIRCULAR;
    hdma_adc3.Init.Priority = DMA_PRIORITY_MEDIUM;
    if (HAL_DMA_Init(&hdma_adc3) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc3);//

第八步​:ADC进行刻度,然后开启ADC和DMA进行采集, 6个通道,每个通道采集10个数方便滤波​。

/* Private user code ---------------------------------------------------------*/
uint16_t adc_value;
uint32_t adc_sum;
float adc_flit;

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_DMA_Init();
MX_ADC3_Init();
/* USER CODE BEGIN 2 */
HAL_ADCEx_Calibration_Start(&hadc3, ADC_SINGLE_ENDED);/* 以单端模式运行ADC校准 */
HAL_ADC_Start_DMA(&hadc3, (uint32_t *)adc_value, 60);   //开启采集
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
    for(int j=0;j<6;j++){
      for(int i=0;i<10;i++){

       adc_sum+=adc_value;
    }
}
      for(int j=0;j<6;j++){
      adc_flit=(3300*adc_sum)/4096/10;//求平均值然后换算采集的电压值
      adc_sum=0;
}
    /* USER CODE END WHILE */
HAL_Delay(5);
    /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
第九步:把编译完的程序下入单片机,就可以看到采集到的数据了。本程序使用了DMA软件触发ADC,循环采集。若需要定时采集的话,可以将ADC的触发方式改成定时器触发。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_60800812/article/details/144919487

页: [1]
查看完整版本: stm32G474的使用STM32CubeMX生成代码进行ADC DMA连续采集