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

分享一个ADC的DMA

[复制链接]
hhhhhhhaa 发布时间:2018-12-13 14:34
只做了一路,多路的话自己扩展
* _# p/ {/ i$ r2 ~# h4 l3 H. o
  1. #include "adc.h"
    / G0 }3 ?' a3 H9 q4 w% s% l: r  e
  2. #include "delay.h"  Y6 U2 j) N! ]7 i+ }
  3. //////////////////////////////////////////////////////////////////////////////////         
    ) x/ N2 q) T$ N$ O  r. F5 G
  4. //本程序只供学习使用,未经作者许可,不得用于其它任何用途: e* q1 i% K2 i' K6 h6 P
  5. //ALIENTEK miniSTM32开发板# u- @9 i7 Z7 s. H, Y
  6. //ADC 代码          
    4 u4 M$ f2 ?8 Q
  7. //正点原子@ALIENTEK& w3 O, O4 N! j6 a: c7 B7 A0 C
  8. //技术论坛:www.openedv.com
    2 a" A7 F% b9 u8 ^( R3 y7 q
  9. //修改日期:2012/9/7
    3 o0 Z1 U+ P' W5 U# t! X- k
  10. //版本:V1.0, _0 B% l  N1 y* ?- ?# D
  11. //版权所有,盗版必究。" V5 g* S# i& k% z% C( v
  12. //Copyright(C) 广州市星翼电子科技有限公司 2009-2019
    4 ~$ O+ }0 `% r
  13. //All rights reserved                                                                          
    9 g+ h, F. a' ?2 K( M9 G
  14. ////////////////////////////////////////////////////////////////////////////////// + }$ [) k2 G2 @4 C
  15.            5 D; U. F5 `" }) I) S; r" h
  16. __IO uint16_t ADC_ConvertedValue;  
    ) \; D1 m9 z  a3 }4 X) ~
  17. //初始化ADC
    7 K3 n& z3 _" h- o
  18. //这里我们仅以规则通道为例
    # e0 s! L  m0 F; I5 y, ?
  19. //我们默认将开启通道0~3                                                                                                                                           / Z# g- _5 p4 m; [" X" Y2 x
  20. void  Adc_Init(void)) l( {: Q& F2 ^- F( Q
  21. {        
    % X. V% u4 Q4 o4 G& {: j+ ~* {, a
  22.         ADC_InitTypeDef ADC_InitStructure; ) ~+ C6 t: ?: T0 m: M
  23.         GPIO_InitTypeDef GPIO_InitStructure;
    / w" k* |3 x9 _' D) l/ F: v& p
  24. /*--------------------------DMA部分---------------------------*/
    ; i& Z( J  K. {3 ~- w" P9 i9 F
  25.         DMA_InitTypeDef DMA_InitStructure;        + R, |6 Y. ^$ \* y7 D
  26.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// 打开DMA时钟# K, w( Q# X7 |- K( E. W0 Q
  27.         DMA_DeInit(DMA1_Channel1);// 复位DMA控制器, X2 _+ q2 w+ g
  28.         DMA_InitStructure.DMA_PeripheralBaseAddr = ( uint32_t ) ( & ( ADC1->DR ) );        // 配置 DMA 初始化结构体        // 外设基址为:ADC 数据寄存器地址
    , D" E) I8 ^' N$ V, |8 \
  29.         DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;// 存储器地址,实际上就是一个内部SRAM的变量7 p8 a2 Z) q  u( ?* l5 U: m9 k
  30.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;// 数据源来自外设% o  R' \1 v( {- x1 y2 ^
  31.         DMA_InitStructure.DMA_BufferSize = 1;// 缓冲区大小为1,缓冲区的大小应该等于存储器的大小
    0 L3 ^( x. A! K
  32.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 外设寄存器只有一个,地址不用递增
    & N7 {; r0 d: D! u7 R( A
  33.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; // 存储器地址固定$ `  F& @  P. M$ F7 b
  34.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// 外设数据大小为半字,即两个字节
    ; R( z" y( J% ?  N6 M( h
  35.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;// 存储器数据大小也为半字,跟外设数据大小相同& R, e! `3 n* \
  36.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;        // 循环传输模式/ I6 L0 b0 }: Y* f! i+ @  f/ |
  37.         DMA_InitStructure.DMA_Priority = DMA_Priority_High;// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
    & S; U1 g: u; ~
  38.         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// 禁止存储器到存储器模式,因为是从外设到存储器2 _, F! C4 C9 d" S' `! O
  39.         DMA_Init(DMA1_Channel1, &DMA_InitStructure);// 初始化DMA+ a* i5 x  N5 Q
  40.         DMA_Cmd(DMA1_Channel1 , ENABLE);// 使能 DMA 通道3 O5 \( U( M. G. z
  41.         /*--------------------------DMA结束---------------------------*/; }2 Y4 D3 @3 E
  42.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1        , ENABLE );          //使能ADC1通道时钟
    5 O; U! l2 @1 L" U9 G
  43.         RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M; }  P+ d2 X7 ^& D

  44. % K( I/ t1 X( r$ b* o1 Y( z
  45.        
    # u) k; h5 N2 a5 r1 M" u# }
  46.         //PA1 作为模拟通道输入引脚                         ) u% n& A0 u+ M, p" R
  47.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    9 K1 o9 O7 x& @5 `5 j
  48.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //模拟输入引脚
    5 Y! @) y, [9 y) U8 r( }6 j
  49.         GPIO_Init(GPIOA, &GPIO_InitStructure);       
    / p: e/ |1 q5 g3 \& h

  50. * [1 E- d( h" B
  51.         ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值4 }3 N( H0 l4 B+ Z$ O  v
  52. $ F: Z9 [2 D  H& K+ B7 o2 q: b
  53.         ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;        //ADC工作模式:ADC1和ADC2工作在独立模式4 I* `8 z* Q  a' J6 a) I7 t
  54.         ADC_InitStructure.ADC_ScanConvMode =DISABLE ;        //模数转换工作在单通道模式- L3 H( {$ O# e, {% s* }
  55.         ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;        //模数转换工作在单次转换模式7 u/ D* g/ k  c1 v1 s
  56.         ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;        //转换由软件而不是外部触发启动" D; i# q8 s% _' e& D
  57.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;        //ADC数据右对齐
    : c( o. M: \+ \. r% a
  58.         ADC_InitStructure.ADC_NbrOfChannel = 1;        //顺序进行规则转换的ADC通道的数目
    % [% r2 D, N* K+ m9 ^
  59.         ADC_Init(ADC1, &ADC_InitStructure);        //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   - z' q8 Y4 z! u# d9 c4 C
  60.   ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );
    & ]8 h+ ~7 i1 i6 K, q' \
  61.         ADC_DMACmd(ADC1, ENABLE);        // 使能ADC DMA 请求
    7 M* `5 v! t" K  N- B4 _* i7 c
  62.        
    8 I5 o4 ^5 \3 m# d# F
  63.         ADC_Cmd(ADC1, ENABLE);        //使能指定的ADC1& N0 P  V' N2 K" }+ Z
  64.         ADC_ResetCalibration(ADC1);        //使能复位校准  : P  n( N  S$ s, [$ l; l' V8 r7 e3 n
  65.         while(ADC_GetResetCalibrationStatus(ADC1));        //等待复位校准结束; Q" a$ v: _3 ^
  66.         ADC_StartCalibration(ADC1);         //开启AD校准* x' @  i. N2 M9 o
  67.         while(ADC_GetCalibrationStatus(ADC1));         //等待校准结束
      [, }+ C9 \* V+ S+ ?5 w! @. r, O
  68.         ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //使能指定的ADC1的软件转换启动功能! o% G+ G& e0 _+ Z
  69. }                                  / ~1 I3 u0 ^) G7 c
  70. //获得ADC值
    , E. y1 s& w  [% A4 T, J, k+ d
  71. //ch:通道值 0~3
    ( H; H7 k1 W6 x3 T0 r# ~% E; C
  72. u16 Get_Adc(u8 ch)   
      [- }( q) g+ c( ^6 L0 H- U
  73. {
    " N6 s0 E& B( h! [9 G4 @! t3 K+ ?
  74.           //设置指定ADC的规则组通道,一个序列,采样时间7 `4 C7 R+ u* O% G
  75. //        ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );        //ADC1,ADC通道,采样时间为239.5周期                                      
    $ A' s7 N/ R, r& x$ {. c
  76. //  
    4 Y) m. [0 f, l# i
  77. //        ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //使能指定的ADC1的软件转换启动功能       
    . S  X* b$ e( c1 A9 J9 I0 }
  78. //         
      ^. [8 h: R( Z! g1 G+ M3 `' A
  79. //        while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
    ) b" `& m$ `/ j" E

  80. / q. x9 ^2 U( D7 ~+ A; Z
  81.         return ADC_GetConversionValue(ADC1);        //返回最近一次ADC1规则组的转换结果, m  M/ T# g0 a% ~
  82. }: w4 k- y4 [7 `

  83. - _& {( [( S4 r1 [6 o0 y3 t5 U5 K
  84. u16 Get_Adc_Average(u8 ch,u8 times)
    . }* ^& l9 E) p  p
  85. {
    0 |$ b; {1 A" r+ k: N. v8 G
  86.         u32 temp_val=0;
    6 T3 p, r# v& e
  87.         u8 t;& _5 ~8 I3 _8 [7 z4 e
  88.         for(t=0;t<times;t++)
    % ^) R! a$ P9 d. c) U$ g
  89.         {
    % Z+ G4 q0 j9 `5 v& `
  90. //                temp_val+=Get_Adc(ch);) O7 ?4 z+ N4 g, t: h
  91.                 temp_val+=ADC_ConvertedValue;
    # \. f) s4 c) w6 Z
  92.                 delay_ms(5);6 k% Y) f6 Y, D0 S$ C6 {/ }0 ^+ b
  93.         }
    ; X0 d0 _4 j! _1 [) Q9 H0 e9 g2 S
  94.         return temp_val/times;# Y9 @4 y) a* \8 \% v
  95. }          
    4 l7 t1 `+ u; `) g, x2 j: B

  96. : k# m+ f: H- A* E" y, s5 w

  97. 1 C. }; n3 N, N/ ^: G6 n4 w
  98. - P( }' ?2 N, e* |" `! U5 E

  99. : P0 z0 U1 p* O0 x, n0 C
  100. 2 e) @+ j. h) L/ s% K; u

  101. 2 @, v$ B9 @0 u3 e, ?9 v
  102. & W, K6 h5 h+ k6 Y' Z

  103. 3 F; j# G+ r! f+ [9 ?' M

  104. , e3 l2 v$ x! \% g: h" u. X

  105. ; @3 ?0 o* z- n5 j1 ?% ~) @

  106. $ {+ T$ E; l3 o' N$ i

  107. + y' P: e! ]$ F
  108. + x. w5 S8 O$ ]3 W
  109. . X" b2 @1 H0 h& P
  110. % ^( C4 W% Z6 m, [. \% C
  111. * Q/ c" X5 _5 i$ ^
  112. 2 z5 V) o7 ]8 X7 W$ _

  113. 1 B$ y* A) ?# {8 _- E. ?
  114. ; |* k; p  y" E. I

  115. ) j5 B/ r' v# |; i: k

  116. " p- j7 C  R3 c8 e0 M, I! ~
  117. * l) i% k: @6 W0 b( e  E5 [$ R

  118. 7 l  F" o* X0 w1 z% l

  119. ! I. q/ w' e6 {0 B$ H" C4 ~* n

  120. . T: p& }; R$ @% Y+ U0 W

  121. ! k2 l- d" L! s- z% z* M0 c: V! T
  122. & w! f  Y  {: [
  123. & Y$ U/ ]! d+ w- S, A, x
  124. + G4 t4 t' f, Y

  125. * [2 M% s# s' S1 A9 d/ [

  126. - ]) v$ K) J& p* _0 N5 h
  127. ' o* ^1 y4 \: H5 s" `( u; v
  128. #ifndef __ADC_H
    3 a. m0 @% ^. t1 l  m
  129. #define __ADC_H        / d. q  q# p( K) Y4 a
  130. #include "sys.h"
    0 Z3 G6 r0 Z) d; T( l! J+ n
  131. //本程序只供学习使用,未经作者许可,不得用于其它任何用途
    ) {$ i/ ]$ X1 \% E( W' f$ ^( M
  132. //ALIENTEK战舰STM32开发板$ c! N8 i: s# c2 S. y2 q9 c
  133. //ADC 代码             T1 M% V5 L* [. v
  134. //正点原子@ALIENTEK
    3 d& K5 M( v( B9 C* q/ d, O
  135. //技术论坛:www.openedv.com( L3 ]/ ^6 y8 k7 l, h3 O
  136. //修改日期:2012/9/7+ ~4 e% U2 \4 c, l! j, \
  137. //版本:V1.0( ]! }( X5 F' P% q0 k
  138. //版权所有,盗版必究。
    9 Y) a# Z$ P2 {! ~/ _) ]
  139. //Copyright(C) 广州市星翼电子科技有限公司 2009-2019. D6 w7 q5 `  D3 X3 \
  140. //All rights reserved                                                                          
    # l3 q7 C4 u2 N; w& F1 Z
  141. ////////////////////////////////////////////////////////////////////////////////// , W! _0 C+ N6 y5 m7 s
  142. / g! i$ g/ S1 Q. k, |% C% d0 M
  143. void Adc_Init(void);
    ' o  F+ t) u$ l; V* v9 d
  144. u16  Get_Adc(u8 ch);
    0 [* w0 m: k0 M5 b# g
  145. u16 Get_Adc_Average(u8 ch,u8 times); 5 C/ N! V9 W0 s9 a' S

  146. , k5 H- k4 c1 G) ]$ s
  147. #endif 1 p9 l" H2 u& x; d: P+ _8 @
复制代码

4 E' u" G% n, d1 M( z5 E- }
) S4 Q7 u( m5 M  K
收藏 评论2 发布时间:2018-12-13 14:34

举报

2个回答
hhhhhhhaa 回答时间:2018-12-13 14:39:05
说明一下,我是参考了正点原子的ADC和野火的DMA ADC来配置的,野火的例子总是重命名,对于我们这种初学者来说太复杂了,所以我就改了改
zccdyfw 回答时间:2019-1-17 10:59:00

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版