所用工具:
stm32cubemx
正点原子 stm32mini
MDK-Keil软件
本片文章重在讲解概念的理解,实际操作更多的在录屏里。较多的文字力求把概念讲得透和易懂,希望大家耐心阅读。如果喜欢看视频学习,建议直接看下面的视频,不用看本文章。
什么是ADC
模拟信号
为了与数据区分,我们把平时看到的连续的信号,比如说电压、电流随时间变化的曲线。就是模拟信号。
数字信号
CPU里面用数字表示的信号。如果我们画他的曲线,则是不连续的,像楼梯一样的波形。
比如:
y=kx,可以用来表述模拟信号。
y={0|0<x<1,1|<1x<2,2|2<x<3…};
(如果还是不能理解可见视频,里面举了很多例子)
如果我们在XY坐标下绘制他们的曲线,就能明显感觉到他们的区别。这也是离散与连续的区别。
ADC
ADC全称 Analog-to-Digital Converter,即模拟-数字转换器,可以将连续变化的模拟信号转换为离散的数字信号,以便CPU进行存储,进而进行加减等数据处理,称之为数字信号处理。
STM32F103xx 系列有 3个 ADC,ADC 分辨率高达 12 位,它有多达18个通道,可测量16个外部和2个内部信号源。这些通道的 A/D 转换可以单次、连续、扫描或间断模式执行。 ADC 的结果可以左对齐或右对齐方式存储在 16 位数据寄存器中。
STM32F103rct6 的 ADC 最大的转换速率为 1Mhz,也就是转换时间为 1us(12 位分辨率 时)。
若是不能体会到转化速度、分辨率,精度等概念,没事,我们会在后面的学习中,体会到这些概念的涵义。
如何使用
线性比例转换
ADC都有满量程,比如STM32的ADC满量程基本都是3.3V,也就是可以测量的电压为0-3.3V,这里有一个好消息和一个坏消息。好消息是ADC的量程可以更改,32有个引脚VREF就是用来调节参考电压的;坏消息是,一般网上购买的开发板不会把这个参考引脚直接连接了3.3V,不会引出来。
ADC测量的测量,是在0-满量程(此处讨论32单片机,下面一概使用3.3V表示满量程),进行线性对应。
比如满量程对应数字为100,32调用ADC去测量3.3V电压,芯片得到的数据是100,如果去测量1.65V,那么芯片得到的数据是50。0V对应0。
ADC位数——分辨率
正如他的名字,反应了ADC对电压的分辨能力。我们在“线性比例转换”部分举的例子里,让满量程对应100,这个100是随意举的,实际要根据ADC位数来确定,比如今天我们的主角F1的12位ADC,3.3V满量程对应2^12-1=4095。用它去测量1.65V,ADC返回给单片机的数据是1.65/3.3*4095≈2048。
现在思考一个问题,如果用它分别去测量0V和0.3mv信号会怎么样?我们通过计算来算下。
测量0V: 0/3.3*4095=0;
测量0.3mV: 0.3/3300*4095≈0.38≈0(ADC返回的数据必须是整数)
这样就体现出了分辨率的重要性,12位3.3V满量程能分辨的电压为:3.3/4095≈8mv,也就是他能分辨的数据只能是0、0.8、1.6、2.4。。。mv,如果是中间的电压,返回的数据取就近的。如果ADC换成了13位的,那么能分辨的电压变成了3.3/(2^13-1)=0.4mv。他返回的数据就变成了0,0.4,0.8,1.2……mv。接下来我们再次测量0和0.3mv。
测量0V: 0/3.3*8191=0;
测量0.3mV: 0.3/3300*8191≈0.76≈1。
采样率
意思是采样速度,比如我们采样周期为1s的信号,如果采样率为10hz,那么一个周期可以采样10个点,如果采样率是10k,那么一个周期可以采样10k个点。
我们如何控制采样率呢,我们可以用定时器,打开它的中断,在他的中断里采样。比如我们设置定时器为10k的中断,那么它的采样率就是10k。但是这样操作虽然简单,但是频繁的进入中断会耽误CPU的运行。
定时器可以在更新时产生一个更新信号,这个信号在32内部可以作为信号,来触发ADC去采样。这样就是硬件在完成,不会打扰CPU的进程。就好比你又聘用了一个助理去帮你触发ADC,你就有时间去喝咖啡了。
cubemx操作介绍
注:原文图片未迁移(image-20210421171359078)
-
Mode:模式选择。一般选择独立模式。如果不开启多个ADC,也只能选择独立模式。
-
Data Alignment:数据对齐方式
-
Right alignment:数据右对齐。
Left alignment:数据左对齐。
-
Scan Conversion Mode:是否开启扫描模式,用于同一个ADC开启多通道。
-
Continuous Conversion Mode:是否开启连续模式。一般不建议开启,开启后采样率不可控。
-
Discontinuous Conversion Mode:没怎么用过,听名字是不连续模式,但是我一直不管他,默认选了disable,但还实际却是不连续。
-
Enable Rrgular Conversion:是否使能规则通道。默认即可。
-
Number Of Conversion:转换通道的数量。开启了几个通道,这里写几个。
-
External Trigger Conversion Source:触发源选择。
注:原文图片未迁移(image-20210421172717000)
- launched by software:软件触发(就是写一个函数,触发一次)
- capture compare X event:定时器通道比较信号。
- Trigger Out event:定时器更新信号(通常使用它来控制采样率)。
注:原文图片未迁移(image-20210421173010456)
- channel:转换通道。
- Sample Time:采样时间。
DMA
前言
关于DMA的系统介绍,完全可以单独开一节课,因为DMA使用的很是广泛,学到后面我们还会接触到升级版的DMAMUX,专为图像处理而生的DMA2D等等。有想法深入了解的同学可以阅读stm32f1的中文参考手册,或者CSDN上查找DMA的相关文章进行进一步的学习。这里只进行最基础的介绍以及如何在ADC的开发中调用DMA。
作用
DMA听起来很高级,仿佛能和DNA的专业程度一教高下,但他其实就是一个“数据的搬运工”。单片机主要靠CPU来处理中断,运行代码,搬运数据等各种事情,但是他就像人一样,一次只能做一件事,如果在搬运数据,就不能运行代码,或者中断处理反应迟钝,如果雇一个管家去帮你搬运数据,CPU就能节省出时间去做别的事情。考虑同时数据的搬运会占用大量的时间,于是32的设计师加入了DMA功能。用于搬运数据。
定时器触发
定时器在自加到ARR的时候会自动更新(一般都会设置),在更新的时候会产生一个信号,大家可以把他简单理解为持续一小段时间的高电平信号,这个信号可以在芯片内部传递,比如传递给ADC的触发端,触发ADC。
比如我们设置定时器100ms更新一次,那么他产生的触发信号的频率为10hz,这样ADC的采样速度为10hz,一秒钟采样10个点。
同时,这样的触发不用CPU干预,不像中断方式的采样,提升了CPU的效率。从中我们可以看到充分利用硬件的好处。
啰嗦几句
结尾处给大家推荐几个不错的文章,以弥补本文章的不足。这里面更多的注重于实操。
adc 采样时间 采样周期数 采样频率计算(以stm32为例),这个很重要,鉴于这位博主讲的很好了,我就不在文章里细讲如何充分发挥32的采样率。
https://blog.csdn.net/wangshixin1016/article/details/83027995
STM32CubeMX ADC单通道和多通道DMA转换
https://blog.csdn.net/sudaroot/article/details/88398971
STM32CubeMX ADC单通道和多通道DMA转换
部分信息可能已经过时