news 2026/6/23 23:12:22

Freertos手把手教STM32CubeMx设置STM32F4芯片DMA发送ADC数据(二)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Freertos手把手教STM32CubeMx设置STM32F4芯片DMA发送ADC数据(二)

本期目标

  • 理清本工程系统框架
  • 弄懂CubeMx配置相关原理及设置的背后含义
  • 对DMA以及ADC相关的重要API接口使用详解
  • 梳理代码设计流程

前置文章链接:

Freertos手把手教STM32CubeMx设置STM32F4芯片DMA发送ADC数据(一)-CSDN博客

在上一章节完成了对框架的初步探索以及对CubeMx的配置

在freertos的task中对buffer进行了一些测试

下面继续上一章的内容继续完成本次目标

2.启动DMA传输并进入中断

此处是使用中断的方式, 意为当数据采集完毕后会使用产生中断

本篇使用的是下面的方式

(##) In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA()) (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE() (+++) Configure and enable two DMA streams stream for managing data transfer from peripheral to memory (output stream) (+++) Associate the initialized DMA handle to the CRYP DMA handle using __HAL_LINKDMA() (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the two DMA Streams. The output stream should have higher priority than the input stream.

在启动ADC传输以后 , 会把数据放到DR寄存器里 , 如果是中断模式 , 会产生一个中断去取走DR寄存器里面的值 , 而是产生一个DMA request ,然后启动对应的DMA通道 , 然后把DR寄存器里面的值搬运到指定的地址(buffer1/buffer2)上

HAL_ADC_Start_DMA()

最主要的就是知晓这个函数怎么用

/** * @brief Enables ADC DMA request after last transfer (Single-ADC mode) and enables ADC peripheral * @param hadc pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @param pData The destination Buffer address. * @param Length The length of data to be transferred from ADC peripheral to memory. * @retval HAL status */

点击函数跳转定义,可以看到这个函数的简介

“启动DMA request 在每次传输完ADC后 , 并且启动ADC外设”

HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)

第一个形参是ADC的句柄

于ADC.c文件里面有定义

所以我们要使用的时候就要在所使用的文件里extern引用

/* USER CODE BEGIN Variables */ extern ADC_HandleTypeDef hadc1; extern DMA_HandleTypeDef hdma_adc1; /* USER CODE END Variables */

第二个形参是DMA将要将数据搬运到的地址 , 就是我们前面定义的buffer1/2

第三个形参是要从ADC采集多少次数据

HAL_ADC_Start_DMA(&hadc1, buffer1, BUFFER_SIZE); HAL_ADC_Start_DMA(&hadc1, buffer2, BUFFER_SIZE);

void StartDefaultTask(void *argument) { /* USER CODE BEGIN StartDefaultTask */ buffer1 = (uint32_t *)malloc((sizeof(uint32_t)* BUFFER_SIZE)); buffer2 = (uint32_t *)malloc((sizeof(uint32_t)* BUFFER_SIZE)); if(NULL == buffer1) { printf("buffer1 malloc failed \r\n"); } if(NULL == buffer2) { printf("buffer2 malloc failed \r\n"); return; } printf("buffer1 , buffer2 malloc success\r\n "); memset(buffer1, 0xff , (sizeof(uint32_t)* BUFFER_SIZE)); memset(buffer2, 0xff , (sizeof(uint32_t)* BUFFER_SIZE)); printf("Unit test ADC + DMA\r\n "); HAL_ADC_Start_DMA(&hadc1, buffer1, BUFFER_SIZE); HAL_ADC_Start_DMA(&hadc1, buffer2, BUFFER_SIZE); /* Infinite loop */ for(;;) { printf("hello world \r\n"); printf("buffer1 data = [%d] \r\n" , buffer1[0]); printf("buffer2 data = [%d] \r\n" , buffer2[0]); osDelay(1000); } /* USER CODE END StartDefaultTask */ }

为了防止ADC调用出错 , 应当接收函数的返回值 , 以观察函数是否异常

