你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103ADC的工作模式和触发方式的探索与理解,结合自我.....  

[复制链接]
拼命三郎 发布时间:2015-1-6 22:43
STM32F103ADC的工作模式和触发方式的探索与理解,结合自我探索分享。
4 U2 k& p, b/ F% {1 z2 H' m9 G- j  Z
7 e5 d- `# W* s5 r
前段时间做开发用到了STM32规则通道的ADC,因为需要定时采集,所以使用了外部触发方式。初次接触到STM32的ADC感觉还可以驾驭,但随着开发的推进,发现自己对于STM32ADC的不知之处还有好多,现将开发过程中的心得与大家分享。
6 W. u# |: l7 F2 w1、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采集之后的计算方式与内部参照电压是相同的。, W7 Y0 `2 p: X8 _, g0 z% u0 \) l9 A
2、STM32F103ADC通道转换模式的问题:5 }: d' L4 `# {. q7 ~
STM32的ADC有单次转换和连续转换2种模式,这两种模式又可以选择是否结合扫描模式。( V' e9 K# l" {) t& J
CONT=0,SCAN=0    单次转换模式(Single conversion mode)单次扫描1通道- N. v, d+ r! j  b  I: N
CONT=1,SCAN=0    连续转换模式(Continuous conversion mode) 连续扫描1通道* d. ?/ G. _+ M# N, y
CONT=0,SCAN=1    扫描转换模式(Scan mode):所有ADC_SQR序列通道转换一次后停止。(单次扫描组)
2 S/ p* k3 k2 X' \; vCONT=1,SCAN=1    扫描转换模式(Scan mode):所有ADC_SQR序列通道转换一次后,再从第一个通道循环。连续扫描一组/ E' y  ?- n: b- h  \

  |$ s4 Q( _, S$ H% r需要注意的是,如果你的转换序列当中有超过一个通道需要转换的话,那么必须要开启扫描模式,否则的话,始终只转换第一通道。6 E$ c5 G/ f- j8 T2 O: O2 j
* K8 X* O& K# U- e4 y* ]9 e

0 l% J; r( l2 L; X% V& \用ADC1,Regular通道的顺序为Ch0,Ch1,Ch2,Ch3,启动Scan模式
6 h# P1 B( A. d/ L3 T. P) l# P在单次转换模式下:' @1 _9 I" {- y/ J- k
启动ADC1,则: x  p! G$ p8 s3 g" d, ?( y
1. 开始转换Ch0& Q5 s% j; a) g9 S, v5 i. S
2. 转换完成后自动开始转换Ch1
2 }0 y( b( o) {# h* n3. 转换完成后自动开始转换Ch2
, b: E; `1 {( Z4 {; m4. 转换完成后自动开始转换Ch3* u! X2 E+ v: |0 ~! p' k7 _* ?- t, L
5. 转换完成后停止,等待ADC的下一次启动。下一次ADC启动从第一步开始
$ L/ O/ E3 o& M+ ~  \  |在连续转换模式下:
' R) g: w. L  t3 b9 @$ p2 y启动ADC1,则
8 A! r: p  U$ W3 X6 Y7 Q1. 开始转换Ch0
5 }6 _5 n) B( H" e$ o6 W, r2 t. `, ~2. 转换完成后自动开始转换Ch1/ f: c) z7 @3 a$ }+ T( Q+ L- y7 }
3. 转换完成后自动开始转换Ch2
" `" s$ ?) E3 r4. 转换完成后自动开始转换Ch3
0 X# ^0 r' Q0 [5. 转换完成后回到第一步9 V- _% f$ F- ~# |
如果没启动Sacn模式则上述过程中没有2、3、4这三个步骤
8 A# X7 S2 q" h上述前提是Discontinuous模式没有启用。# H" _6 m# s/ |  M8 s# ?

  |7 ~+ c$ X. C$ _4 O5 y, _2 @4 T  C3 v5 n9 o6 D1 Y+ j
关于这个扫描模式,着实让我纠结了好久,一开始,根据中文手册上的来。咱玩包含两个通道的规则通道采集,完了还不带DMA的。

手册中对规则通道转换的描述

