当前位置: 首页 > news >正文

STM32单片机芯片与内部33 ADC 单通道连续DMA

目录

一、ADC DMA配置——标准库

1、ADC配置

2、DMA配置

二、ADC DMA配置——HAL库

1、ADC配置

2、DMA配置

三、用户侧

1、DMA开关

(1)、标准库

(2)、HAL库

2、DMA乒乓

(1)、标准库

(2)、HAL库


上文提到了当转换速度较高的时候需要由DMA进行搬运。

一、ADC DMA配置——标准库

1、ADC配置

        可以看到ADC配置几乎不用变。

	// 使能ADC DMA 请求ADC_DMACmd(ADCx, ENABLE);

2、DMA配置

        最重要的是源地址、目的地址、传输大小。如下配置为将每次ADC的数据从DR源地址搬运到ADC_ConvertedValue变量,因为只有一个大小长度,因此设定为1,大小设置为两个字节。

__IO uint16_t ADC_ConvertedValue;DMA_InitTypeDef DMA_InitStructure;// 打开DMA时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// 打开ADC时钟ADC_APBxClock_FUN ( ADC_CLK, ENABLE );// 复位DMA控制器DMA_DeInit(ADC_DMA_CHANNEL);// 配置 DMA 初始化结构体// 外设基址为:ADC 数据寄存器地址DMA_InitStructure.DMA_PeripheralBaseAddr = ( uint32_t ) ( & ( ADCx->DR ) );// 存储器地址,实际上就是一个内部SRAM的变量DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;// 数据源来自外设DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;// 缓冲区大小为1,缓冲区的大小应该等于存储器的大小DMA_InitStructure.DMA_BufferSize = 1;// 外设寄存器只有一个,地址不用递增DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 存储器地址固定DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; // 外设数据大小为半字,即两个字节DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// 存储器数据大小也为半字,跟外设数据大小相同DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;// 循环传输模式DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;	// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响DMA_InitStructure.DMA_Priority = DMA_Priority_High;// 禁止存储器到存储器模式,因为是从外设到存储器DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// 初始化DMADMA_Init(ADC_DMA_CHANNEL, &DMA_InitStructure);// 使能 DMA 通道DMA_Cmd(ADC_DMA_CHANNEL , ENABLE);

        有人会好奇,DR寄存器32位,为什么定义的16位,不会丢失什么嘛,前面数据手册介绍过。高16位用于双ADC,单ADC仅用到低16位,且一般右端对齐,则为低12位有效。

二、ADC DMA配置——HAL库

1、ADC配置

        同样不修改配置。

    HAL_ADC_Start_DMA(&ADC_Handle, (uint32_t*)&ADC_ConvertedValue, 1);

2、DMA配置

        可以看到源地址和目的地址和长度最重要的被放在了HAL_ADC_Start_DMA中,这样可以实现不修改初始化的情况下,进行地址、长度的修改。

DMA_HandleTypeDef hdma_adcx;
__IO uint16_t ADC_ConvertedValue;// 开启DMA时钟RHEOSTAT_ADC_DMA_CLK_ENABLE();// 数据传输通道hdma_adcx.Instance = RHEOSTAT_ADC_DMA_STREAM;hdma_adcx.Init.Direction=DMA_PERIPH_TO_MEMORY;;            //存储器到外设hdma_adcx.Init.PeriphInc=DMA_PINC_DISABLE;                 //外设非增量模式hdma_adcx.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式 hdma_adcx.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;//外设数据长度:16位hdma_adcx.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;   //存储器数据长度:16位hdma_adcx.Init.Mode= DMA_CIRCULAR;                         //外设普通模式hdma_adcx.Init.Priority=DMA_PDATAALIGN_HALFWORD;               //中等优先级//初始化DMA流,流相当于一个大的管道,管道里面有很多通道HAL_DMA_Init(&hdma_adcx); __HAL_LINKDMA( &ADC_Handle,DMA_Handle,hdma_adcx);

