在嵌入式开发中,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为数据采集提供了高效的解决方案。本教程从配置到实现详细介绍了如何使用这些特性,相信可以帮助开发者快速上手。
|