STM32 HAL库实战:高效整合DMA与ADC开发指南

server/2025/3/14 8:17:18/

STM32 HAL库实战:高效整合DMA与ADC开发指南

一、DMA与ADC基础介绍

1. DMA:解放CPU的“数据搬运工”

DMA(Direct Memory Access) 是STM32中用于在外设与内存之间直接传输数据的硬件模块。其核心优势在于无需CPU干预,可显著提升系统效率。

  • 功能特点:

    • 支持存储器↔外设、存储器↔存储器的数据传输。

    • 多通道管理,每个通道独立控制一个外设的数据传输。

    • 传输完成后触发中断通知CPU。

  • 典型应用场景:

    • ADC多通道连续采样数据的自动存储。

    • 串口大数据收发、SPI/I2C通信等。

2. ADC:模拟世界的“数字翻译器”

ADC(Analog-to-Digital Converter) 负责将模拟信号(如电压、温度)转换为数字信号。STM32的ADC模块支持多通道、高精度采样。

  • 关键参数:

    • 分辨率:12位(0~4095)。

    • 采样速率:最高1MHz(STM32F1系列)。

    • 输入通道:16个外部通道 + 2个内部通道(温度传感器、VREF)。

  • 工作模式:

    • 单次转换、连续转换、扫描模式(多通道轮询)。

二、DMA+ADC整合开发步骤

1. 硬件与工程配置

硬件连接示例
  • ADC通道:PA1(通道1)接模拟输入(如MQ2烟雾传感器、电位器等)。
  • DMA通道:ADC1使用DMA1通道1(见STM32参考手册)。
    在这里插入图片描述
硬件代码配置
ADC基础配置
void adc_config(void)
{adc_handle.Instance = ADC1;adc_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;adc_handle.Init.ScanConvMode = ADC_SCAN_DISABLE;adc_handle.Init.ContinuousConvMode = ENABLE;adc_handle.Init.NbrOfConversion = 1;adc_handle.Init.DiscontinuousConvMode = DISABLE;adc_handle.Init.NbrOfDiscConversion = 0;adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;HAL_ADC_Init(&adc_handle);HAL_ADCEx_Calibration_Start(&adc_handle);
}
ADC硬件配置
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance == ADC1){RCC_PeriphCLKInitTypeDef adc_clk_init = {0};GPIO_InitTypeDef gpio_init_struct = {0};__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();gpio_init_struct.Pin = GPIO_PIN_1;gpio_init_struct.Mode = GPIO_MODE_ANALOG;HAL_GPIO_Init(GPIOA, &gpio_init_struct);adc_clk_init.PeriphClockSelection = RCC_PERIPHCLK_ADC;adc_clk_init.AdcClockSelection = RCC_ADCPCLK2_DIV6;HAL_RCCEx_PeriphCLKConfig(&adc_clk_init);}
}
ADC通道配置

void adc_channel_config(ADC_HandleTypeDef* hadc, uint32_t ch, uint32_t rank, uint32_t stime)
{ADC_ChannelConfTypeDef adc_ch_config = {0};adc_ch_config.Channel = ch;adc_ch_config.Rank = rank;adc_ch_config.SamplingTime = stime;HAL_ADC_ConfigChannel(hadc, &adc_ch_config);
}
DMA配置:
void dma_config(void)
{__HAL_RCC_DMA1_CLK_ENABLE();dma_handle.Instance = DMA1_Channel1;dma_handle.Init.Direction = DMA_PERIPH_TO_MEMORY;//内存相关配置dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;dma_handle.Init.MemInc = DMA_MINC_ENABLE;//外设相关配置dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;dma_handle.Init.PeriphInc = DMA_PINC_DISABLE;dma_handle.Init.Priority = DMA_PRIORITY_MEDIUM;dma_handle.Init.Mode = DMA_CIRCULAR;HAL_DMA_Init(&dma_handle);__HAL_LINKDMA(&adc_handle, DMA_Handle, dma_handle);
}

2. 关键代码实现

初始化并启动DMA
void adc_dma_init(uint32_t *mar)
{adc_config();adc_channel_config(&adc_handle, ADC_CHANNEL_1, ADC_REGULAR_RANK_1, ADC_SAMPLETIME_239CYCLES_5);dma_config();HAL_ADC_Start_DMA(&adc_handle, mar, 1);
}

在主函数中,调用该函数,DMA将会一直将值存放在mar所指的内存上。

3. 优化技巧与常见问题

提升ADC精度
  • 硬件优化:

    • 添加0.1μF滤波电容到ADC输入引脚。

    • 单独为VDDA和VSSA供电。

  • 软件优化:

    • 丢弃前几次采样值(避免电源不稳定)。
