目录
1、介绍
(1)ADC,模拟信号转换为数字信号
GPIO只能读取引脚的高低电平,
而ADC可以对高低电平之间的任意电平之间的任意电压进行量化,最终用一个变量来表示。读取这个变量就可以知道引脚的电压到底是多少。(将模拟信号转换为数字信号,是模拟电路到数字电路的桥梁)
ADC就是相当于一个电压表,把引脚的电压值测出来,放在一个变量里。
(2)DAC和PWM,数字信号转换为模拟信号
DAC:数字模拟转换器,可将数字变量转化为模拟电压(数字到模拟的桥梁)。主要应用在波形生成领域,如信号发生器、音频解码芯片等。
PWM也有DAC的功能,PWM只有完全导通和完全断开两种状态,这两种状态都没有功率损耗,所以在直流电机调速这种大功率的应用场景,使用PWM来等效模拟量是比DAC更好的选择。并且PWM电路更加简单,更加常用。
(3)ADC的两个关键参数
分辨率:一般用多少位来表示,12位AD值,表示范围为0~2^12 - 1(即量化结果的范围是0~4095),位数越高,量化结果就越精细,对应分辨率就越高。
转换时间(转换频率):AD转换需要一小段时间,1μs表示从AD转换开始到产生结果,需要花费1μs的时间,对应AD转换的频率就是1MHz(为STM32 ADC的最快转换频率,若转换一个频率比较高的信号,就要考虑这个转换频率够不够用)
(4)
输入电压0V对应转换结果0,3.3V对应4095
二者呈线性关系
(5)
(该系列最多有)16个外部信号源是16个GPIO口,在引脚上直接接模拟信号就行,不需要任何额外的电路,引脚就能直接测电压;
2个内部信号源是内部温度传感器(可测量CPU的温度,内部参考电压为一个1.2V左右的基准电压)和内部参考电压 VREFINT(V Reference Internal)。
(6)
普通的AD转换流程是:启动一次转换、读一次值,再启动、再读值。
STM32的ADC比较高级,可以列一个组,一次性启动一个组,连续转换多个值。并且有两个组,一个用于常规使用的规则组,一个用于突发事件的注入组
(7)
ADC一般用于测量光线强度、温度的值,并且经常有一个需求是,如果光线(温度)高于某个阈值、低于某个阈值时,执行一些操作。高于某个阈值或低于某个阈值的判断,可以用模拟看门狗来自动执行。
模拟看门狗可以检测指定的某些通道,当AD值高于它设定的上阈值或低于下阈值时,就会申请中断,执行中断函数里的相应操作。(这样就不需要手动读值,再用 if 进行判断了)
(8)
ADC的资源有ADC1、ADC2 共两个ADC外设;
最多只能测量10个外部引脚的模拟信号(想要更多的外部通道,可选择引脚更多的型号)
2、逐次逼近型ADC
(1)型号为ADC0809 的普通ADC
若DAC输出电压比较大(小)就调小(增大)DAC数据,直到DAC输出的电压和外部通道输入的电压近似相等,这样DAC输入的数据就是外部电压的编码数据了。
通常使用二分法进行寻找
(2)STM32的ADC
1)
一般情况下,使用规则组就足够了
2)触发ADC开始转换的信号
触发ADC开始转换的信号有两种:①软件触发,在程序中手动调用一条代码就可以启动转换;②硬件触发
因为ADC经常需要过一个固定时间段转换一次,比如每隔1ms转换一次,正常思路为用定时器,每隔1ms申请一次中断,在中断里手动开始一次转换。但频繁进中断对程序有一定影响(若有很多中断,可能导致一些中断不能及时响应),这种需要频繁进中断,并且只是进行一些简单的操作的,一般会有硬件支持。
如:给TIM3定个1ms的时间,把TIM3的更新事件选择TRGO输出,在ADC这里选择开始触发信号为TIM3的TRGO,这样TIM3的更新事件就能通过硬件自动触发ADC转换了。
3)
4)
3、ADC通道与引脚的对应关系
4、转换模式(4种)
①单次转换,非扫描模式:只转换一次,想再启动一次转换就需要再触发一次;非扫描模式下,菜单只有第一个序列1的位置有效,这时,菜单同时选中一组的方式就退化为简单地选中一个的方式。
②连续转换,非扫描模式:一次转换结束后不会停止,立刻开始下一轮的转换,然后一直持续下去;菜单列表只用第一个。
③单次转换,扫描模式:只转换一次;确定有几个通道,每次触发之后,依次对这前几个位置进行AD转换,转换结果都放在数据寄存器里,为防止数据被覆盖,就需要用DMA及时将数据挪走。
④连续转换,扫描模式:一次转换结束后不会停止,立刻开始下一轮的转换,然后一直持续下去;只转换一次;确定有几个通道,每次触发之后,依次对这前几个位置进行AD转换,转换结果都放在数据寄存器里,为防止数据被覆盖,就需要用DMA及时将数据挪走。
⑤间断模式
5、触发控制
6、数据对齐
我们这个ADC是12位的,它的转换结果就是一个12位的数据,但数据寄存器是16位的,所以存在一个数据对齐的问题。
一般使用右对齐
7、转换时间
8、校准
校准过程是固定的,只需要在ADC初始化的最后,加几条代码就行了