之前完成了规则通道DMA的数据传输了,不过平时在使用ADC的时候可能就会遇到很多情况,不可能就这样简单的按规则通道来采样,DMA存储,使用数据的;可能有时候会需要立刻采样,那样我们就需要利用到注入通道了。文档关于注入通道的解释: - 1 利用外部触发或通过设置ADC_CR2寄存器的ADON位,启动一组规则通道的转换。
- T! |3 i0 h8 t# K; w7 {9 z3 I - 2 如果在规则通道转换期间产生一外部注入触发,当前转换被复位,注入通道序列被以单次扫描方式进行转换。 ( n6 ~: E7 ]6 f9 i# R$ e
- 3 然后,恢复上次被中断的规则组通道转换。如果在注入转换期间产生一规则事件,注入转换不会被中断,但是规则序列将在注入序列结束后被执行。</font>
复制代码
* _8 ~# Y2 z8 o$ D1 R( ^& P+ B: U 将变阻器的那路ADC设置为注入通道:
& u! y! Z1 T+ o" H- 1 ADC_InjectedSequencerLengthConfig(ADC1, 1);\\设置注入通道长度
2 T% d7 L7 D P2 A" P - 2 ADC_InjectedChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_7Cycles5);\\配置注入通道7 Z$ R9 z7 l. Y7 W7 s6 P
- 3 ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);\\开始注入通道数据采样和转换</font>
复制代码
! H, ]. | j* e' H0 I+ A( I
7 o& r1 ~' E' E( I _ 开始之后,延迟足够的时间,让ADC采样和转换完成。
( E+ O% x+ B, h5 U+ r# } 用ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);读取注入通道1的数据,结果发现数据一直不变,那肯定是哪里设置出错了,找了下别人的设置,并做了一些尝试,发现了原来是设置的问题,注入采样的触发方式没有设置:8 J# I4 ?( O$ o$ L& @# V
- ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);</font>
复制代码 4 `7 {4 f5 g' n0 z- d
这个函数设置注入方式使用软件触发方式,设置完之后用开始采样和读取数据函数,就能采到正确的数据。9 u. W/ Z8 M, `( v! X& B
' B% f2 t( F; x0 Q( T( M
上面的例子使用触发注入完成的,下面又尝试了自动注入。这样每次进行规则通道采样时,也会顺便把注入通道也进行采样了,而启动注入通道采样则不会对规则通道进行采样。7 \2 M7 C7 N% Y |
如果设置了 JAUTO 位,在规则组通道之后,注入组通道被自动转换。这可以用来转换在 ADC_SQRx 和 ADC_JSQR 寄存器中设置的多至 20 个转换序列。
+ |$ P1 A: Q" ~2 t3 j/ a8 [; q8 a
2 }9 z& q/ i4 A# h# V! Y" z D4 c- | 还有在规则通道使用DMA数据传输,且使用注入通道采样时,不知道会不会对数据有影响?
4 i1 ]6 q$ O- ? Q' f" s 查了下文档,只有在规则通道的转换结束时才产生 DMA 请求,并将转换的数据从 ADC_DR 寄存器传输到用户指定的目的地址,还有注入方式转换后数据存储到 ADC_DRJx寄存器和规则方式转换后数据存储在ADC_DR寄存器中。
0 m1 U) F' h7 v7 g6 w' m4 r/ f. C: P
e/ H. D$ _, u" I& J. i
在注入通道和规则通道的混合使用中,我花了不少时间去找正确的设置,问题是不知道哪些库函数是必要的,哪些是非必要的,后来对着例子尝试之后才知道。后面我还想了解下具体的寄存器设置,看了几个初始化的函数,发现其实很多设置都是对ADC_CR1的设置,有不少不明白的看了寄存器就知道了,看来函数的使用还是要和寄存器对应的位结合起来,这样才能理解的透彻点。
) g+ ^( Z4 K$ ^9 s- b1 _$ ~1 d d 下面是我整个代码的设置,其他设置和上篇例子一样,只改了ADC设置:
6 w, O u# y. r0 U, L& Q# s: V! n) O: {1 M" b
- static void Protect_AdcInit(void) " A& C0 }( ^8 K! [
- {
; l* ]' o6 u7 ^. l, a( j - ADC_InitTypeDef ADC_InitStructure; $ X1 A; ]* [2 s$ V$ v, \! @. I
- 1 \3 y! f6 o7 q* p/ q5 q% Q
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
3 l0 F' i! s7 b2 E: d) R - ADC_InitStructure.ADC_ScanConvMode = ENABLE;
- s* ?* p! ?1 k - ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; / J& M( {5 S" u
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发
+ w/ Q( l" d: y, c - ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ) ^9 @! _$ v z; s
- ADC_InitStructure.ADC_NbrOfChannel = 2;//规则通道的数量 o$ ]/ A% l/ N9 W9 @: d3 H! N# R) I- f
- ADC_Init(ADC1, &ADC_InitStructure);//这个大部分是初始化规则通道的
+ ^# z) M+ p4 R& k5 ?- c. } -
; A# N, _7 S- Z* w% ` - ADC_TempSensorVrefintCmd(ENABLE); m1 I# b- r; o
- ADC_RegularChannelConfig(ADC1,ADC_Channel_TempSensor,1,ADC_SampleTime_239Cycles5);
& y( g8 k) B& n i - ADC_RegularChannelConfig(ADC1,ADC_Channel_Vrefint,2,ADC_SampleTime_239Cycles5);
- [7 X4 L1 L/ a% Z- X - # t2 k" V9 Y* c3 l
- ADC_InjectedSequencerLengthConfig(ADC1, 1);
4 I3 r9 V" D, B# P. I( T, O. k - ADC_InjectedChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_7Cycles5);
5 j! m' ?) V/ |$ j! M - ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);//设置规则通道软件触发
! h3 [/ O0 y* ]' x - /* Enable automatic injected conversion start after regular one */
- |4 o# i5 Y8 N' Z" T - // ADC_AutoInjectedConvCmd(ADC1, ENABLE); ( E. ^" e6 d* R" Z' p" y: h: i
- & }+ R+ `7 ^- A. d
- & d4 d' m2 [' b! V4 L9 q
- ADC_DMACmd(ADC1, ENABLE); 9 e( T% F! K0 T4 t: R
- /* Enable ADC1 external trigger */ # j5 x- ~7 _3 ^1 \+ v
- ADC_ExternalTrigConvCmd(ADC1, DISABLE); " F: J- T1 ~, M/ r
- ADC_ExternalTrigInjectedConvCmd(ADC1, DISABLE); $ c+ ?! [/ |6 k8 g4 G% [, T
- ! ]) g; d. {0 w2 E! L& C7 k
- ADC_Cmd(ADC1, ENABLE);
2 f, g8 B6 d) l. l) @ - . ~4 k) i2 f8 O7 W# _) e
- ADC_ResetCalibration(ADC1); 4 O6 U- x* l- I0 ?! z+ K" L
-
6 Y0 h* W/ D; ?- p4 q1 h - while(ADC_GetResetCalibrationStatus(ADC1));
" `6 g0 m; E8 b; w$ C. O - + B: L4 s* Z- | r7 ~+ u
- ADC_StartCalibration(ADC1); 2 [, o9 c9 @: q. Y: Q ]
- : _! x+ @, w' H& z3 ]0 o8 t
- while(ADC_GetCalibrationStatus(ADC1));
h, r( G8 Y- m" j -
# G/ J( p* {3 E( ]+ c - } [/size]
复制代码
" H$ d. J; l: Y: H. |# X7 @% k8 {( L
读取数据在这里:
$ ?" U0 i0 \, Y2 R! j- /* 注入转换中断 */: {1 L( Y8 ]0 a* @3 J& E1 W/ A
- void ADC1_2_IRQHandler(void)
d% [( D/ }2 b) u2 F+ @ - {
* {9 B9 H1 t9 g9 t/ ?/ M - s32 inj_v1,inj_v2,inj_v3,inj_v4;
! [4 Z- J/ I& u$ y& t; D5 Z! R+ e* ]
7 y: S$ u% u4 K- if(ADC_GetITStatus(ADC1,ADC_IT_JEOC) == SET){
q+ M4 a2 \! C$ F) o X a - ADC_ClearITPendingBit(ADC1,ADC_IT_JEOC);
% ]1 i2 F& N- p8 a - inj_v1 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);
0 O% i# C9 Y( _2 N2 |- n! x# ` - inj_v1 += ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_4);) E+ d, M* k" V; r4 H/ @
- inj_v1 >>= 1;
7 ~: J* L$ }5 G8 {3 v% l* i
+ C& k. J4 M5 h/ r- inj_v2 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2);! [" u3 M( v0 s- F# W: e( W. } `
- inj_v2 += ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_3);* I8 ?8 q7 Q4 r6 G- D( q
- inj_v2 >>= 1;$ L1 J. _! r' k% i+ j
- $ Z6 K' N K. X5 m" e. w+ t
- inj_v3 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_3);+ f& Q: y+ Y) E- Y2 K$ z
- inj_v3 += ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_2);
) k8 D: K' N0 [" j% t - inj_v3 >>= 1;% d# m" s" K* F% B! S+ Z$ L
- 2 L1 @6 e% J. U! c% N6 r. S, {% F
- inj_v4 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_4);
0 P/ H( a, P% h* p - inj_v4 += ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_1);
! y) K- [% T& `( ^ - inj_v4 >>= 1;
, |, d7 j/ V- O7 n3 r T( | - }
6 C0 [% L) W# D2 Y7 n - }+ W; Q* y& i4 H7 C' X3 D. w
- 7 u. C, l3 o+ r P+ x" b9 J q
- /* 规则转换中断 */
% e; L7 C# F; d& O - void DMA1_Channel1_IRQHandler(void)6 N( y2 T% D" z. X) M2 ]; {
- {
( ]0 Z2 f9 ^% k4 q( b9 _ - if(DMA_GetFlagStatus(DMA1_FLAG_TC1) == SET){6 S3 b `( J) I t
- DMA_ClearFlag(DMA1_FLAG_TC1);% @* _4 T! S6 @' ?3 H$ \1 f
- DMA_ClearITPendingBit(DMA1_IT_GL1);
6 k, v: v9 d) ]( |. ?' B4 X3 A - ADC_SoftwareStartConvCmd(ADC1,DISABLE);2 J9 X4 \2 v7 l9 v- o
- DMA_Cmd(DMA1_Channel1,DISABLE);
* }: w/ p, j8 K& n) j/ Z' _
! _1 w. W7 f. R! U4 ^( F8 I- regular_convert_calc();( z& F, J( K4 Z# m4 t v
; d9 d6 ?8 o1 x$ x- DMA1_Channel1->CNDTR = NUM_OF_REG_CHANNEL;! P/ J( T- l3 [- }
- DMA_Cmd(DMA1_Channel1,ENABLE);$ I- }7 f* w( L, Y" H0 F: k, L; f
- ADC_SoftwareStartConvCmd(ADC1,ENABLE); W/ \8 F5 ]: O# j, @! A8 k
- }5 W* p. y$ @4 n, v. _3 Z- t
- }</font>
复制代码 1 u- k; x8 S0 _ e! j9 l5 z. m7 m
来源:lanmanck |
感谢分享!!!