三、用户侧

还是前面的问题,如果需要处理1000个点,该怎么办?

        如果不需要前1000和后1000连续,则可以进行DMA的开关或ADC的开关,如果要求连续则开启DMA乒乓切换。

1、DMA开关

        说明不需要DMA的连续转换,而是传输1000个点则停止,处理后再进行一次DMA传输。

(1)、标准库

        需要修改为单次的缓冲区大小、单次传输模式。

define max_size 1000
__IO uint16_t ADC_ConvertedValue[max_size ];// 存储器地址,实际上就是一个内部SRAM的数组DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;// 缓冲区大小为1,缓冲区的大小应该等于存储器的大小DMA_InitStructure.DMA_BufferSize = max_size ;// 单次传输模式DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;	// 存储器地址,实际上就是一个内部SRAM的变量DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue;// 存储器地址递增DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 

        DMA中断赋值flag,主函数用户检测到flag=1说明单次1000个点的数据好了,就可以进行处理,然后再次开启DMA和ADC。

        DMA进入中断,关闭ADC转换并将数据转换结果置1。当然也可以直接在主函数检测DMA的传输完成TCIF。

// DMA 完成后产生中断,停止 DMA,用户处理数据
void DMA1_Channel1_IRQHandler(void)
{if (DMA_GetITStatus(DMA1_IT_TC1))  // 检查 DMA 传输完成中断{// 清除 DMA 中断标志DMA_ClearITPendingBit(DMA1_IT_TC1);// 关闭 ADC 转换ADC_SoftwareStartConvCmd(ADCx, DISABLE);flag=1;}
}

        主函数检测到flag置位1后,说明可以进行数据处理,处理完成后,就可以重启DMA和ADC转换了。

if(flag==1)
{data_process();flag=0;// 重新启动 DMADMA_Cmd(ADC_DMA_CHANNEL, ENABLE);// 重新启动 ADCADC_SoftwareStartConvCmd(ADCx, ENABLE);
}

(2)、HAL库

        需要修改为单次的缓冲区大小、单次传输模式。

define max_size 1000
__IO uint16_t ADC_ConvertedValue[max_size ];hdma_adcx.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式 hdma_adcx.Init.Mode= DMA_NORMAL;                         //外设普通模式HAL_ADC_Start_DMA(&ADC_Handle, (uint32_t*)&ADC_ConvertedValue, max_size );

有StartDMA,自然也有StopDMA,在中断服务函数直接执行即可。

HAL_ADC_Stop_DMA(&ADC_Handle)

2、DMA乒乓

        每次中断后修改目的地址,并开启新的中断,只需要修改中断服务函数即可。

(1)、标准库

__IO uint16_t ADC_ConvertedValue[2][max_size];  // 定义两个缓冲区,双缓冲区// 存储器地址,实际上就是一个内部SRAM的变量DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue[currentBuffer];
// DMA 完成后产生中断,停止 DMA,用户处理数据
void DMA1_Channel1_IRQHandler(void)
{if (DMA_GetITStatus(DMA1_IT_TC1))  // 检查 DMA 传输完成中断{// 清除中断标志DMA_ClearITPendingBit(DMA1_IT_TC1);// 切换到下一个缓冲区currentBuffer = (currentBuffer + 1) % 2;  // 切换到另一个缓冲区// 重新配置DMA传输目标地址DMA_Init(ADC_DMA_CHANNEL, &DMA_InitStructure);DMA_Cmd(ADC_DMA_CHANNEL, ENABLE); // 重新启动DMA}
}

        在主函数中判断,如果currentBuffer为1,说明当前在向第二部分写入此时可以处理第一部分,如果为0,则说明在向第一部分写入此时可以处理第二部分。

(2)、HAL库

        可以看到,得力于源地址和目的地址和长度最重要的被放在了HAL_ADC_Start_DMA中,可以很方便实现。

