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

stm32f405/407的两重 ADC同步触发模式+DMA 配置

[复制链接]
sailor.wu 发布时间:2015-11-2 22:08
双重 ADC 模式:
3 S5 ~2 A/ {+ Q在 ADC1 或 ADC2 转换事件结束时:
  D& D# ^! h6 W* d. O● 会生成一个 32 位 DMA 传输请求(如果 ADC_CCR 寄存器中的 DMA[1:0] 位等于: }' S8 x1 F5 R( O: x
0b10)。此请求会将存储在 ADC_CDR 32 位寄存器高位半字中的 ADC2 转换数据传输
( ~8 {5 X7 I4 o: x. |/ Z- |* d到 SRAM,然后将存储在 ADC_CCR 低位半字中的 ADC1 转换数据传输到 SRAM。
. h. k+ N7 |  N/ Z● 当 ADC1/ADC2 的规则通道全部完成转换后,会生成一个 EOC 中断(如果已在两个 ADC. A% Y; z* y, I& S$ q( D1 P
接口中的一个接口上使能)。
- f% r- s7 }9 G; W) o- d" ~  s' B( \! n, p. N+ c3 q
转换示意图:+ H/ {* }, U. ?0 O4 P0 b) l9 U
. L" H6 c" Z8 S6 X7 L

转换示意图

转换示意图

