STM32使用ADC+DMA进行多通道模拟量采集 (踩坑及傻瓜式解析)
STM32使用ADC+DMA进行多通道模拟量采集 (踩坑及通俗解析)
利用STM32的片上外设可采集多个模拟量(如传感器数值),并在嵌入式程序中使用。如果只使用了一个通道,用时令ADC转换而后读取DR寄存器即可。多通道时,可利用ADC+DMA可实时,有序的转存多通道数据至程序内存(数组),用时可随时访问并索引到对应通道。
CubeMX配置
时钟配置如下:
原先经常忽视时钟的信息,这里注意一下ADC1,2,3的时钟频率,其于ADC采样时间有关。如果时钟配置的很高,那么选择1.5Cycles可能不满足最小转换时间,产生错误不易debug。
ADCs配置如下:
ADC1的独立模式工作逻辑:一个ADC外设(ADC1)对应一个缓存(DR寄存器),同时采集多个通道指按配置的顺序依次将模拟量转换位数字量,然后储存在外设所谓的"共享内存"——DR寄存器中,DR的值被硬件不断的覆盖写入,在恰当时刻读取DR中的值,可得到对应通道的数据。通过一系列硬件中断信号,标志位等,可保证DR中读取的数据与期望的通道相对应。总而言之,DR成为了安全队列。
各个选项含义见表格。
ADCs_Common_Settings(ADC基础设置) Mode(工作模式) Independent mode(独立模式) 在同一引脚上仅有一个ADC在采集模拟信号 ADC_Settings(ADC设置) Data Alignment(数据对齐) Right alignment(数据右对齐)/Left alignment(数据左对齐) Scan Conversion Mode(扫描模式) ENABLE(使能)/DISABLE(禁止) #当有多个通道需要采集信号时必须开启扫描模式,此时ADC将会按设定的顺序轮流采集各通道信号 Continuous Comverion Mode(连续转换模式) ENABLE(使能)/DISABLE(禁止) #连续转换模式将会在上一次ADC转换完成后立即开启下一次转换 Discontinuous Comverion Mode(单次转换模式) ENABLE(使能)/DISABLE(禁止) #单次转换模式ADC只采集一次数据就停止采集,使用单次转换模式需要转换通道数大于1 Number Of Discontinuous Conversions(单次转换次数) #此项设置为单次转换模式的附属设置,需要使能单次转换模式 ADC_Regular_ConversionMode(规则通道模式) Enable Regular Conversions(规则通道控制) ENABLE(使能)、DISABLE(禁止) #需要使能规则通道控制才可以进一步对规则通道的使用进行配置 Number Of Conversion(ADC转换通道数) #按照实际使用的通道数进行选择,会影响可供设置的通道数量 External Trigger Conversion Source(外部触发转换模式) Regular Conversion Launched by software(软件控制触发) #ADC需要在接收到到触发信号后才开始模数转换,可以被定时器触发、外部中断触发、软件触发 RANK(模拟信号采集及转换的次序) Channel(ADC转换通道) Sampling Time(采样周期) #ADC采样时间计算公式:TCONV=采样周期+12.5各周期 ADC_Injected_ConversionMode(注入通道模式) #一般情况下不需要使用注入通道,可以将注入通道认为是ADC中断,即打断规则通道的采样进程执行注入通道的采样 Enable Regular Conversions(注入通道控制) ENABLE(使能)、DISABLE(禁止) #需要使能注入通道控制才可以进一步对注入通道进行配置 Number Of Conversion(ADC注入转换通道数) #按照实际使用的通道数进行选择,会影响可供设置的注入通道数量 External Tigger Source(外部触发模式) Injected Conversion Mode(注入转换通道模式) Rank(注入转换通道大于0时才可对其配置,后面的数字代表顺序) Channel(转换通道) Sampling Time(转换时间) Injected Offset(注入通道偏移量) WatchDog(看门狗) Enable Analog WatchDog Mode(使能模拟量看门狗模式) #需要选中本项才可对看门狗进行进一步的设置 Watchdog Mode(看门狗模式) Single regular channel
Single injected channel
Single regular or injected channel(监测单一通道的规则通道)
(监测单一通道的注入通道)
(监测单一通道的规则及注入通道)Analog WatchDog Channel(看门狗通道) High Threshold(高阈值) Low Threshold(低阈值) Interrupt Mode(看门狗中断) DMA配置如下
由于开始不太理解DMA几个配置的含义,曾在这里踩了很多坑,对应在程序中说明。
因为没有使用中断,NVIC Settings中我把中断关闭了。
程序使用
自动生成代码有时有坑:main中有系统生成的各外设初始化函数调用
/* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_ADC1_Init(); MX_DAC_Init(); MX_UART4_Init(); MX_USART3_UART_Init(); ......
检查
MX_DMA_Init();
是否在MX_ADC1_Init();
之前调用,默认情况我的在后面,后发现DMA功能异常,手动更改顺序后正常启用ADC转换,DMA模式
开一个数组存数,main中while前调用两个库函数开启外设即可。业务中随时访问数组得到ADC转换值。uint16_t testbuffer[4]={0}; while(HAL_ADCEx_Calibration_Start(&hadc1)!=HAL_OK); while(HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&testbuffer,4)!=HAL_OK);
调用HAL库函数
HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&testbuffer,4)
开启了配置好的ADC和DMA,其中:hadc1为外设的句柄,很好理解。
testbuffer
是DMA搬运的目的内存。 我希望testbuffer[0]~[3]
分别存入四个通道的转换数据,因此创建了size
为4的数组,函数第三个参数设置为4,并勾选了Memory下Increment Address
选项框。Increment Address
使得每搬运一次DR寄存器的数据后,搬运目的地的起始地址向后偏移一个Data With
,注意这里是CubeMX配置的Data With
而不是函数形参的类型宽度或目的数组的元素宽度。第三个参数为4告诉DMA搬运四次为一个循环,如果没有配置Circle模式,4次后停止。下次调用重新启用,从testbuffer
地址重新写入。Circle模式下,四次搬运四次后自动重新开启,即目的地址回到testbuffer
。 函数形参类型是
uint32_t*
,起初把我迷惑了,创建了uint32_t
类型的数组以存放DMA搬运的数据。实际上,貌似函数只使用了传入的首地址。为了便于直接使用,这里的数据类型应与DMA配置的Data Width
对应。我使用的MCU其ADC转换精度为12位,因此使用HalfWord(16bit)
足以,因此配置时两边都使用了默认的HalfWord
,该配置使DMA每次从ADC搬运16bit数据到地址testbuffer,下一波数据搬运到testbuffer+16bit
的地址中,再下一次到testbuffer+2*16bit
。如果testbuffer
是uint32_t
类型的,并不影响数据搬运行为,但访问testbuffer[0]
时,得到的uint32_t
类型的数值是通道ch1
和ch2
合并而来的,还要取高16位和低16位将两帧分开。对于每一帧,低12位是数据,剩余的4位被0填充。
testbuffer
的size
不应小于第三个参数,否则数组越界。数组可以很大,但只循环使用前面的几段。有些程序采集四个通道,用size
为400的数组,DMA也依次搬运400次,这时数组中同时保存了连续时间内的100组“四个通道的数据”,可对每个通道求取平均值当作检测值。 在上述配置下,启动后ADC时刻转换着外界模拟量的值,DMA不停搬运数据,而DMA请求不同于中断请求,高频的DMA转换并不会不占用CPU,
testbuffer[]
中被这个硬件进程不断刷新着数据。可近似认为访问testbuffer[]
时得到的是ADC转换的实时值。
STM32使用ADC+DMA进行多通道模拟量采集 (踩坑及傻瓜式解析)相关推荐
- STM32H743+CubeMX-ADC(16bit分辨率)+DMA采样三路模拟量,硬件过采样器实现1024倍过采样
一.前言 上一个笔记:STM32H743+CubeMX-ADC+DMA采样三路模拟量(并行),没过采样 这个应该是STM32上ADC采样的终极解决方案了,硬件1024倍过采样+DMA搬运数据. 在一个 ...
- STM32H743+CubeMX-ADC(16bit分辨率)+DMA采样三路模拟量(并行),没过采样。
文章目录 一.前言 二.CubeMX 2.1.RCC,SYS,Clock Configuration 2.2.CORTEX_M7(cache与MPU) 2.3.ADC3 Mode and Config ...
- 我的第一篇文章——stm32的ADC+DMA+滤波算法
stm32的ADC+DMA+滤波算法 一 工程目的 (1)外设配置 (2)源码 头文件 主文件 二 调试过程遇到的问题 1 如果打开中断 2 无法打开ADC 3 变量无法赋值 三 参考资料 四 写在最 ...
- Arduino初初教程7——模拟量采集
2019独角兽企业重金招聘Python工程师标准>>> 模拟量采集需要用到模拟量器件,这里主要指一些随着环境变化输出电压值随之变化的器件,如火焰传感器.部分温度传感器.可调电阻等等 ...
- PLC模拟量采集在工业自动化控制中的应用
在复杂的工业现场中,往往需要对温度.电压.电流.压力等等模拟量进行数据采集,可以借助PLC进行控制采集,但目前市场各种PLC模拟量采集模块十分多,不同的厂家不同的PLC都有自己独特的模拟量采集模块,而 ...
- PLC模拟量采集算法数学基础(线性传感器)
模拟量采集库如何设计,具体算法代码请参看下面这篇博文: PLC模拟量输入 模拟量转换FC:S_ITR_RXXW_BOSS的博客-CSDN博客_s_itr模拟量采集.工业现场应用特别广泛.大部分传感器的 ...
- 模拟量采集软件虚拟精度提升方案
模拟量采集软件虚拟精度提升方案 AI的数据采集精度是AI采集的重要指标,一般来说控制器的AI精度会有一个指标,比如)0.5%,这个精度是标定精度,实际AI通过高一个等级的测量系统如0.1%测量后,经过 ...
- Arduino UNO模拟量采集
Arduino UNO模拟量采集 环境准备 打开arduino开发环境 观察输出结果 环境准备 准备一个滑动变阻器,Arduino uno 板一块,接线图如下: 打开arduino开发环境 编写程序代 ...
- 树莓派拓展模拟量采集(AD)功能
1.前言 树莓派自身不带有模拟量采集功能(A/D)功能,当需要AD功能时,常通过IIC外接一个A/D模块来实现,如8位A/D芯片PCA9685.本文首先简要介绍PCA9685特性,然后基于树莓派的Bc ...
最新文章
- 编译安装LAMP之配置httpd以FastCGI方式与php整合
- 值对于int32太大或太小怎么解决_深孔加工10种常见问题及解决措施,条条都是宝贝!...
- python把c语言的.h文件转为c++的.cpp和.h文件
- Java并发编程—schedule方法和scheduleAtFixedRate方法的区别
- matlab 矩阵jocobi迭代_高校MATLAB被禁用,掀起中国本土软件脆弱的冰山一角
- java lambda表达式详解_Lambda表达式详解
- 策略模式+工厂模式(反射)+枚举代替 大量 if..else if..
- Opencv dnn实现人类性别检测和年龄预测
- java文件格式转换
- office图标修复工具_买电脑送Office,可你知道怎样才算用上吗?
- 软工导论测试代码(归档):设备管理系统
- yii2 联表查询时,查询关联表的字段时,使用asArray方法
- 单片机 STM32 HAL 闪存 AT24C02
- 立林门禁读卡器接线图_立林楼宇对讲维修方法—常见故障的解决方法
- 背离意味着趋势正在减弱
- apache、iis6、ii7独立ip主机屏蔽拦截蜘蛛抓取(适用vps云主机服务器)
- 带你读懂Spring 事务——事务的隔离级别(超详细,快藏)
- 银行智能风险防控系统(第二版)
- 解决onelink短链被应用市场劫持的问题
- 利用现代技术研发的人工智能
热门文章
- html用js生成二维码
- 一台计算机组装完成以后,要先装什么.,一台刚组装好的电脑,还需要进行哪些操作?...
- 新浪财经隆重推出四大千万级财经博客
- RK3399平台开发系列讲解(其他篇)1.11、CPU如何定频
- SEO培训: 《搜索引擎优化知识完全手册》
- 中兴手机、泰康:微信营销的妙用与滥用
- WPF程序设计读书笔记(1-1)
- Excel数据分析常用函数①——查询函数(vlookup,hlookup,lookup,match,index…)
- Linux 学习之创建、删除文件和文件夹命令
- 篮球中各个位置的名称及介绍…