[STM32H7] STM32H743的高性能ADC采样与DMA实现详解

[复制链接]
5807|10
 楼主| 帛灿灿 发表于 2024-11-21 07:57 | 显示全部楼层 |阅读模式
在高性能嵌入式系统中,高速高精度ADC采样是数据采集的重要环节。STM32H743作为STM32家族的高端MCU,内置多个16位ADC模块,采样速度高达3.6 MSPS,非常适合高速数据采集任务。本文以STM32H743ZI为例,介绍如何使用ADC配合DMA进行高效的数据采集,并提供完整的代码实现。

一、STM32H743ZI简介STM32H743ZI基于ARM Cortex-M7内核,主频高达480 MHz,拥有1 MB的SRAM和2 MB的Flash,配备多个高速ADC、DAC、FMC、ETH等外设,广泛应用于工业自动化、信号处理等领域。
二、硬件连接为进行ADC采样测试,可使用开发板自带的模拟输入通道。STM32H743ZI的ADC通道如下:
  • ADC1_IN0 (PA0)
  • ADC2_IN1 (PA1)
  • ADC3_IN2 (PA2)
在实验中,我们将使用开发板上的可变电阻连接至ADC1_IN0模拟输入通道,提供一个可调的电压信号。

三、代码实现以下代码使用STM32 HAL库实现ADC采样与DMA传输。开发环境为STM32CubeIDE。
  1. #include "main.h"

  2. // ADC句柄定义
  3. ADC_HandleTypeDef hadc1;
  4. DMA_HandleTypeDef hdma_adc1;

  5. // ADC采样数据缓冲区
  6. #define ADC_BUFFER_SIZE 256
  7. uint32_t adc_buffer[ADC_BUFFER_SIZE];

  8. // 初始化ADC1
  9. void MX_ADC1_Init(void) {
  10.     ADC_ChannelConfTypeDef sConfig = {0};

  11.     // 配置ADC1
  12.     hadc1.Instance = ADC1;
  13.     hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
  14.     hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  15.     hadc1.Init.ScanConvMode = DISABLE;
  16.     hadc1.Init.ContinuousConvMode = ENABLE;
  17.     hadc1.Init.DiscontinuousConvMode = DISABLE;
  18.     hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  19.     hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  20.     hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  21.     hadc1.Init.NbrOfConversion = 1;
  22.     hadc1.Init.DMAContinuousRequests = ENABLE;
  23.     hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;

  24.     if (HAL_ADC_Init(&hadc1) != HAL_OK) {
  25.         Error_Handler();
  26.     }

  27.     // 配置ADC通道
  28.     sConfig.Channel = ADC_CHANNEL_0;
  29.     sConfig.Rank = ADC_REGULAR_RANK_1;
  30.     sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;

  31.     if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
  32.         Error_Handler();
  33.     }
  34. }

  35. // DMA初始化
  36. void MX_DMA_Init(void) {
  37.     // 启用DMA时钟
  38.     __HAL_RCC_DMA2_CLK_ENABLE();

  39.     // 配置DMA
  40.     hdma_adc1.Instance = DMA2_Stream0;
  41.     hdma_adc1.Init.Channel = DMA_CHANNEL_0;
  42.     hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
  43.     hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
  44.     hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
  45.     hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  46.     hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  47.     hdma_adc1.Init.Mode = DMA_CIRCULAR;
  48.     hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
  49.     hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

  50.     if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) {
  51.         Error_Handler();
  52.     }

  53.     // 将DMA与ADC绑定
  54.     __HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1);
  55. }

  56. // 主函数
  57. int main(void) {
  58.     HAL_Init();               // 初始化HAL库
  59.     SystemClock_Config();     // 配置系统时钟
  60.     MX_DMA_Init();            // 初始化DMA
  61.     MX_ADC1_Init();           // 初始化ADC1

  62.     // 启动ADC与DMA
  63.     HAL_ADC_Start_DMA(&hadc1, adc_buffer, ADC_BUFFER_SIZE);

  64.     while (1) {
  65.         // 可在此处理采样数据
  66.         uint32_t avg = 0;
  67.         for (int i = 0; i < ADC_BUFFER_SIZE; i++) {
  68.             avg += adc_buffer[i];
  69.         }
  70.         avg
四、代码解析
  • ADC配置
    使用HAL_ADC_Init和HAL_ADC_ConfigChannel配置ADC工作参数,如分辨率、采样时间和输入通道。
  • DMA配置
    配置DMA传输模式为循环模式,并绑定到ADC外设。DMA使数据采集更高效,无需CPU参与传输。
  • 数据采样
    HAL_ADC_Start_DMA启动ADC采样并通过DMA传输数据到缓冲区,主循环中可以直接处理数据。
  • 平均值计算
    示例代码对缓冲区中的数据求平均值,用于进一步处理。


五、调试与优化
  • 采样频率调整
    根据应用需求调整ADC采样时间和时钟分频系数。
  • 数据处理效率
    结合硬件加速功能(如FPU),对采样数据进行高效处理。
  • 多通道采样
    配置扫描模式,实现对多个通道的连续采样。

六、总结通过本文,你将掌握如何在STM32H743ZI上实现高速ADC采样,并利用DMA提高数据传输效率。这种方法在信号处理、工业控制等领域应用广泛,为你的嵌入式开发提供了可靠的技术支持。

公羊子丹 发表于 2024-11-21 07:58 来自手机 | 显示全部楼层
STM32H7系列果然性能强大,3.6MSPS的ADC我直呼顶不住。
周半梅 发表于 2024-11-21 07:58 来自手机 | 显示全部楼层
用DMA真的省事,之前手动轮询累得我头发都秃了。
童雨竹 发表于 2024-11-21 07:59 来自手机 | 显示全部楼层
一直不太懂平均值处理的用处,这次算是明白了。
万图 发表于 2024-11-21 07:59 来自手机 | 显示全部楼层
中断模式采样和DMA相比,有啥实际差异呢?
Wordsworth 发表于 2024-11-21 07:59 来自手机 | 显示全部楼层
这个示例能不能扩展到多通道采样,求大佬指点!
Pulitzer 发表于 2024-11-21 07:59 来自手机 | 显示全部楼层
开发板上的可调电阻接ADC,真是个不错的入门实践思路。
Bblythe 发表于 2024-11-21 08:00 来自手机 | 显示全部楼层
这配置代码确实清晰易懂,尤其是DMA部分学到了不少。
Uriah 发表于 2024-11-21 08:00 来自手机 | 显示全部楼层
H743这款主控适合信号处理类的项目,看着心动了。
Clyde011 发表于 2024-11-21 08:00 来自手机 | 显示全部楼层
有没有更复杂的项目,比如结合FPU做FFT分析的?
DLPIC 发表于 2025-9-26 15:04 | 显示全部楼层
测试了,DMA速度有瓶颈,ADC转换了,结果也不能完全传输。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

166

主题

6196

帖子

0

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