4 C2 n# z* P7 h; T2 n0 D
- z" I8 z5 T: I, b配置代码:+ x  F+ ~6 j% i% Q9 L! G+ A! o$ U/ E
) K) s* c* [0 U* k  N2 S6 z
#define ADC_CDR_ADDRESS    ((uint32_t)0x40012308) //适用于双重和三重模式的 ADC 通用规则数据寄存器( ADC_CDR)
; c0 _% r$ {1 }5 o" k9 ?
) M; Q& [5 \3 W9 [# b2 G: Q% n8 L1 N& Q3 @- z! N6 h" b# r; o5 n9 `
void Init_ADC12(void)5 _7 |0 m' N9 F# f+ y
{6 E% U5 |! D& ^9 }1 S( ^; ?
  GPIO_InitTypeDef  GPIO_InitStructure;0 l! I* |0 y) o! G
  ADC_CommonInitTypeDef ADC_CommonInitStructure;) w; Y0 i. s1 U0 {. S0 C' ?
  ADC_InitTypeDef       ADC_InitStructure;
  C9 ?" U* }  Q4 T5 U    3 G# d: E9 G6 }& W) ~
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟  l, {3 X: g; `9 }2 t
  
) n$ E) N! ]+ N# e6 z( P! X' n% d  //先初始化ADC1通道 IO口
5 c4 E8 z  t/ N* F- k' q  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;;' c# d& M6 J4 h# L2 I
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
! ?/ |) j8 u# t  H- H  Y& ~! t  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉& O6 o$ G' @( X
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化  2 l8 K' \3 L& R% H2 m
  ' z# T8 L/ c; K0 f8 N
7 H, w3 v4 D& [2 l  j8 _, M
  /*****************************************************************
2 g$ B, A# J& i) o  *************************** DMA Configuration  ******************7 D# _6 U: }' g/ q2 {8 D; p# x8 Y
  *******************************************************************/5 S# |# l9 c6 E% Y( s1 }
  0 K: E, k% l( I2 G- x8 ?/ }6 b' M( X
  . R8 s# |) O, ?" b
  + R8 m5 g; P1 H. f& V) c$ ^
    DMA_InitTypeDef DMA_InitStructure;) Y. y9 A/ K8 \# g/ f
    /*首先开DMA2时钟,由407参考手册-RM0090-Reference manual
& o6 r  R# U& M& g     *165页可知,ADC与DMA2映射,而且DMA2挂载在AHB1时钟总线上*/
4 y8 K3 H2 \* G7 S: N9 c: z% S$ q0 {    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);6 b" k9 R  r# E4 t" u3 A; D9 |
    $ v4 y4 P( d) g  g2 I8 U
    DMA_DeInit(DMA2_Stream0);
7 |- W) y3 O/ G. b    DMA_StructInit( &DMA_InitStructure);, _2 n7 @  a4 x, \4 s) l
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;                     //选择Channel_04 t1 J- U# T: Y2 L. \
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS; //数据传输的外设首地址,详解见上2 o7 \- b7 @: i4 x/ E9 a
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&adc_result;   //自己定义待发送数组的首地址,要强制转换为32位' s' _+ @3 i, X9 P6 b
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;       //数据传输方向选择为内存->外设
( U! F  W9 [/ d$ {    DMA_InitStructure.DMA_BufferSize = 2;                      //传输数据大小为16,单位由以下确定,大小要配合定义的数组类型和外设数据类型1 q& @$ k) v. U6 X" `5 U5 r
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器自动增加禁止,因为这里只用到了DR数据寄存器9 n6 U( M; J" l9 g7 C, \
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;         //内存地址自增不允许,因为只存取一个数
- K) W3 i# W: i5 S    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设的数据大小
5 P+ z7 q7 O" c: k    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;     //这里也选Byte
+ q8 q3 U# R* v, K4 t( m2 M    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;       //DMA传输模式为Normal,如果为Circular,将会循环传输
1 J" V2 T- {* G* n3 ~9 a/ |! g    DMA_InitStructure.DMA_Priority = DMA_Priority_High;   //优先级为VeryHigh
1 I' B. l9 Y. X    DMA_InitStructure.DMA_FIFOMode=DMA_FIFOMode_Disable;
  Q6 I/ M6 N! J    DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_HalfFull;
0 L+ C. N, R( v5 ], S& N( S2 q; d; w    DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single;6 U1 m# m6 ]& V: r' Z. }! ^& P
    DMA_InitStructure.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;
- U+ p. v9 P: |; n2 o5 J: x- X4 l    DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  L+ y. `6 D& I- k3 ~6 M   
% k! w$ X! m- W0 ?0 Z2 ?4 u5 ^! K
. I$ }4 e* M8 l6 `1 c//    NVIC_InitTypeDef NVIC_InitStructure;) y! F/ K2 s% u7 S% E% _
//    /* DMA中断配置 */' X2 M9 Z+ |  R
//    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;      //嵌套通道为DMA2_Stream0_IRQn
- m  `5 C, q9 W/ r, y//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级为 1
% ^! g, b) o) X, `# z% z//    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          //响应优先级为 0" l5 \* m( z3 Y8 [
//    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;              //通道中断使能
* ?) e, }: z5 Y, B//    NVIC_Init(&NVIC_InitStructure);" z6 j% |  {1 Q/ ~( i$ _5 G. y+ W9 t
   
2 d; e% x2 B/ X8 a" i* `5 y) N   
8 `- Z  E) S( C% F( x    * P( p- [# f% }
    //使能DMA2_Stream0通道
6 h( w" U! m' J7 u9 T    DMA_Cmd(DMA2_Stream0, ENABLE);
. g. h1 Z) \8 S4 N. \   
3 ]/ |% j8 B. v/ _3 ?( g
- B- v. m% G( ^# P+ S//    /* DMA中断开 */; R7 y; N# b' b' G
//    DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);+ r. J( H' G* d* ?2 D( [- t9 s5 v
   
, D5 N* t! z! M% k; a  /*****************************************************************
: M$ s9 w+ H- z; ]8 Z  *************************** ADC Configuration  ******************2 X: X  ~+ r, s9 h# }
  *******************************************************************/
6 V# ?( F; x# x+ q+ `
( N' \3 T/ P4 K  R$ Y  
  u+ g3 ]6 ]$ e5 ?  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟8 A; _7 [0 a1 _1 {
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //使能ADC2时钟6 V  q0 e5 e. L' Z/ E
7 e9 X& L! ~% j+ e( ~8 a
  ADC_DeInit();7 _6 h5 k, m6 ]* d) q
  //初始化ADC Common
* @" O4 f' W( s9 V# G* o3 _  ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;  M8 R8 ~8 F3 L( s' @# ^+ A
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟; P( l0 K6 b  g& c% x3 O$ Y- D
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; //DMA使能
+ x: U$ {. _3 f' h9 F( |4 {; P6 C% r  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz * ]: w5 }4 `- d6 z8 j3 a
  ADC_CommonInit(&ADC_CommonInitStructure);//初始化" F0 s2 A  a9 e7 [9 y$ g3 J5 W
    # r+ s' p1 b$ D
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
+ B- i4 x8 T+ G0 X" k- D4 v) a  ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式   
; u/ a) @0 K5 k9 f- a$ M2 `2 U  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
4 N; I- _$ ?4 b! q! F2 w  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发1 a; o: {" W  G# p; L' e, F
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐   
# B& L% r( S, E% V8 {  ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1 & }; W8 m' x  ~2 d+ W1 H
  - S' q* q$ y9 A9 n  b
  ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
8 v/ k* U: G# J( Y: T8 [   
$ T! `) Z; s1 s( R- z. q" g. A  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式4 Q( k* l1 |$ K9 B" N
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式   
9 t9 G, y2 {: M7 D; p  U6 y+ v5 `  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
5 @  Q7 b+ ]& F# ?8 |  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发
' k) H3 j- U1 ]% X/ O  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐    ( X7 k# M: t, B& o3 H! i) g2 t, Q( g
  ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1
0 _' N8 P# ~$ ~; z  . A. `5 ~2 B( x8 G
  ADC_Init(ADC2, &ADC_InitStructure);//ADC初始化
8 s5 e4 c  C0 M3 m  . E* R9 [6 k! z, K. A
  
/ M% |& a! h7 @* G1 X  ADC_RegularChannelConfig(ADC1, ADC_Channel_0 , 1, ADC_SampleTime_15Cycles);    9 d2 D7 p0 `* w* H! ~
  ADC_RegularChannelConfig(ADC2, ADC_Channel_1 , 1, ADC_SampleTime_15Cycles); - `5 g* N  L6 Z- d1 v
  ' @/ y# ^, W) S  Y8 ~2 t+ `7 N
  /* Enable ADC1 DMA */
7 K$ }; N- I( K; V  ADC_DMACmd(ADC1, ENABLE);
/ j3 f0 P, L' m: ?: S7 c  
4 O1 \) w! z4 P# P& L" T8 B      I- ^! W- J8 t1 A5 h9 [$ I7 b
    /* Enable DMA request after last transfer (Multi-ADC mode)  */
# H- k" n/ I. \7 l* r2 v  T  ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
9 n9 {5 R$ w6 v5 {/ d7 C- p  
3 v7 s# W5 q$ m% i, S. Z, k  
7 o& Q, V. J+ _! p. D  ADC_Cmd(ADC1, ENABLE);//开启AD1转换器    6 I/ J: E+ C, N, w4 M' s  K
  ADC_Cmd(ADC2, ENABLE);//开启AD2转换器   
7 s* Q( A; ~9 w& M$ v/ m
. \7 H* }' e% L( E7 Y

转换示意图

转换示意图
收藏 4 评论12 发布时间:2015-11-2 22:08

举报

12个回答
disheng4688 回答时间:2015-11-3 08:36:56
谢谢分享         
dear祝子 回答时间:2015-11-3 08:50:24
给你32个赞!!!
me浩 回答时间:2015-11-3 09:03:20
谢谢分享啊
我是你的e 回答时间:2015-11-3 09:05:58
感觉你的头像很酷,内容也不错!所以给你一个赞
钊钊 回答时间:2015-11-3 09:28:38
看了下,楼主的思路还行,但是我不明白这么做的目的,或者说要实现的是什么,恕我看不懂呢,能稍微解释下吗?
sailor.wu 回答时间:2015-11-18 18:31:49
电机FOC控制,需要采两相电流,ADC采样时间短的话,调制度就可以放大。
wz002 回答时间:2015-11-20 15:55:16
:)
ataudio 回答时间:2015-11-20 17:01:41
与ADC 相关的都要关注。
‪931581159 回答时间:2017-4-7 13:43:17
本帖最后由 ‪931581159 于 2017-4-7 13:44 编辑 " |: e( G. U* N! ?& h! r; r# ?
( t0 B! [* Z/ p9 m) c/ H. b( S" P& K
内存地址自增不允许,因为只存取一个数4 w- [: y( ]& l0 f2 O' e6 S$ j
这句注释错了吧,明明你设置的是DMA_MemoryInc_Enable; ]3 B- w- e2 t  L8 B# Z3 s
虽然我也不知道到底是注释错了还是代码错了
9 L; L* P% M' W1 d" `- R……
' m. g+ |. V6 t1 r5 k多看了几段,为什么注释和代码都是自相矛盾?
# B; E* a" e0 S3 X
alisa123 回答时间:2018-12-16 23:51:18
楼主, 我看  你分享的代码中,把关于DAM的中断的部分注释掉了, 请问这一块开DMA中断的代码是OK的吗?你有测试过在DAM中断中收数据吗?
panze 回答时间:2018-12-25 16:33:07
谢谢分享啊
lxl8511 回答时间:2019-1-10 16:30:29
谢谢分享谢谢分享谢谢分享谢谢分享谢谢分享谢谢分享

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版