打印
[STM32G4]

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

[复制链接]
194|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
万图|  楼主 | 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:
#include "main.h"

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

ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;

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

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);

int main(void) {
    HAL_Init(); // 初始化HAL库
    SystemClock_Config(); // 配置系统时钟
    MX_GPIO_Init(); // 初始化GPIO
    MX_DMA_Init(); // 初始化DMA
    MX_ADC1_Init(); // 初始化ADC

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

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

        // 用户应用逻辑
        HAL_Delay(100); // 模拟处理延迟
    }
}

void MX_ADC1_Init(void) {
    ADC_ChannelConfTypeDef sConfig = {0};

    hadc1.Instance = ADC1;
    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
    hadc1.Init.Resolution = ADC_RESOLUTION_12B;
    hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
    hadc1.Init.ContinuousConvMode = ENABLE;
    hadc1.Init.DiscontinuousConvMode = DISABLE;
    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.NbrOfConversion = ADC_CHANNEL_NUM;
    hadc1.Init.DMAContinuousRequests = ENABLE;
    if (HAL_ADC_Init(&hadc1) != HAL_OK) {
        Error_Handler();
    }

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

    // 配置通道1
    sConfig.Channel = ADC_CHANNEL_1;
    sConfig.Rank = ADC_REGULAR_RANK_2;
    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
        Error_Handler();
    }
}

static void MX_DMA_Init(void) {
    __HAL_RCC_DMA1_CLK_ENABLE();

    // 初始化DMA请求
    hdma_adc1.Instance = DMA1_Channel1;
    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_WORD;
    hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_adc1.Init.Mode = DMA_CIRCULAR;
    hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
    if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) {
        Error_Handler();
    }

    // 关联DMA和ADC
    __HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1);
}
四、运行结果运行代码后,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 | 只看该作者
请教下,如果是三通道应该怎么改?

使用特权

评论回复
5
童雨竹| | 2024-12-8 07:47 | 只看该作者
感觉这个配置好复杂,有没有更简单的方法?

使用特权

评论回复
6
Wordsworth| | 2024-12-8 07:47 | 只看该作者
有没有推荐的硬件滤波电路?

使用特权

评论回复
7
Pulitzer| | 2024-12-8 07:47 | 只看该作者
文中提到的DMA循环模式很有用,赞一个!

使用特权

评论回复
8
Bblythe| | 2024-12-8 07:47 | 只看该作者
开发板和代码都对上了,一次成功运行!

使用特权

评论回复
9
Uriah| | 2024-12-8 07:48 | 只看该作者
我用的是STM32F系列,可以参考这篇文章配置吗?

使用特权

评论回复
10
Clyde011| | 2024-12-8 07:48 | 只看该作者
感谢详细代码解读,新手也能看明白!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

42

主题

3752

帖子

0

粉丝