// DMA 完成后产生中断,停止 DMA,用户处理数据
void DMA1_Channel1_IRQHandler(void)
{if (DMA_GetITStatus(DMA1_IT_TC1))  // 检查 DMA 传输完成中断{// 清除中断标志DMA_ClearITPendingBit(DMA1_IT_TC1);// 切换到下一个缓冲区currentBuffer = (currentBuffer + 1) % 2;  // 切换到另一个缓冲区HAL_ADC_Start_DMA(&ADC_Handle, (uint32_t)ADC_ConvertedValue[currentBuffer], max_size );}
}

        在主函数中判断,如果currentBuffer为1,说明当前在向第二部分写入此时可以处理第一部分,如果为0,则说明在向第一部分写入此时可以处理第二部分。

相关文章:

STM32单片机芯片与内部33 ADC 单通道连续DMA

目录 一、ADC DMA配置——标准库 1、ADC配置 2、DMA配置 二、ADC DMA配置——HAL库 1、ADC配置 2、DMA配置 三、用户侧 1、DMA开关 (1)、标准库 (2)、HAL库 2、DMA乒乓 (1)、标准库 &#xff…...

【0376】Postgres内核 分配 last safe MultiXactId

上一篇: 【0375】Postgres内核 XLOG 之 设置下一个待分配 MultiXactId 和 offset 文章目录 1. 最后一个安全的 MultiXactId1.1 计算 multi wrap limit1.2 计算 multi stop limit1.3 计算 multi warn limit1.4 计算 multi vacuum limit2. 初始化 MultiXactState 成员3. 完成 mu…...

php时间strtotime函数引发的问题 时间判断出错

在 PHP 中,strtotime 函数能处理的最大时间范围取决于您的系统和 PHP 版本。 一般来说,它可以处理的时间范围从 1901 年 12 月 13 日到 2038 年 1 月 19 日。超过这个范围可能会导致不可预测的结果或错误。 如果您需要处理更大范围的时间,可能…...

Kibana:LINUX_X86_64 和 DEB_X86_64两种可选下载方式的区别

最近需要在vm(操作系统是 Ubuntu 22.04.4 LTS,代号 Jammy。这是一个基于 x86_64 架构的 Linux 发行版)上安装一个7.17.8版本的Kibana,并且不采用docker方式。 在下载的时候发现有以下两个选项,分别是 LINUX_X86_64 和 …...

【LeetCode每日一题】 LeetCode 151.反转字符串中的单词

LeetCode 151.反转字符串中的单词 题目描述 给你一个字符串 s ,请你反转字符串中单词的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意:…...

gitlab克隆仓库报错fatal: unable to access ‘仓库地址xxxxxxxx‘

首次克隆仓库,失效了,上网查方法,都说是网络代理的问题,各种清理网络代理后都无效,去问同事: 先前都是直接复制的网页url当做远端url,或者点击按钮‘使用http克隆’ 这次对于我来说有效的远端u…...

在已有vue cli项目中添加单元测试配置

使用的是vue cli ^4.0.0的脚手架,项目采用的vue2进行编写,项目本身是没有使用单元测试的。应该挺多项目还是使用的vue2的项目进行开发的,自己在开发中过程中,还是发生了挺多需要记录原来功能的情况,这个时候去翻文档明…...

企业级NoSql数据库REDIS集群

1.1数据库主要分为两大类:关系型数据库与 NoSQL数据库 关系型数据库,是建立在关系模型基础上的数把库,其借助于集合代数等数学概念和方法来处理数据库中的数掘主流的 MySQLOracle、Ms sOLSerer和 DB2 都属于这类传统数据库 NoSQL数据库,全称…...

HTML与数据抓取:GET与POST方法详解

讲GET和POST就不能只讲GET和POST 你要讲HTTP请求的基本概念: HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最为广泛的一种网络协议,主要用于Web浏览器与Web服务器之间的数据通信。HTTP是一个基于…...