常见问题排查
  • 数据错位:检查DMA数据宽度(需与ADC对齐方式一致)。

  • 采样值跳动:增加采样时间或添加软件滤波(如滑动平均)。

  • DMA不触发:确认DMA通道与ADC的映射关系(参考数据手册)。

三、项目实战:DMA单通道采集(烟雾)

功能需求

  • 使用PA1烟雾报警模拟输入。
  • 每3秒计算一次并通过串口输出。

核心代码片段

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "uart1.h"
#include "adc.h"#define CAL_PPM  10  // 校准环境中PPM值
#define RL	     10  // RL阻值
#define R0	     97  // R0阻值uint16_t adc_result = 0;
int main(void)
{float RS ;float ppm;HAL_Init();                         /* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */led_init();                         /* 初始化LED灯 */uart1_init(115200);adc_dma_init((uint32_t  *)&adc_result);printf("hello world!\r\n");while(1){ 
//        printf("adc result: %f\r\n", (float)adc_result / 4096 * 3.3);RS = (3.3f - (float)adc_result / 4096 * 3.3) / (float)adc_result / 4096 * 3.3 * RL;ppm = 98.322f * pow(RS/R0, -1.458f);printf("adc result: %f\r\n", ppm);delay_ms(3000);}
}

四、总结

通过DMA+ADC的高效整合,开发者可以实现低CPU占用率的模拟信号采集系统。关键点在于:

  1. 合理配置ADC的扫描模式与DMA循环传输。
  2. 利用HAL库的中断回调机制处理数据。
  3. 通过硬件与软件优化提升信号质量。

掌握这一技术后,可轻松应对传感器数据采集、工业控制等高实时性场景的需求。


http://www.ppmy.cn/server/174828.html

相关文章

SpringBoot3+Lombok如何配置logback输出日志到文件

Background/Requirement SpringBoot3Lombok如何配置logback输出日志到文件,因为我需要对这些日志进行输出,控制台输出和文件输出,文件输出是为了更好的作为AuditLog且支持滚动式备份,每天一个文件。 Technical Solution 1.确保你…

计算机网络--访问一个网页的全过程

文章目录 访问一个网页的全过程应用层在浏览器输入URL网址http://www.aspxfans.com:8080/news/index.aspboardID5&ID24618&page1#r_70732423通过DNS获取IP地址生成HTTP请求报文应用层最后 传输层传输层处理应用层报文建立TCP连接传输层最后 网络层网络层对TCP报文进行处…

STM32F407 cubeIDE Bootloader APP 如何写

一、bootloader 代码如下: #define FLASH_JUMP_ADDR (0x0800c000) /* USER CODE END PD *//* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ----------…

红帆 iOffice M2 移动端密码爆破的渗透测试思路,绕过客户端实现Burpsuite批量跑,分享渗透思路,共建网络安全

一、本文概述 今天来自于领导的一个需求,需要对甲方的红帆 ioffice M2进行一次渗透测试【有授权书的】,拿到对应的APP和接口以后,我发现了进行不下去的一个关键点,他家的OA只有APP端,没有Web端,而且密码被加密了。 二、开始分析 红帆 iOffice M2,在登录的过程中,涉及…

AI预测福彩3D新模型百十个定位预测+胆码预测+杀和尾+杀和值2025年3月13日第21弹

前面由于工作原因停更了很长时间,停更期间很多彩友一直私信我何时恢复发布每日预测,目前手头上的项目已经基本收尾,接下来恢复发布。当然,也有很多朋友一直咨询3D超级助手开发的进度,在这里统一回复下。 由于本人既精…

Unity开发的抖音小游戏接入抖音开放平台中的流量主(抖音小游戏接入广告)

前言:作者在进行小游戏审核版本的过程中,碰到了下列问题,所以对这个抖音小游戏接入广告研究了下。 还有就是作者的TTSDK版本号是6.2.6,使用的Unity版本是Unity2022.3.29f1,最好和作者的两个版本号保持一致,因为我发现TTSDK旧版的很多函数在新版中就已经无法正常使用了,必…

数据结构-栈(详解)

目录 一、栈的基本概念二、栈的基本操作三、栈的实现方式1. 数组实现栈2. 链表实现栈 四、栈的应用场景五、总结 一、栈的基本概念 栈(Stack)是一种特殊的线性表,它只允许在表的一端进行插入和删除操作。这一端称为栈顶(Top&…

主流向量数据库对比

在 AI 的 RAG(检索增强生成)研发领域,向量数据库是存储和查询向量嵌入的核心工具,用于支持高效的语义搜索和信息检索。向量嵌入是文本或其他非结构化数据的数值表示,RAG 系统通过这些嵌入从知识库中检索相关信息&#…