[STM32G4] STM32G431的ADC多通道DMA配置与使用

[复制链接]
3932|11
 楼主| 万图 发表于 2024-12-8 07:46 | 显示全部楼层 |阅读模式
AD, ADC, DM, DMA, ST
在嵌入式开发中,ADC(模数转换器)是不可或缺的组件,用于将模拟信号转换为数字信号。在使用ST的STM32G431时,其强大的性能和灵活的外设配置使其成为众多工程师的选择。本文将重点介绍如何配置STM32G431的ADC多通道功能,并结合DMA(直接存储器访问)实现高效的数据采集。
一、硬件环境与开发环境
  • MCU型号:STM32G431RB
  • 开发板:STM32G4系列官方开发板
  • 开发环境:STM32CubeIDE 1.13.3
  • 硬件说明
    • 使用ADC的通道0和通道1采集两个模拟输入信号。
    • 通过DMA传输ADC转换结果至内存中,避免CPU占用。

二、主要步骤1. 配置ADC多通道在STM32CubeMX中:
  • 选择ADC1并启用。
  • 在"Configuration"选项中,添加两个输入通道(如Channel 0和Channel 1)。
  • 设置"Scan Conversion Mode"为"Enable"以实现多通道采样。
2. 启用DMA传输在STM32CubeMX中:
  • 在DMA设置中,选择ADC1的DMA请求。
  • 设置数据流为"Memory to Peripheral"(内存到外设)。
  • 配置DMA传输模式为"Circular"(循环模式)以便连续采样。
3. 编写应用程序代码配置完成后生成代码,完成初始化逻辑后补充应用代码。

三、代码实现以下代码展示了如何配置和使用ADC多通道DMA:
  1. #include "main.h"

  2. #define ADC_CHANNEL_NUM 2 // 定义采样通道数量

  3. ADC_HandleTypeDef hadc1;
  4. DMA_HandleTypeDef hdma_adc1;

  5. uint32_t adcBuffer[ADC_CHANNEL_NUM]; // 存储ADC采样结果的缓冲区

  6. void SystemClock_Config(void);
  7. static void MX_GPIO_Init(void);
  8. static void MX_DMA_Init(void);
  9. static void MX_ADC1_Init(void);

  10. int main(void) {
  11.     HAL_Init(); // 初始化HAL库
  12.     SystemClock_Config(); // 配置系统时钟
  13.     MX_GPIO_Init(); // 初始化GPIO
  14.     MX_DMA_Init(); // 初始化DMA
  15.     MX_ADC1_Init(); // 初始化ADC

  16.     // 开始ADC和DMA
  17.     if (HAL_ADC_Start_DMA(&hadc1, adcBuffer, ADC_CHANNEL_NUM) != HAL_OK) {
  18.         Error_Handler(); // 启动失败时进入错误处理
  19.     }

  20.     while (1) {
  21.         // 实时处理采样数据
  22.         uint32_t adc_value_channel0 = adcBuffer[0];
  23.         uint32_t adc_value_channel1 = adcBuffer[1];

  24.         // 用户应用逻辑
  25.         HAL_Delay(100); // 模拟处理延迟
  26.     }
  27. }

  28. void MX_ADC1_Init(void) {
  29.     ADC_ChannelConfTypeDef sConfig = {0};

  30.     hadc1.Instance = ADC1;
  31.     hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  32.     hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  33.     hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  34.     hadc1.Init.ContinuousConvMode = ENABLE;
  35.     hadc1.Init.DiscontinuousConvMode = DISABLE;
  36.     hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  37.     hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  38.     hadc1.Init.NbrOfConversion = ADC_CHANNEL_NUM;
  39.     hadc1.Init.DMAContinuousRequests = ENABLE;
  40.     if (HAL_ADC_Init(&hadc1) != HAL_OK) {
  41.         Error_Handler();
  42.     }

  43.     // 配置通道0
  44.     sConfig.Channel = ADC_CHANNEL_0;
  45.     sConfig.Rank = ADC_REGULAR_RANK_1;
  46.     sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  47.     if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
  48.         Error_Handler();
  49.     }

  50.     // 配置通道1
  51.     sConfig.Channel = ADC_CHANNEL_1;
  52.     sConfig.Rank = ADC_REGULAR_RANK_2;
  53.     if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
  54.         Error_Handler();
  55.     }
  56. }

  57. static void MX_DMA_Init(void) {
  58.     __HAL_RCC_DMA1_CLK_ENABLE();

  59.     // 初始化DMA请求
  60.     hdma_adc1.Instance = DMA1_Channel1;
  61.     hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
  62.     hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
  63.     hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
  64.     hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  65.     hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  66.     hdma_adc1.Init.Mode = DMA_CIRCULAR;
  67.     hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
  68.     if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) {
  69.         Error_Handler();
  70.     }

  71.     // 关联DMA和ADC
  72.     __HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1);
  73. }
四、运行结果运行代码后,ADC将持续对Channel 0和Channel 1的输入信号进行采样,结果存储在adcBuffer中,可直接在主循环中使用这些数据。
五、优化建议
  • 调整采样时间以适应不同的信号源阻抗。
  • 使用低通滤波器对模拟信号进行预处理,提高采样精度。
  • 根据实际应用选择适当的ADC分辨率和DMA模式。

六、总结STM32G431强大的ADC多通道功能结合DMA为数据采集提供了高效的解决方案。本教程从配置到实现详细介绍了如何使用这些特性,相信可以帮助开发者快速上手。

公羊子丹 发表于 2024-12-8 07:46 | 显示全部楼层
学到了,DMA模式的使用确实减少了CPU的负担!
周半梅 发表于 2024-12-8 07:46 | 显示全部楼层
想问问多通道的采样速度可以多快?
帛灿灿 发表于 2024-12-8 07:47 | 显示全部楼层
请教下,如果是三通道应该怎么改?
童雨竹 发表于 2024-12-8 07:47 | 显示全部楼层
感觉这个配置好复杂,有没有更简单的方法?
Wordsworth 发表于 2024-12-8 07:47 | 显示全部楼层
有没有推荐的硬件滤波电路?
Pulitzer 发表于 2024-12-8 07:47 | 显示全部楼层
文中提到的DMA循环模式很有用,赞一个!
Bblythe 发表于 2024-12-8 07:47 | 显示全部楼层
开发板和代码都对上了,一次成功运行!
Uriah 发表于 2024-12-8 07:48 | 显示全部楼层
我用的是STM32F系列,可以参考这篇文章配置吗?
Clyde011 发表于 2024-12-8 07:48 | 显示全部楼层
感谢详细代码解读,新手也能看明白!
结合国际经验 发表于 2024-12-31 23:10 | 显示全部楼层
在硬件方面,PWM 信号需要与风扇的控制引脚连接。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

175

主题

6227

帖子

1

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