【es6复习笔记】模板字符串(3)

介绍 模板字符串是 ES6 引入的一种新的字符串声明方式,它使用反引号()来定义字符串,而不是单引号()或双引号(")。模板字符串可以包含变量、表达式和换行符,这使得它…...

cursor保存更改操作技巧

1. 当我们在agent模式时,要求cursor更改代码时,cursor回答后,就已经更改了代码了,这时候就可以对程序进行编译和测试, 不一定先要点” accept“, 先测试如果没有问题再点“accept”,这样composer就会多一条…...

ASP.NET |日常开发中定时任务详解

ASP.NET |日常开发中定时任务详解 前言一、定时任务的概念与用途1.1 定义1.2 应用场景 二、在ASP.NET中实现定时任务的方式2.1 使用System.Timers.Timer2.2 使用Quartz.NET 三、定时任务的部署与管理3.1 部署考虑因素3.2 管理与监控 结束语优质源码分享 ASP.NET &am…...

【零基础保姆级教程】制作自己的数据集(二)——Labelme的安装与使用及常见的报错解决方法

前段时间安装了Labelimg,网上有些博客写着Labelme能进行语义分割的标注,但UI窗口就那么大找不着选项,只能打矩形框,为了能够标注自己的分割数据集,遂写下该教程以供参考。 采用Labelimg进行目标检测标注的教程如下。 …...

Move AI技术浅析(二):输入与预处理

一、视频输入模块 1.1 视频输入步骤详解 视频输入模块的主要任务是接收视频数据,并将其转换为后续处理所需的格式。具体步骤: 1.1.1 视频读取 步骤:从文件系统、网络流或摄像头读取视频数据。技术:使用 OpenCV 的 cv2.VideoCa…...

实践KDTS-WEB从mysql迁移到kingbasev9

数据库国产化替代数据迁移是一个复杂且关键的过程。这涉及到将原有数据库中的数据准确、完整地迁移到新的国产数据库中,同时确保数据的完整性和一致性。人大金仓提供了强大的数据库迁移工具(KDTS)对同构、异构数据库数据迁移; 数…...

WebGIS实战开源项目:智慧机场三维可视化(学习笔记)

From:新中地 1.简介 智慧机场解决方案,基于数字化大平台,融合AI、大数据、IoT、视频云、云计算等技术,围绕机场“运控、安防、服务”三大业务领域,构建“出行一张脸”及“运行一张图”两大场景化解决方案。 https://…...

2025年PMP项目管理考试时间一览表

PMP认证是全球项目管理领域公认的权威认证,它不仅能证明你在项目管理方面的专业水平,还能大大提升你的职场竞争力! 随着企业对项目管理人才的需求不断增长,获得PMP认证将为你带来更多的职业机会和高薪职位。 为了帮助大家合理安排…...

20241224在ubuntu20.04.6下的终端分屏软件terminator的安装以及使用

20241224在ubuntu20.04.6下的终端分屏软件terminator的安装以及使用 2024/12/24 18:35 百度:终端分屏软件 https://blog.csdn.net/weixin_49693003/article/details/143683326 可以实现终端分屏的工具:terminator 安装: sudo apt-get insta…...

打造高效租赁小程序让交易更便捷

内容概要 在如今节奏飞快的商业世界里,租赁小程序如同一只聪明的小狐狸,迅速突围而出,成为商家与消费者之间的桥梁。它不仅简化了交易流程,还在某种程度上将传统租赁模式带入了互联网时代。越来越多的企业意识到,这种…...

光谱相机在农业中的具体应用案例

作物生长监测与产量预测 美国爱荷华州玉米种植园:农场主使用无人机搭载高光谱相机,定期对玉米田进行拍摄。通过分析光谱数据,获取玉米的叶面积指数、叶绿素含量等生长参数。在玉米生长关键期,依据这些参数及时调整施肥和灌溉方案…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...