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

【原创】STM32F407的多通道ADC_DMA配置,四通道

[复制链接]
wjandsq 发布时间:2015-6-16 18:20
/**
: H* m3 ^. p6 B9 M) x! [  * @brief  ADC_Config' E: i( ^. f5 \3 a8 I" d
  * @note   This function Configure the ADC peripheral  
5 \% p0 J7 {. I. O$ Z  *         1) Enable peripheral clocks
/ N9 k2 j) W) X  *         2) Configure ADC Channel 12、8、13、9 pin as analog input$ T, ^' P) z5 ?8 j
  *         3) DMA2_Stream0 channel0 configuration/ g/ F3 v8 v4 G5 B- A9 F( @2 t  b
  *         4) Configure ADC1 Channel 12、8、13、9(PC2 PC3 PB0 PB1)
: @( o; P  e$ j/ W7 ?  * @param  None
6 r' b+ b7 M  q9 r4 U( s6 y  * @retval None; O; r: W- B9 X( I- J/ ^" U
  */4 k, s8 n% j6 X& w
void ADC_Config()+ [" `' s% O# a+ k
{
" s" h. |" ~  k& n  GPIO_InitTypeDef GPIO_InitStruct;0 {8 e) ^5 g/ r' \1 |( G
  ADC_InitTypeDef ADC_InitStruct;8 F% j0 T: ]% e4 q
  ADC_CommonInitTypeDef ADC_CommonInitStruct;
/ Y5 U9 `% C- ~( |  DMA_InitTypeDef DMA_InitStruct;* ?' j# A9 T- r& o. j3 t

: H! L# u+ f, t3 A9 @) H  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE);
" {) Y0 i& }2 N( _: S
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
0 A5 S+ N* y8 z9 E0 Q' ^, Y  ADC_DeInit();
) e6 C# X: ]: \+ t
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
( A9 `& B, L. l+ `  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);5 M7 }: B- j8 S" e
  2 v/ F) D, E2 d8 q9 H
  DMA_InitStruct.DMA_Channel = DMA_Channel_0;
+ c, d: m8 T* V" h! Z  DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&ADC1->DR);
6 {, ~9 y" c" o9 F0 E  DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)(&ADC_Value[0][0]);, a( r) g4 ~1 k3 A! Z
  DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;0 g& E3 a3 j0 y7 e# r
  DMA_InitStruct.DMA_BufferSize = 40;7 Y  {* G: M; [7 h0 ?. b8 ]0 ]
  DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
: n: X2 Y: A" s2 o4 P8 }  DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
; r, W) z, G5 T  l# T* m9 T3 a' h0 w  DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
; O; l2 @) x  F/ Y5 [  DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
9 g& W) N& K7 j1 K  j  DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;3 g/ U9 P* _5 H' s7 D/ q5 _
  DMA_InitStruct.DMA_Priority = DMA_Priority_Low;7 ?  }# O! l$ ^& A6 ^8 W* V
  DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;  p' x" X, [# `& |5 }. m7 p% q  a
  DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;: m1 f, X' W/ j3 e: t* ~' R5 ?. h
  DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;$ [( }1 P4 h5 v; P# ^' Y
  DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
. H- h* |" D6 v7 S- o( K+ A  DMA_Init(DMA2_Stream0, &DMA_InitStruct);1 X, h$ |: f! J( S% k
  DMA_Cmd(DMA2_Stream0, ENABLE);% D" }2 h* v1 ~  D& C

* d1 C$ x1 e% Q3 K) G- W  DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
& Z) a% |, D6 s3 H  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;8 W9 n& T! ^; S: J. S
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
1 L; H8 [6 M  Y$ M& i+ @3 z  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;7 k! n' c2 T+ r
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
% X; F; L; {0 a0 s1 h% J/ q6 M  NVIC_Init(&NVIC_InitStructure);0 L+ S4 x# T( k- L% R

- D* B4 e* R% K+ C2 i  /*
# A8 }" G' J6 e+ \8 b& f- p# b
    PC2: ADC_Channel_12 --> AIW0 (0~5V)8 `* S1 N( }$ T; f: T4 U$ i! ?
    PB0: ADC_Channel_8  --> AIW2 (0~5V)
8 z; A7 x. h- d0 z. T/ g    PC3: ADC_Channel_13 --> AIW4 (0~5V)
. Z, B9 g2 n/ x" N    PB1: ADC_Channel_9  --> AIW6 (0~5V)
# N8 J1 h* {2 `- a9 Z$ ~! @   */& c( W$ ~( ~; q+ _
  GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_0 | GPIO_Pin_1;
1 @1 `; V% i3 |% v  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;; x6 {  |9 e1 k2 w/ j+ A
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
3 P+ j  y# y( J) K/ b; {7 j% r  GPIO_Init(GPIOB, &GPIO_InitStruct);. F# A9 E( T2 B: m
  4 i$ C  Y$ m$ P
  GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_2 | GPIO_Pin_3;' F8 D& {. W8 `/ x' B
  GPIO_Init(GPIOC, &GPIO_InitStruct);& V8 l' |% {3 K5 g3 m

2 G- ?/ Z! {$ N( ]. i  /* ADC Common Init **********************************************************/& M" ?$ _2 d9 w- m9 q
  /* 设置ADC工作在独立模式 */( z, ~6 ]6 c, E9 u
  ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent;
, q! u$ O# c' W  \7 ?. z  ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div6;6 U) |7 E6 m; j& Y
  ADC_CommonInitStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;# @1 H) J& a/ _; }
  ADC_CommonInitStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;5 n+ ]) |8 I: @; [
  ADC_CommonInit(&ADC_CommonInitStruct);! S6 V) N2 |4 Q; ~
' n* C$ M- N, n0 _! B$ t8 v5 j4 P: ]- B
  /* ADC1 Init ****************************************************************/
0 c: y) y8 y/ t# r! b5 }  ADC_StructInit(&ADC_InitStruct);
% L" Z1 S: R. R3 H& q  /* 规定AD转换工作在扫描模式,即对多个通道采样 */, v6 L' N& k# f8 h* n
  ADC_InitStruct.ADC_ScanConvMode = ENABLE;* |# z4 X" I$ Z$ d% s, ^$ y
  /* 设定AD转换在连续模式(ENABLE) 单次转换模式(DISABLE) */, C" g. m! [+ ~1 O  Y0 Q$ E& ^1 @
  ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
7 B' m4 n1 B2 A0 j! \% x# A6 Q# J  /* 不使用外部触发转换 */. N8 Y; ~1 J* A+ X6 h
  ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
2 I% l+ N9 [" H0 G  /* 不使用外部触发转换时,该设置无效 *// R/ t$ C4 g( |7 D; i% o' {
  ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
0 z1 j  K- p5 l% F* r  /* 采集的数据在寄存器中以右对齐的方式存放 */
  p: \9 j" s9 T+ \  ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;. M+ V: h: e/ r8 i5 i' @) d
  /* 设定要转换的AD通道数目,这里是PC2 PC3 PB0 PB1 */: D1 r. R9 ]* r) |+ k9 @
  ADC_InitStruct.ADC_NbrOfConversion = 4;
# c3 R0 u  _4 t7 @4 v4 s2 }& Q
% v6 N) F- B( y! t  ADC_Init(ADC1,&ADC_InitStruct);
( U- x0 p# k) ~  & L, Q0 g0 W' W
  /* PC2选择Rank 1,AD转换数据传输到ADC_Value[0] --> AIW0 */
6 X( a/ ~6 f$ o6 c5 z4 G  ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_15Cycles);
( _! W0 H) Q: @7 p6 D  /* PB0选择Rank 2,AD转换数据传输到ADC_Value[1] --> AIW2 */4 Z% v0 `/ {; S9 P; h2 C
  ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 2, ADC_SampleTime_15Cycles);( q3 ^8 S) N" N# O& G2 h
  /* PC3选择Rank 3,AD转换数据传输到ADC_Value[2] --> AIW4 */( _, e) ^7 Z: y% }% e2 k/ o: r
  ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 3, ADC_SampleTime_15Cycles);. }) `' F+ t- R5 E
  /* PB1选择Rank 4,AD转换数据传输到ADC_Value[3] --> AIW6 */
8 i0 D7 _* ~& s& m  ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 4, ADC_SampleTime_15Cycles);+ g2 H. }. |: n: ~  S! x7 ~6 k& F9 v
! w# f$ \  @! T3 l
  /* Enable DMA request after last transfer (Single-ADC mode) */
