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

分享一个ADC的DMA

[复制链接]
hhhhhhhaa 发布时间:2018-12-13 14:34
只做了一路,多路的话自己扩展: u' Z+ }# G" X8 P
  1. #include "adc.h"
    1 I$ U9 v& E- M
  2. #include "delay.h"% f' u: r0 L# \% h9 i
  3. //////////////////////////////////////////////////////////////////////////////////         
    / V4 f7 ~; e' W* o1 ~* ?
  4. //本程序只供学习使用,未经作者许可,不得用于其它任何用途2 y* k2 R8 n! }/ |8 o
  5. //ALIENTEK miniSTM32开发板
    : w4 s4 N2 q, [6 ^' e+ D, O6 B
  6. //ADC 代码          
    9 A$ S% d4 p3 G3 H0 Y0 r% w, |% c% h6 `
  7. //正点原子@ALIENTEK
    : N8 ?' R1 O0 m
  8. //技术论坛:www.openedv.com/ |0 G. {) e: b2 v
  9. //修改日期:2012/9/7
    " C2 G9 n7 {5 P7 Y7 N6 e- e1 v1 x
  10. //版本:V1.0
      {8 N$ O3 B0 C7 J# \$ v% U! H
  11. //版权所有,盗版必究。& s( t  ]2 J, B
  12. //Copyright(C) 广州市星翼电子科技有限公司 2009-2019, U: A1 J" x9 u- L- E4 ^5 t$ O' s
  13. //All rights reserved                                                                          7 p0 Q* c' ?4 Q% Q7 E# F
  14. ////////////////////////////////////////////////////////////////////////////////// ) {/ }' \3 }' `5 g- m
  15.           
    ; j4 J4 Z9 S7 U2 {+ O7 k
  16. __IO uint16_t ADC_ConvertedValue;  # ~6 B, m) {+ o7 }& O" c+ o
  17. //初始化ADC
    + I. ]. V* E- Q- o' m+ ?8 _
  18. //这里我们仅以规则通道为例# a. x$ {. e7 o2 u
  19. //我们默认将开启通道0~3                                                                                                                                          
    7 N) N/ C6 {) ]1 K! R7 ]
  20. void  Adc_Init(void)
    9 e+ t0 P8 n2 Q: [0 ]+ _! ?9 W4 j
  21. {        
    ; }' D  ?1 O: Y$ |
  22.         ADC_InitTypeDef ADC_InitStructure; 3 @( X; i2 X7 N: b7 U; W6 o
  23.         GPIO_InitTypeDef GPIO_InitStructure;
    . a. V) {8 q# E% @1 [+ g
  24. /*--------------------------DMA部分---------------------------*/
    % N5 s% d$ Q, D6 I
  25.         DMA_InitTypeDef DMA_InitStructure;       
    1 E9 Y+ }; b' Z# L0 N
  26.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// 打开DMA时钟
      D- _: e# n( |+ N
  27.         DMA_DeInit(DMA1_Channel1);// 复位DMA控制器$ z, s) W6 f4 E  f9 k7 l% e
  28.         DMA_InitStructure.DMA_PeripheralBaseAddr = ( uint32_t ) ( & ( ADC1->DR ) );        // 配置 DMA 初始化结构体        // 外设基址为:ADC 数据寄存器地址& Y$ v5 W6 l" _
  29.         DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;// 存储器地址,实际上就是一个内部SRAM的变量
    4 P( g) ~: @3 G# |
  30.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;// 数据源来自外设  Z" Q9 [( {/ S7 R2 B) l# Q3 G
  31.         DMA_InitStructure.DMA_BufferSize = 1;// 缓冲区大小为1,缓冲区的大小应该等于存储器的大小( G% j* m" v! s  P$ B2 S
  32.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 外设寄存器只有一个,地址不用递增
    * g* k5 y2 J  z
  33.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; // 存储器地址固定
    , v) x0 G7 ?$ y  L0 S6 X$ @
  34.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// 外设数据大小为半字,即两个字节
    8 [* v2 l  s1 [: [* I
  35.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;// 存储器数据大小也为半字,跟外设数据大小相同
    9 \- d  f8 e1 v- S8 P& a
  36.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;        // 循环传输模式4 j' T, a- Q# r+ m5 e
  37.         DMA_InitStructure.DMA_Priority = DMA_Priority_High;// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
    ) B/ F# A5 p/ ^! A5 X* @3 O
  38.         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// 禁止存储器到存储器模式,因为是从外设到存储器$ `# E# X& }! Z1 s- W" f
  39.         DMA_Init(DMA1_Channel1, &DMA_InitStructure);// 初始化DMA
    : b( H* P+ s0 ]$ c0 P5 X! `: H
  40.         DMA_Cmd(DMA1_Channel1 , ENABLE);// 使能 DMA 通道, k4 P3 n5 J/ T  g  D+ A) Q
  41.         /*--------------------------DMA结束---------------------------*/) P: G! D/ A! K1 l1 c( r
  42.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1        , ENABLE );          //使能ADC1通道时钟% {7 d* R. b; L8 s
  43.         RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M3 i) q' N$ @% J( U
  44. % G* s$ e2 m' [& U1 K+ b1 `
  45.        
    8 }1 m0 o: I, V( C
  46.         //PA1 作为模拟通道输入引脚                         * v4 c7 K. c% v9 C) \, A! p" }" k
  47.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    * B3 j9 O: o  x( q9 g; y
  48.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //模拟输入引脚$ f* V) `4 F, s5 A
  49.         GPIO_Init(GPIOA, &GPIO_InitStructure);       
    ) q$ ]6 }. ?, j$ e! M7 Q
  50. % x" x5 g& n: N$ ]& j3 ]  @8 `
  51.         ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
    $ A+ S* E* o1 ^# b/ |& |
  52. 2 f! k8 x1 `5 V. C$ o" ~
  53.         ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;        //ADC工作模式:ADC1和ADC2工作在独立模式
    ) f* w: w' S, Q3 c% B0 ?" R, d
  54.         ADC_InitStructure.ADC_ScanConvMode =DISABLE ;        //模数转换工作在单通道模式1 `0 J  g7 |! z, b  g
  55.         ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;        //模数转换工作在单次转换模式+ n6 F( h0 `; s: @
  56.         ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;        //转换由软件而不是外部触发启动
    # ~1 o4 U4 N; U& M  _7 [
  57.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;        //ADC数据右对齐. p, B2 n$ T9 Q6 j5 u4 a
  58.         ADC_InitStructure.ADC_NbrOfChannel = 1;        //顺序进行规则转换的ADC通道的数目
    4 P3 @& O1 @$ F  ]$ u$ D# w% w
  59.         ADC_Init(ADC1, &ADC_InitStructure);        //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   
    $ R7 a& _' P8 z) B. X" o4 y
  60.   ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );# o! k6 a0 v( U' ~% r
  61.         ADC_DMACmd(ADC1, ENABLE);        // 使能ADC DMA 请求7 `, u; C; h1 T3 e, m
  62.         ; W2 k; {9 L" T( ~# x
  63.         ADC_Cmd(ADC1, ENABLE);        //使能指定的ADC1
    : p5 q- M# D# o- j& K
  64.         ADC_ResetCalibration(ADC1);        //使能复位校准  . c; J+ p$ `1 r$ w
  65.         while(ADC_GetResetCalibrationStatus(ADC1));        //等待复位校准结束2 O& a% @" W& |. L4 i
  66.         ADC_StartCalibration(ADC1);         //开启AD校准
    7 F5 l5 X+ P$ }" r/ I' @' D# Y
  67.         while(ADC_GetCalibrationStatus(ADC1));         //等待校准结束
    ( j  b! X9 q3 h1 H7 o+ [& P
  68.         ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //使能指定的ADC1的软件转换启动功能! i) I2 b) |- `! y6 z$ G( C% j
  69. }                                  9 K$ x  g4 H8 W7 o3 y: q; ^& [  f$ @  Z# n
  70. //获得ADC值# c6 K& g) }- _0 x
  71. //ch:通道值 0~3
    * r* X' R/ K- V/ |+ ^7 \# E
  72. u16 Get_Adc(u8 ch)   
    5 c( t1 o6 P5 ^9 b
  73. {
    3 N0 s$ y$ X' B* C: u, [# e
  74.           //设置指定ADC的规则组通道,一个序列,采样时间2 ~; Y( s. x0 R( ~! M' T8 W0 z
  75. //        ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );        //ADC1,ADC通道,采样时间为239.5周期                                      
    " p; E- C" x/ P$ J0 K# j5 e
  76. //  ; e* Y. t& n. T  f: t' O6 x2 m2 M
  77. //        ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //使能指定的ADC1的软件转换启动功能        & I* \& e6 m% E& A: X
  78. //         0 n8 N; d' R9 @$ y! U1 B2 m+ F
  79. //        while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束% o1 a; M/ M+ N5 m6 j- i) l9 P
  80. + N; N- f& ?7 L2 t
  81.         return ADC_GetConversionValue(ADC1);        //返回最近一次ADC1规则组的转换结果/ g! o  w% ?- Y
  82. }" t& N" n* c: q& H

  83. 9 w- }1 v% L- X; C% i8 x2 r
  84. u16 Get_Adc_Average(u8 ch,u8 times)
      n1 S% K& p7 Y& Z: K6 E
  85. {
    . _  q: w6 c6 e6 W5 x
  86.         u32 temp_val=0;" C& j# w  E3 Z( T; V. q4 q( c
  87.         u8 t;
    : S6 b6 Q% \2 c* J$ Q
  88.         for(t=0;t<times;t++)
    * |& ]# b$ b% I# |
  89.         {
    , d3 B& G5 w* j& {2 u, g& j  s/ {9 p
  90. //                temp_val+=Get_Adc(ch);) ]9 w; \3 d1 O, ?; c1 [  [8 D! Q
  91.                 temp_val+=ADC_ConvertedValue;
    $ o1 x) ?3 F) g; D6 r
  92.                 delay_ms(5);  |2 D* ]; n: B$ C+ e) }( i
  93.         }- X1 x  F$ W1 _- V' B, Q
  94.         return temp_val/times;, S% Z  f) c2 M' K6 @. u
  95. }          & y1 j# [7 e8 j8 ]0 k3 @
  96. 1 S4 B- `; |' c
  97. 1 R0 L" C$ r/ t- ?8 `, z; i" \5 V; {
  98. ' t' m$ P( q& i4 N7 R. M
  99. / z% ^  D- ~! h

  100. - f& z# i/ R  ^# |& ?; C' m: a/ C2 d

  101. 8 L5 l4 w3 ^- [8 w, ^0 j% y* c
  102. ( t8 [. X3 Q8 M4 U1 J3 E2 Z

  103. $ F: U  s& r- S. z0 ~1 f

  104. : \, z+ S  d' o, j9 _3 n

  105. & [' `: b" Z7 z1 R  i

  106. 8 C2 z- }9 \- {0 A/ e! F/ [! w3 y

  107. + m! f& q/ {( r- o5 m

  108. : n# q8 Z* V  o

  109. 4 R8 D$ H  m* v# R; M/ _) H1 j
  110. ) Q5 [' l! h% n/ {# ~3 ~% b: T
  111. 8 [7 P. K  O; I# Q$ W

  112. & s! Z" S* a9 d" V7 h

  113. 5 E! m' H, j/ ^2 i& X7 E
  114. % N7 X/ [1 C3 y5 @4 S7 b8 d
  115. 3 D5 n5 {9 G8 W6 N. d
  116. 2 v0 I& `, Z2 E4 F4 {& P
  117. : j9 h9 N7 M! G
  118. & c- ?2 J7 _# O  C

  119. # k5 H1 s9 ?' L
  120. + j1 s6 G3 T+ a' {* A& F& X) t
  121.   M. T+ }' Q. L: I* h
  122. + l3 X# X5 d3 ~
  123. " m5 e) C8 j2 U9 t6 s( V  ^

  124. 1 q' `% M; j# P$ [3 C+ V
  125. 4 l9 ?2 Z; l5 H  k6 g/ r; l& H

  126. ! n0 v* a- q7 A, z' D( ~
  127. * O0 v; B, b8 N- ?* K0 J7 [/ G( I
  128. #ifndef __ADC_H0 H: y9 F" x$ d
  129. #define __ADC_H        * R, b2 {( R8 j! n' z
  130. #include "sys.h". D& w5 @& ~+ a6 D  V* P+ O
  131. //本程序只供学习使用,未经作者许可,不得用于其它任何用途2 v# ?  J9 ^1 Q0 G* G  ^
  132. //ALIENTEK战舰STM32开发板, m) O% P" m/ R3 ~& S
  133. //ADC 代码          
    0 q' N7 r3 Q" K4 K
  134. //正点原子@ALIENTEK
    % x$ s8 }" o4 a' D. V6 X
  135. //技术论坛:www.openedv.com
    / |& N9 u+ i+ ?
  136. //修改日期:2012/9/7  V/ R- e' x: M* @1 V
  137. //版本:V1.02 i& V$ m4 N# o4 L" O
  138. //版权所有,盗版必究。0 i9 ^# f6 d- X' w
  139. //Copyright(C) 广州市星翼电子科技有限公司 2009-2019& J5 R; r- L, Q' u, S4 R0 }
  140. //All rights reserved                                                                          # A8 |+ O  W" ?5 F1 p& H# Y
  141. ////////////////////////////////////////////////////////////////////////////////// * _; q6 i! C) K( V& D8 H% _
  142. / y) R; p: O$ s. }9 X+ }
  143. void Adc_Init(void);
    ) F1 G6 m# x! ]  u4 {4 l; W0 v8 Z
  144. u16  Get_Adc(u8 ch);
    " ^0 K/ o$ }* c! }' K# M; t4 D
  145. u16 Get_Adc_Average(u8 ch,u8 times); ( F, y7 o2 o7 A! B, O
  146. 8 U3 p5 c2 H( _4 a  V
  147. #endif ) ]3 C: `1 G" |2 N9 B& j4 Q: t
复制代码
+ Y5 M) A6 w: z: Q6 d2 Y
# A. J/ w4 e' X) k% 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 手机版