之前完成了规则通道DMA的数据传输了,不过平时在使用ADC的时候可能就会遇到很多情况,不可能就这样简单的按规则通道来采样,DMA存储,使用数据的;可能有时候会需要立刻采样,那样我们就需要利用到注入通道了。文档关于注入通道的解释: - 1 利用外部触发或通过设置ADC_CR2寄存器的ADON位,启动一组规则通道的转换。 ' e3 \' {* G6 I# o6 @) u6 B
- 2 如果在规则通道转换期间产生一外部注入触发,当前转换被复位,注入通道序列被以单次扫描方式进行转换。 , W/ K( a O/ |* i! a9 H5 @
- 3 然后,恢复上次被中断的规则组通道转换。如果在注入转换期间产生一规则事件,注入转换不会被中断,但是规则序列将在注入序列结束后被执行。</font>
复制代码# c; X* I4 c$ o5 v2 r
将变阻器的那路ADC设置为注入通道:
; u' g: E# c+ l' {9 a, L: Y- 1 ADC_InjectedSequencerLengthConfig(ADC1, 1);\\设置注入通道长度9 c4 s* A% `' I" ^5 j- N% D; @1 N$ r
- 2 ADC_InjectedChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_7Cycles5);\\配置注入通道
0 p& W; U. M, e - 3 ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);\\开始注入通道数据采样和转换</font>
复制代码 / G. C5 A8 P5 b, Q
/ n4 ~* S( j* x1 N 开始之后,延迟足够的时间,让ADC采样和转换完成。3 [6 S; w5 R, E
用ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);读取注入通道1的数据,结果发现数据一直不变,那肯定是哪里设置出错了,找了下别人的设置,并做了一些尝试,发现了原来是设置的问题,注入采样的触发方式没有设置:2 r$ o% J" Q0 L! O0 A$ I$ j
- ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);</font>
复制代码 2 t! r+ B4 I" Y5 V
这个函数设置注入方式使用软件触发方式,设置完之后用开始采样和读取数据函数,就能采到正确的数据。
' p! G/ j9 j6 q7 |3 D p
6 Y& v$ _: q3 i# G 上面的例子使用触发注入完成的,下面又尝试了自动注入。这样每次进行规则通道采样时,也会顺便把注入通道也进行采样了,而启动注入通道采样则不会对规则通道进行采样。9 L0 P( d+ g+ [5 B8 q# l/ ~: I" X
如果设置了 JAUTO 位,在规则组通道之后,注入组通道被自动转换。这可以用来转换在 ADC_SQRx 和 ADC_JSQR 寄存器中设置的多至 20 个转换序列。& X# L* ]/ y2 e2 A+ P
+ ?" b! i) n# J0 n 还有在规则通道使用DMA数据传输,且使用注入通道采样时,不知道会不会对数据有影响?
- }, [! \- y+ M! _% b5 J 查了下文档,只有在规则通道的转换结束时才产生 DMA 请求,并将转换的数据从 ADC_DR 寄存器传输到用户指定的目的地址,还有注入方式转换后数据存储到 ADC_DRJx寄存器和规则方式转换后数据存储在ADC_DR寄存器中。- o |" p' Z _0 }4 o) c$ t5 L
T& Y" Y8 ^- G' m9 w0 k' v/ l; _1 @( X1 q7 ~: K
在注入通道和规则通道的混合使用中,我花了不少时间去找正确的设置,问题是不知道哪些库函数是必要的,哪些是非必要的,后来对着例子尝试之后才知道。后面我还想了解下具体的寄存器设置,看了几个初始化的函数,发现其实很多设置都是对ADC_CR1的设置,有不少不明白的看了寄存器就知道了,看来函数的使用还是要和寄存器对应的位结合起来,这样才能理解的透彻点。% n" S5 R* O7 G$ p/ v' L
下面是我整个代码的设置,其他设置和上篇例子一样,只改了ADC设置:
" L+ I% s) P" e* X! s2 ?, ^; b
0 Q" ]' i. }) M) [- w7 u8 b- static void Protect_AdcInit(void)
( P2 C, F; g2 y; Q8 w q8 v- R" a - { . J0 ?+ a$ H7 h2 w
- ADC_InitTypeDef ADC_InitStructure;
9 S' p$ w }% H- n* A5 M4 f6 U3 H - ( E3 ?. L; p* b6 ~. H
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 6 v5 \# V" Q% U6 ~' e0 ^+ f) f
- ADC_InitStructure.ADC_ScanConvMode = ENABLE;
; P2 g/ [+ g$ J' V, D - ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; 9 j; y# u7 S# T- \, O, t
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发 % G: {5 o) O5 A. l% B8 z) p
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 2 {+ X& p8 l% m" y- g
- ADC_InitStructure.ADC_NbrOfChannel = 2;//规则通道的数量
' e, h: c5 X3 g( x& N% a4 U( z - ADC_Init(ADC1, &ADC_InitStructure);//这个大部分是初始化规则通道的
+ `0 e4 e" r, L, L - $ w: @( H! i/ q6 O3 ~
- ADC_TempSensorVrefintCmd(ENABLE);
J O/ A: Q% p c6 b$ F6 Q' r - ADC_RegularChannelConfig(ADC1,ADC_Channel_TempSensor,1,ADC_SampleTime_239Cycles5);
0 y8 y4 T0 s) U8 I, A0 H+ ` - ADC_RegularChannelConfig(ADC1,ADC_Channel_Vrefint,2,ADC_SampleTime_239Cycles5);
4 w* `/ d; Y Z8 \ -
. N2 ? d; ^% J - ADC_InjectedSequencerLengthConfig(ADC1, 1);
* t8 Z8 [' R9 e: p' _9 h# c: S" K - ADC_InjectedChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_7Cycles5); ' b( f: t$ m5 y3 O
- ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);//设置规则通道软件触发 - \8 E& R8 b' \9 h" @
- /* Enable automatic injected conversion start after regular one */
# x" O# N# Y8 a - // ADC_AutoInjectedConvCmd(ADC1, ENABLE);
9 h& w7 v' j6 t; v, f; g -
6 O! T+ W$ I$ ~ -
; r' @8 _0 n3 Z# M/ ?, f. N0 b - ADC_DMACmd(ADC1, ENABLE); / c$ P( h+ A5 P; u% g' R+ @; l
- /* Enable ADC1 external trigger */ ! {$ p9 h- F$ ?$ R0 |0 @# t
- ADC_ExternalTrigConvCmd(ADC1, DISABLE); ) t! N' [4 Z/ U; a, t
- ADC_ExternalTrigInjectedConvCmd(ADC1, DISABLE); " i4 S% P( g) e3 {: ~
- + n q: y" T L# i5 f% \+ e7 A
- ADC_Cmd(ADC1, ENABLE);
& p! @# X) M7 | -
2 v$ Z( {: W& R# ^2 T( C* z) f - ADC_ResetCalibration(ADC1);
2 M8 m8 D8 j2 V) a3 _ -
6 l+ b% R; s l g& c - while(ADC_GetResetCalibrationStatus(ADC1));
" o7 S9 c3 ?: g- ?$ b" K5 T Z -
! v; W% M* V. a3 I: T0 e+ l - ADC_StartCalibration(ADC1); 3 r5 x6 a4 D; r+ F( h* \
- ( i g, {$ M# `$ q2 [8 N
- while(ADC_GetCalibrationStatus(ADC1)); , e: m7 x, L! @' f* |
- 9 {" H o" N( p1 W/ g
- } [/size]
复制代码 , [; {- v7 e" V) K! z8 I2 S! M
8 x+ g, S6 R, l8 o H" E A9 @6 U
读取数据在这里:. Z ?2 |! q$ [# I" B7 Z
- /* 注入转换中断 */6 E2 Q# U7 P9 n! Z1 w, M: o2 z) p- Z
- void ADC1_2_IRQHandler(void)7 J9 I/ h* d) x6 f( Z
- {8 u7 t k; }4 p# P, S2 C7 n
- s32 inj_v1,inj_v2,inj_v3,inj_v4;
( `4 M: P* u/ j - 4 `1 V' r% n+ Q: u
- if(ADC_GetITStatus(ADC1,ADC_IT_JEOC) == SET){
1 w7 ?2 v4 F! r - ADC_ClearITPendingBit(ADC1,ADC_IT_JEOC);! [2 ^, O( C9 N- }
- inj_v1 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);
( M8 i' j0 Y0 w# B3 a" U - inj_v1 += ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_4);
, V1 U) P$ e! e& E) o/ ` - inj_v1 >>= 1;
; K" @9 g& N, J7 J) x- x7 { - 2 r- k5 p2 c) y: q* y! T" x0 j4 F
- inj_v2 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2);$ U) X. [# X/ t) r3 S4 U1 E; C* }; R
- inj_v2 += ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_3);
/ L3 g4 Q# B }3 N - inj_v2 >>= 1;1 \# u# U, T/ {8 I( W5 F$ q
- 0 Q3 d& }' f9 z& N
- inj_v3 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_3);
6 X( `6 s: b7 y; ~' H% ] - inj_v3 += ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_2);& K$ Y6 K# x" K% ^4 D: c
- inj_v3 >>= 1;
9 h9 t# u0 { i$ D! @9 \ e
* l; D+ M3 J+ I3 ~- `' r4 K8 |0 D6 {7 x- inj_v4 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_4);" E( h: m" b- P2 e( W& \. L' O% v7 F
- inj_v4 += ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_1);& [. X. }* y6 I* g3 w
- inj_v4 >>= 1;
) U* k- d- d' X1 F7 V, x& t - }
" }; i: C C1 }! |7 A# d - }9 O! h8 o4 J: x
. m* J4 d Q [: T: h7 K# w- /* 规则转换中断 */, E! F3 X$ z D3 b2 L
- void DMA1_Channel1_IRQHandler(void)
/ ~" f% H6 g$ Q$ Z9 s - {; c1 u- F& o# w; `- u3 K; y9 I
- if(DMA_GetFlagStatus(DMA1_FLAG_TC1) == SET){
0 D; Q& N/ D. A4 q B$ r" R# \ - DMA_ClearFlag(DMA1_FLAG_TC1);# }: o3 z0 z7 @* l- e
- DMA_ClearITPendingBit(DMA1_IT_GL1);
0 O o8 q# G' R- I - ADC_SoftwareStartConvCmd(ADC1,DISABLE);
0 ]- B5 z% R4 i - DMA_Cmd(DMA1_Channel1,DISABLE);
e1 }- q) `, N$ n# j - 4 M0 A8 S1 x: } B' a
- regular_convert_calc();) `0 D3 g3 A7 T u p6 t% U6 _$ d
- ! p! D& G9 ^5 s+ Z9 |
- DMA1_Channel1->CNDTR = NUM_OF_REG_CHANNEL;
4 n6 C9 B G- K( n K - DMA_Cmd(DMA1_Channel1,ENABLE);
3 ^+ t4 ]' | ~/ y# O - ADC_SoftwareStartConvCmd(ADC1,ENABLE);
, _( h7 s' l& ~ - }
7 B' R% T P1 }1 w+ v0 ~* s - }</font>
复制代码 ; `4 X; G( b, m; [. Z1 z+ m& K
来源:lanmanck |
感谢分享!!!