# l- W. U$ a% p5 c$ E# `) K. P0 t  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);6 r6 B, i! f& o6 F0 n- W" P& E/ B
  ADC_DMACmd(ADC1, ENABLE);
" D  S8 B$ g2 S: ?) r% v  ADC_Cmd(ADC1, ENABLE);5 e: T: Z6 u" W5 v4 k$ o
  ADC_SoftwareStartConv(ADC1);) ~8 p, t1 d( B, Z$ }
5 p6 a! J$ U5 `! C  Q, D
}

: |/ @, \6 E/ O: }2 W6 ^' w( Y
# Z0 Z4 g9 N; s
& @% e$ d! K1 V3 }" E
赞 收藏 1 评论6 发布时间:2015-6-16 18:20

举报

6个回答
你好我好大家好! 回答时间:2015-6-17 10:54:17
帮顶                              
semon12345 回答时间:2015-6-17 14:50:06
看着有点头晕。
wjandsq 回答时间:2015-6-17 16:05:00
本帖最后由 wjandsq 于 2015-6-18 18:44 编辑 # V5 J" x4 V1 }- J+ C: E7 f! v) n

  F. p7 \/ W( }- B4 ~0 \可以声明一个数组ADC_Value[10][4];
4 O* F- i4 w( Z( _9 pDMA_InitStruct.DMA_BufferSize = 4; 改为
3 u: i6 W. ~" vDMA_InitStruct.DMA_BufferSize = 40;
. \% j- R# |2 R+ z这样  PC2   PB0   PC3   PB1 采集到的数据依次放在
2 z; `7 O2 I- L$ \ADC_Value[0][0]、ADC_Value[0][1]、ADC_Value[0][2]、ADC_Value[0][3]3 `' U3 [' m7 b
ADC_Value[1][0]、ADC_Value[1][1]、ADC_Value[1][2]、ADC_Value[1][3]
8 x" a4 Q# ?9 v9 u....
) O8 j' U# b4 |3 h# kADC_Value[8][0]、ADC_Value[8][1]、ADC_Value[8][2]、ADC_Value[8][3]ADC_Value[9][0]、ADC_Value[9][1]、ADC_Value[9][2]、ADC_Value[9][3]
# `8 t' j9 g2 B
1.jpg
2.jpg
Paderboy 回答时间:2015-6-17 21:46:15
多谢分享。。
wjandsq 回答时间:2015-6-18 18:51:58
为避免多通道数据采集出现错位,没有使用循环模式,转换完毕自动停止,进行均值滤波后,
) u8 v" S0 |9 Y3 u3 Q- f) p可以重新设置DMA传输的地址和传输数目,重新启动ADC转换,这样能控制ADC转换的频率。; c& s  @# J2 V* [# K  K0 A; [

6 D: j6 I/ W7 d' P0 c    if(Flag_ADC_Finished){
% \* F' @1 A5 Q  n! c0 o9 |; H$ j  b      Flag_ADC_Finished = 0;# r" U  @% k- y$ |
      DMA2_Stream0->M0AR = (uint32_t)(&ADC_Value[0][0]);
; L; }6 Z: n1 T" Y7 w/ \& y      DMA2_Stream0->NDTR = 40;
' {( }8 E8 N% U* z- m9 j8 K' Y      DMA_Cmd(DMA2_Stream0, ENABLE);
5 g3 B( n% Z4 V& a      ADC_Cmd(ADC1, ENABLE);; ?+ e1 f1 k* z8 p7 \4 D
      ADC_SoftwareStartConv(ADC1);
2 j$ \1 J+ o& K2 }6 z    }
ZXiang 回答时间:2018-3-13 21:02:11
能发下原码吗

所属标签

相似技术帖

官网相关资源

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