手册中对规则通道转换的描述
,手册说了每一个规则通道转换完毕都置位EOC,那就是每转换一个通道都可以进中断喽,那这样的话,咱还用啥DMA啊,直接中断吧,好吧。就这么办,程序写好了,跟踪调试发现,中断虽然进了,但是只有第二组数据。为什么不行呢,手册中讲的好好的,怎么就不行了呢,带着这个疑问,楼主开始了探索之旅1 z  Z2 m3 H% x8 j
首先继续不用DMA,在主函数中采用以下语句读取ADC数据。
8 A/ t8 P/ r1 n8 O8 |    while (1)$ h, J0 l9 C0 P. p. w& R8 g
    {, E7 H8 ?' L5 K; p0 |
                if((ADC1->SR)&0x02)//读取判断EOC位+ J7 m7 N) S: M" X/ ]* w
                {; [3 l% I: `1 L; c# g6 [
                        adcx = ADC_GetConversionValue(ADC1);        //返回最近一次ADC1规则组的转换结果: {6 |! E# O  J% Q5 d4 o
                        Filter_Table[ Filter_Tab_Count++ ] = adcx;& R3 z7 t4 N% \5 s
                }
% b2 A3 l: S( h3 M& `  V! Y    }
% e$ h& M5 D8 ]2 r还是只有最后一组数据。好吧,那这样好了:" I- ^7 L- G0 F! h3 L
    while (1)
, w; u0 q  e; T, z; l$ t! a6 N    {! b% z( ?7 f& v1 O: H; Q# ^
                adcx = ADC_GetConversionValue(ADC1);        //返回最近一次ADC1规则组的转换结果
: @# z; w- }' |, ~6 w6 s( S                Filter_Table[ Filter_Tab_Count++ ] = adcx;* S# J$ V! e6 H! G9 K' w* {
    }
8 M; P6 k. m. {终于凑效了,可以在跟踪的时候,在不同时间停下的时候读到第一组和第二组数据了,这是为什么呢,这说明第一通道也是在转换的,只是在转换完毕的时候没有置位EOC罢了,当然也就不能触发ADC中断了。% P) a3 P8 [! c$ N' c
1 l2 S3 f( ]6 H" z" E
& e% R2 D' n2 }' w. [+ i' v0 k% O
看来又被手册忽悠了,多个通道用中断的方式是不行的。PS:手册中的一个规则通道应该指的是一个规则通道组。
% Y! ]3 q0 p  s$ X; F# Z7 S2 l' M) p! o* A- ?# Z
好吧,那启用DMA好了,那么问题来了,手册扫描模式中讲到

手册中对规则通道扫描模式的描述

手册中对规则通道扫描模式的描述
,EOC置位后DMA才来搬运数据,那么岂不是要丢好多数据!当然中文手册也讲了,以英文手册为准,既然有疑问,那咱翻翻英文手册好了 3.jpg 英文手册中讲到,在ADC_DR寄存器每次更新后,DMA才会搬运数据。总结:ADC在采用规则通道组采集的时候必须启用扫描模式,并且启用DMA传输支持。
( \: q8 }; O4 T% q  \7 M5 o5 `: p- t

5 l8 u; ?2 K, w! S1 a好了,终于写的差不多了,由于个人能力有限,有表达不清的地方还请斧正,我一定更改,这么晚了,洗洗睡去了。! G* O1 F( {/ N6 h. D8 g% ^, a6 F& m
7 B& l+ i& q# D* x  K
/ k4 ?( P6 P  R8 e: K
赞 1 收藏 6 评论85 发布时间:2015-1-6 22:43

举报

85个回答
默罕默德.ST 回答时间:2015-1-7 19:18:48
u16 TestAdc(void)
" x* p+ }( m% C; N& j% F0 b+ }{
5 ~4 g& O; U  J: Gu16 adc; 1 t6 f* b9 X) _: k; F; s% C
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)==RESET); //检查制定ADC标志位置1与否 ADC_FLAG_EOC 转换结束标志位 : c- u" o( t  Q1 X+ }; C- X' t
adc=ADC_GetConversionValue(ADC1);
+ j& l4 P3 G* n6 O' r& w
5 G& v% n2 S3 X6 s$ ereturnadc;//返回最近一次ADCx规则组的转换结果& t3 M) d, x( y* H
}查询方式获取AD值
拼命三郎 回答时间:2015-1-7 21:43:33
山东大哥 发表于 2015-1-7 18:215 R$ C. V5 O. s* W) n
STM32的定时器功能石灰厂强大的,当然学习起来也是很难的,当时跳ADC的时候也走了很多的弯路,而官方这方面 ...

, G+ t, x5 F) c$ i& I( oSTM32的定时器理解起来确实很费脑细胞
a93749 回答时间:2018-3-1 11:23:28
你没开启间断模式吧,所以eoc不能每次都更新。
, {) M& c+ A' Z1 h9 Z* W, P8 n对于规则通道组,间断模式下每转换一个通道,EOC就会置位一次。因此不必像SCAN模式那样必须采用DMA来搬运数据。
拼命三郎 回答时间:2015-1-6 22:50:53
自己顶上去,睡觉了。
天好蓝 回答时间:2015-1-7 08:46:20
学习了,研究下。
拼命三郎V5 回答时间:2015-1-7 08:54:26
最近正在做ADC采集,学习了。
625058882 回答时间:2015-1-7 09:08:10
中文手册仅供参考,请以英文手册为准,说实话我也上过当
拼命三郎 回答时间:2015-1-7 09:37:39
ADC.zip (2.78 KB, 下载次数: 239)
大秦正声 回答时间:2015-1-7 09:52:26
分辨率实际效果如何谢谢
拼命三郎 回答时间:2015-1-7 17:21:04
大秦正声 发表于 2015-1-7 09:52
* R* _2 ^7 s- J) S- t- x6 S3 V3 W分辨率实际效果如何谢谢
2 o" d- c0 W( C% E$ T5 U7 ^
还没有研究过分辨率
我是酱油哥 回答时间:2015-1-7 17:27:00
103有十二位的ADC 其分辨率是不是1/4096?
kxj116 回答时间:2015-1-7 17:36:36
应该是4095分之一,分辨率和采集速度设置什么的没什么关系
guomenhaolaogon 回答时间:2015-1-7 18:08:33
哈哈,狗曲折的,中文版的手册太旧太狗血了。纸上得来终觉浅,绝知此事要躬行。
山东大哥 回答时间:2015-1-7 18:21:57
STM32的定时器功能石灰厂强大的,当然学习起来也是很难的,当时跳ADC的时候也走了很多的弯路,而官方这方面的支持貌似很不足。
台湾华瑞 回答时间:2015-1-7 18:47:21
做技术,就是苦逼,唯有不断的探索才能成功。
拼命三郎 回答时间:2015-1-7 19:21:45
默罕默德.ST 发表于 2015-1-7 19:18
4 q, E& s8 \8 i1 q1 r. ju16 TestAdc(void) # k7 J3 y* |6 e- @: b
{ 5 F" C: f2 m, {6 N1 E
u16 adc;
/ s5 l' t7 t* g
了解了,有时间交流下

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版