HAL_StatusTypeDef ret1 = HAL_OK; HAL_StatusTypeDef ret2 = HAL_OK; ret1 = HAL_ADC_Start_DMA(&hadc1, buffer1, BUFFER_SIZE); ret2 = HAL_ADC_Start_DMA(&hadc1, buffer2, BUFFER_SIZE); if(HAL_OK != ret1) { printf("HAL_ADC1 call failed "); } if(HAL_OK != ret2) { printf("HAL_ADC2 call failed "); }

至此我们的API :HAL_ADC_Start_DMA()就调用成功了

HAL_ADC_ConvCpltCallback()

当DMA输出到Buffer1后 ,触发DMA中断(中断做的第一件事: 发送消息队列或任务通知(邮箱)给线程A) 。 (涉及函数:xTaskNotifyFromISR或xQueueGenericSendFromISR)

(+) At The end of data transfer by HAL_ADC_ConvCpltCallback() function is executed and user can add his own code by customization of function pointer HAL_ADC_ConvCpltCallback
__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { /* Prevent unused argument(s) compilation warning */ UNUSED(hadc); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_ADC_ConvCpltCallback could be implemented in the user file */ }

将此函数复制到freertos文件调用

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { /* Prevent unused argument(s) compilation warning */ UNUSED(hadc); printf("buffer1 data = [%d] \r\n" , buffer1[0]); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_ADC_ConvCpltCallback could be implemented in the user file */ }

打印一串数据到串口,验证是否可行

可以看到函数被运行了

HAL_ADC_ErrorCallback()

同样的 , 要设置一个验错机制

(+) In case of transfer Error, HAL_ADC_ErrorCallback() function is executed and user can add his own code by customization of function pointer HAL_ADC_ErrorCallback
void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc) { /* Prevent unused argument(s) compilation warning */ UNUSED(hadc); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_ADC_ErrorCallback could be implemented in the user file */ printf("ADC trasfer error \r\n"); }

下一章节:

Freertos手把手教STM32CubeMx设置STM32F4芯片DMA发送ADC数据(三)-CSDN博客

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 14:22:15

JVM G1 和 CMS 详解与对比

G1(Garbage-First)和 CMS(Concurrent Mark Sweep)都是 JVM 中针对老年代的垃圾收集器,旨在解决传统 Serial Old、Parallel Old 收集器的STW(Stop-The-World)时间过长问题,适用于高并…

作者头像 李华
网站建设 2026/6/23 5:05:31

实战解析:2PC与Saga分布式事务的完全避坑指南

实战解析:2PC与Saga分布式事务的完全避坑指南 【免费下载链接】school-of-sre linkedin/school-of-sre: 这是一个用于培训软件可靠性工程师(SRE)的在线课程。适合用于需要学习软件可靠性工程和运维技能的场景。特点:内容丰富&…

作者头像 李华
网站建设 2026/6/23 15:16:58

Lumafly模组管理器:重构空洞骑士模组生态的专业解决方案

Lumafly模组管理器:重构空洞骑士模组生态的专业解决方案 【免费下载链接】Lumafly A cross platform mod manager for Hollow Knight written in Avalonia. 项目地址: https://gitcode.com/gh_mirrors/lu/Lumafly 在《空洞骑士》的模组生态中,玩…

作者头像 李华
网站建设 2026/6/23 17:19:40

12.14 - 搜索旋转排序数组 判断两个结构体是否相等

目录 1.搜索旋转排序数组 a.核心思想 b.思路 2.判断两个结构体是否相等 a.默认情况 b.特殊情况处理 c.重载 运算符 1.搜索旋转排序数组 33. 搜索旋转排序数组 - 力扣(LeetCode)https://leetcode.cn/problems/search-in-rotated-sorted-array/de…

作者头像 李华
网站建设 2026/6/23 18:36:43

WaveTools鸣潮120帧解锁与游戏性能优化全攻略

WaveTools鸣潮120帧解锁与游戏性能优化全攻略 【免费下载链接】WaveTools 🧰鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools 🎯 你是否在鸣潮1.2版本更新后,发现原本流畅的120帧体验突然消失了?别担心…

作者头像 李华
网站建设 2026/6/23 18:50:31

三步学会百度网盘极速下载:告别龟速的终极方案

三步学会百度网盘极速下载:告别龟速的终极方案 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 还在为百度网盘的下载速度而烦恼吗?当你明明拥有高速网络…

作者头像 李华