
前段时间做开发用到了STM32规则通道的ADC,因为需要定时采集,所以使用了外部触发方式。初次接触到STM32的ADC感觉还可以驾驭,但随着开发的推进,发现自己对于STM32ADC的不知之处还有好多,现将开发过程中的心得与大家分享。. h0 H6 ]5 q. |4 u! ` 1、STM32F103中不足100脚的芯片ADC参考电压在芯片内部接到Vadd管脚上,这个是无论如何都不能通过设置寄存器更改的。那么STM32内部有没有参考电压呢,答案是否定的,参考电压是没有的,参照倒是有一个1.2V的。说实话,一开始我也以为这个参照电压就是参考电压,但是随着学习的跟进,发现这个参照电压的作用仅仅是可以”参照“而已,前面也讲了参考电压Vref已经接到Vadd上了,那么这个参照电压和Vref不是一回事了。只是用于修正你所读到的ADC值而已。举个例子吧:假设Vref=Vadd=3.3,在AD采集的时候要一次读取ADC通道的值和通道17即参照电压的值,假设此时读到的AD值为2000,读到通道17的值为1500。此时如果参照电压是准的,Vadd是波动的,那么Vref实际的值应该是4095*1.2/1500=3.27V,那么AD值2000对应的电压应该为2000/4095*3.27V=1.597V。这样大家就可以理解参照电压的作用了,如果大家还不满足内部参照电压的精度的话,可以再开辟一个AD通道,外接外部基准电压芯片。AD采集之后的计算方式与内部参照电压是相同的。 2、STM32F103ADC通道转换模式的问题:+ L. q. E0 l' U" Y! ~, K STM32的ADC有单次转换和连续转换2种模式,这两种模式又可以选择是否结合扫描模式。6 j3 Q F5 h) a* d* ?* `. E9 `4 r CONT=0,SCAN=0 单次转换模式(Single conversion mode)单次扫描1通道: ?* p2 y8 p; K' Y& O CONT=1,SCAN=0 连续转换模式(Continuous conversion mode) 连续扫描1通道 CONT=0,SCAN=1 扫描转换模式(Scan mode):所有ADC_SQR序列通道转换一次后停止。(单次扫描组)6 O1 T7 k; o) w( w CONT=1,SCAN=1 扫描转换模式(Scan mode):所有ADC_SQR序列通道转换一次后,再从第一个通道循环。连续扫描一组 需要注意的是,如果你的转换序列当中有超过一个通道需要转换的话,那么必须要开启扫描模式,否则的话,始终只转换第一通道。, G4 ?% ~, t+ ^: c# o . D% x2 u" |- N& O Q - `: b, h9 P+ ^8 |# B 用ADC1,Regular通道的顺序为Ch0,Ch1,Ch2,Ch3,启动Scan模式 在单次转换模式下:9 J% ?2 s, B, c4 r" A7 S9 x 启动ADC1,则 1. 开始转换Ch0 2. 转换完成后自动开始转换Ch1 3. 转换完成后自动开始转换Ch2, u l& `7 P% [- V 4. 转换完成后自动开始转换Ch3 5. 转换完成后停止,等待ADC的下一次启动。下一次ADC启动从第一步开始8 b: e+ C% g7 P, l, @& b H2 a/ B 在连续转换模式下:( p% J( q* N) l$ X- j& z; ` 启动ADC1,则 1. 开始转换Ch0( P1 |' F2 P% v& p0 f 2. 转换完成后自动开始转换Ch1 3. 转换完成后自动开始转换Ch2/ o6 p4 y$ W# L9 ?% H 4. 转换完成后自动开始转换Ch3: s& {0 ^) ~7 x1 {4 m. r 5. 转换完成后回到第一步 如果没启动Sacn模式则上述过程中没有2、3、4这三个步骤 上述前提是Discontinuous模式没有启用。 关于这个扫描模式,着实让我纠结了好久,一开始,根据中文手册上的来。咱玩包含两个通道的规则通道采集,完了还不带DMA的。 ![]() n1 N) k0 k9 y2 ?3 O7 F+ y5 G 手册说了每一个规则通道转换完毕都置位EOC,那就是每转换一个通道都可以进中断喽,那这样的话,咱还用啥DMA啊,直接中断吧,好吧。就这么办,程序写好了,跟踪调试发现,中断虽然进了,但是只有第二组数据。为什么不行呢,手册中讲的好好的,怎么就不行了呢,带着这个疑问,楼主开始了探索之旅; q9 b& u2 E+ j0 d2 e 首先继续不用DMA,在主函数中采用以下语句读取ADC数据。
还是只有最后一组数据。好吧,那这样好了:
终于凑效了,可以在跟踪的时候,在不同时间停下的时候读到第一组和第二组数据了,这是为什么呢,这说明第一通道也是在转换的,只是在转换完毕的时候没有置位EOC罢了,当然也就不能触发ADC中断了。9 t* ?6 [. |+ Y( U6 U 6 A- A- _3 J( ]& k 看来又被手册忽悠了,多个通道用中断的方式是不行的。PS:手册中的一个规则通道应该指的是一个规则通道组。 % ~6 ^+ a, Q9 ~- f6 E ![]() 好吧,那启用DMA好了,那么问题来了,手册扫描模式中讲到,EOC置位后DMA才来搬运数据,那么岂不是要丢好多数据!当然中文手册也讲了,以英文手册为准,既然有疑问,那咱翻翻英文手册好了 ! N( h" F6 ~' b2 r; j( L' \ ![]() 英文手册中讲到,在ADC_DR寄存器每次更新后,DMA才会搬运数据。总结:ADC在采用规则通道组采集的时候必须启用扫描模式,并且启用DMA传输支持。4 c# Y7 [+ f6 o: z( ~ 3 D2 @0 y6 L+ h" x T$ [ ) o1 Q/ Y- J5 F% z8 l8 ^, A; Q |