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

分享一个ADC的DMA

[复制链接]
hhhhhhhaa 发布时间:2018-12-13 14:34
只做了一路,多路的话自己扩展4 X0 p1 s; P8 X, f/ t9 ~
  1. #include "adc.h"% \( m8 {  |- k" _3 A! r
  2. #include "delay.h". B7 B$ G( o1 ^
  3. //////////////////////////////////////////////////////////////////////////////////         - Q* U+ x1 ?! w& v6 G9 }6 [  u- O
  4. //本程序只供学习使用,未经作者许可,不得用于其它任何用途
    6 a$ T3 B! {5 Z. m5 n# A; Z9 v
  5. //ALIENTEK miniSTM32开发板$ x& S; c6 S5 w' {" o/ h6 E
  6. //ADC 代码          
    / |: M5 \1 }, ^
  7. //正点原子@ALIENTEK! l9 X- B, L: G8 l3 L; b
  8. //技术论坛:www.openedv.com
    9 S* R' i" e3 I, ^1 X$ v* {
  9. //修改日期:2012/9/7
    0 r) }& j, u& O6 A. y
  10. //版本:V1.02 ?) O- ~3 I6 v2 T& |, o
  11. //版权所有,盗版必究。
    6 T( G, \0 Y% j& f: @  a. N$ B6 Y  }
  12. //Copyright(C) 广州市星翼电子科技有限公司 2009-2019! t% ]* A1 U1 b4 n% I
  13. //All rights reserved                                                                          
    8 Y- u1 C) S* }: Z
  14. ////////////////////////////////////////////////////////////////////////////////// * ^. ?1 R) {! T! Y
  15.            % y4 p% e! f1 n+ w( p: N
  16. __IO uint16_t ADC_ConvertedValue;    B3 G8 j( l9 g+ r: Z# v% L0 x+ J
  17. //初始化ADC# {' U  r. m/ d8 {) S
  18. //这里我们仅以规则通道为例
    " Y; \' T( P7 q& S, i2 H$ i- G! j
  19. //我们默认将开启通道0~3                                                                                                                                          
    % V. W3 h- Y9 F9 W4 Z+ g. j
  20. void  Adc_Init(void)
    ; J2 Y5 E, h/ W+ N2 }. H
  21. {         % H6 R' S3 N( x( v' y4 ~$ l" i) V
  22.         ADC_InitTypeDef ADC_InitStructure; / y8 f% L; h" h6 p2 H+ r+ }- t
  23.         GPIO_InitTypeDef GPIO_InitStructure;
    " E0 T# |2 d- M7 x3 ~3 P
  24. /*--------------------------DMA部分---------------------------*/
    $ s* U. O  K8 a. z  e  c# C
  25.         DMA_InitTypeDef DMA_InitStructure;        . p" ?& ~5 l2 f7 i9 x6 E! N' p
  26.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// 打开DMA时钟6 w. O+ ], A( L* h$ B5 F
  27.         DMA_DeInit(DMA1_Channel1);// 复位DMA控制器* u+ Z7 l# ]6 q2 J' H6 i
  28.         DMA_InitStructure.DMA_PeripheralBaseAddr = ( uint32_t ) ( & ( ADC1->DR ) );        // 配置 DMA 初始化结构体        // 外设基址为:ADC 数据寄存器地址
    : J  J- M8 C! A6 S, Z5 A9 S
  29.         DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;// 存储器地址,实际上就是一个内部SRAM的变量* O7 }8 i7 x( g
  30.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;// 数据源来自外设' o0 b& n  B8 t. r" x
  31.         DMA_InitStructure.DMA_BufferSize = 1;// 缓冲区大小为1,缓冲区的大小应该等于存储器的大小
    ! H5 i1 Y; I8 E' r
  32.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 外设寄存器只有一个,地址不用递增
    & y: ~3 K% p: E# [7 |* r; J, ^
  33.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; // 存储器地址固定' Q) H8 U! n5 ^7 f
  34.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// 外设数据大小为半字,即两个字节
    , k& d1 }/ h8 y
  35.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;// 存储器数据大小也为半字,跟外设数据大小相同
    6 v& B4 N* t- v+ F6 K6 f
  36.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;        // 循环传输模式6 R$ u. H* _+ s" M
  37.         DMA_InitStructure.DMA_Priority = DMA_Priority_High;// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
    0 l( B+ x' r8 A% i5 n$ h1 A
  38.         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// 禁止存储器到存储器模式,因为是从外设到存储器% o4 h. [0 U0 l9 V
  39.         DMA_Init(DMA1_Channel1, &DMA_InitStructure);// 初始化DMA
    ' b2 ?' ]$ b  {" u
  40.         DMA_Cmd(DMA1_Channel1 , ENABLE);// 使能 DMA 通道
    6 K5 n' i! F6 G
  41.         /*--------------------------DMA结束---------------------------*/
    $ c6 s' S- M/ y8 w; g; P
  42.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1        , ENABLE );          //使能ADC1通道时钟0 a1 y5 g5 [. Y8 \
  43.         RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M: a9 [# _. E5 |3 j1 G" N( U" i

  44. 8 v; p9 b5 O# n4 M0 t
  45.        
    # o: D2 P! |$ e' ]! i
  46.         //PA1 作为模拟通道输入引脚                        
    2 L4 W" j! l/ Q% {5 H( o& n
  47.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;+ S8 V9 `2 B$ l* Q
  48.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //模拟输入引脚
    7 q8 N, G5 ?' [. Q% W/ g
  49.         GPIO_Init(GPIOA, &GPIO_InitStructure);       
    7 q# C3 f6 t( T$ B5 @, ~* F+ k, }

  50. ! b% x! @: b% l, ^. `" `3 x9 V
  51.         ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
    ! H1 a, p9 T  W1 p9 p. _
  52. + l6 \9 e. a6 O( X: D+ E: s
  53.         ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;        //ADC工作模式:ADC1和ADC2工作在独立模式: R4 |$ b& T! e- G& I: L
  54.         ADC_InitStructure.ADC_ScanConvMode =DISABLE ;        //模数转换工作在单通道模式
    + q, h7 t1 Z  v- |- [' y7 f, q5 |
  55.         ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;        //模数转换工作在单次转换模式
    2 P- M1 R( @- U: A, j6 A
  56.         ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;        //转换由软件而不是外部触发启动
    4 q7 W' h$ }1 c# V0 @2 Z8 R
  57.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;        //ADC数据右对齐
      I& R/ v, x: ]. j0 p
  58.         ADC_InitStructure.ADC_NbrOfChannel = 1;        //顺序进行规则转换的ADC通道的数目
      b4 t" [# w2 e1 v) e; D8 [" z
  59.         ADC_Init(ADC1, &ADC_InitStructure);        //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   ! z1 o, f1 ^, e8 S4 a$ Y3 f
  60.   ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );  ^* z( Q9 R5 ^$ U1 l
  61.         ADC_DMACmd(ADC1, ENABLE);        // 使能ADC DMA 请求7 K  {0 B+ d4 e6 V) y- q4 \
  62.         + t  t8 C. }6 j9 \( c, C3 E1 D
  63.         ADC_Cmd(ADC1, ENABLE);        //使能指定的ADC1- M7 n4 {) y: R! s3 V* S, M5 X1 E
  64.         ADC_ResetCalibration(ADC1);        //使能复位校准  
    ' v  ~% x' u/ F6 h
  65.         while(ADC_GetResetCalibrationStatus(ADC1));        //等待复位校准结束
    1 y! Z7 W7 F) @6 M0 z, s' z- a
  66.         ADC_StartCalibration(ADC1);         //开启AD校准- e: ^: w* W! Y1 a0 o  r& r( x
  67.         while(ADC_GetCalibrationStatus(ADC1));         //等待校准结束4 Q  i% B3 K. S/ Z  F3 j
  68.         ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //使能指定的ADC1的软件转换启动功能
      s1 }6 ]9 N+ b0 }- ]
  69. }                                  " X" l; e7 [* O# m( L1 x9 @! }
  70. //获得ADC值0 O5 ]8 U  [6 A" d) r3 G0 D+ v
  71. //ch:通道值 0~3  P- Q- ?3 N8 `; F. b3 E
  72. u16 Get_Adc(u8 ch)   & n& k7 |/ @# e( I9 f  ]
  73. {
    & J2 K/ j3 _* x3 r7 Z$ J6 d+ o
  74.           //设置指定ADC的规则组通道,一个序列,采样时间
    $ W1 b* Z5 n8 H
  75. //        ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );        //ADC1,ADC通道,采样时间为239.5周期                                      
    % c. h; F4 {' t1 U8 s2 [) `
  76. //  # v) N0 d  d" A7 d0 Y7 h, T
  77. //        ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //使能指定的ADC1的软件转换启动功能        , Z/ L3 b: V) I; {0 g$ |" K
  78. //         4 z) |" z/ ^2 F; ]6 n8 h4 R* x
  79. //        while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束6 V! H) X6 q& P5 |, Z: ?" D

  80. - F4 i+ Z( E9 J: b+ M
  81.         return ADC_GetConversionValue(ADC1);        //返回最近一次ADC1规则组的转换结果+ O5 b- u( P& N6 V" d. p
  82. }- u2 F- t' N/ X0 U4 n" Y

  83. 2 d. E6 u  \0 \) |: l0 |' o( G
  84. u16 Get_Adc_Average(u8 ch,u8 times)
    1 i# M+ H* H9 a" S
  85. {. t: {1 h$ Z9 l$ q( z
  86.         u32 temp_val=0;
    - ]/ q3 A, d# B& k6 q
  87.         u8 t;5 s8 a* G' [4 {+ |( w
  88.         for(t=0;t<times;t++)
    ' e' m4 e, R9 H% t% z5 x
  89.         {6 r1 r4 I0 Q# D
  90. //                temp_val+=Get_Adc(ch);) w( F- J3 [1 B) [8 [( A
  91.                 temp_val+=ADC_ConvertedValue;% N' z) i6 m5 I$ h- w; ~* C1 Z
  92.                 delay_ms(5);. l5 f& H/ h6 s
  93.         }
    # s) s* b5 s. Q
  94.         return temp_val/times;
    ! x5 I+ A! F9 w
  95. }          
    ' W. A- H/ @7 f. u0 W, b7 h) S+ V

  96. 6 I, S/ p( Q, w; j/ M# L% U# Q) i1 \

  97. . H2 m* B. c7 D
  98. 2 r- K$ }: D5 h

  99. 8 A2 d7 A% R- v' _; Q0 H
  100. - o  k! H. A6 Q9 F2 [

  101. + {. \. _! u/ G8 u5 k

  102. % C# W4 d5 Z1 @, ~

  103. ; @+ D. Z5 m9 U% J
  104. # G) S+ f2 H+ [# Z
  105. - ^1 U3 R& z0 E0 C1 M6 F4 s
  106. 5 \+ b; |* k( X; B: W# Q

  107.   y) \: c3 `) d+ t5 a8 e

  108. & W4 q% b* z; g* Z
  109. 3 l, |8 B2 u4 E8 B9 ^
  110. 3 C: z9 R) W. q7 Z* @3 o5 d: w
  111. 2 Q- y* Q. X, a+ {
  112. ! o3 ^0 u; K3 z2 r. x4 ~

  113. , z+ l* w8 L' m. Y
  114. 9 Q; z4 Z. E+ }5 Q3 T% a
  115. + _7 z5 s/ }- I
  116. 9 Y( B' D6 |. C- \) [% W8 |3 {/ n% J

  117. 5 D- `: z1 N, J8 P$ Z5 X! ~- o

  118. 5 _6 o, F4 F8 g. `* G

  119. 8 Y* B& w2 u: U' A9 d) ~

  120. ' [7 s- t6 a: y  E; T5 @8 V

  121. & y/ V% c8 [' z0 Z0 G" b  w1 a

  122. ! G7 t- ^% S4 X2 \6 }

  123. & m! [, \5 V" I8 y) O; ]: ]# Z0 k
  124. 7 b4 m5 h) o) a

  125. ) ~( I% y5 s7 Q3 c5 F. N

  126. ) o& T% X6 O' k9 u2 j

  127. 1 V" L# B* _- E
  128. #ifndef __ADC_H
    % e' {6 t: U; z' [; S3 k
  129. #define __ADC_H        8 F: w+ A& P1 I
  130. #include "sys.h"
    ' G+ a1 G9 c  O
  131. //本程序只供学习使用,未经作者许可,不得用于其它任何用途0 }4 V# ^- M  D" r6 J/ m
  132. //ALIENTEK战舰STM32开发板) ?0 u' \& O! f4 `
  133. //ADC 代码          
    1 l* P* H* ~: V2 ~
  134. //正点原子@ALIENTEK; ?( Q, o4 H; G$ X- ]3 p7 Y# Z- ]
  135. //技术论坛:www.openedv.com, ^$ t) ^; W; F' A3 p* ~! }
  136. //修改日期:2012/9/7' w" Z0 i& p9 l7 C+ [
  137. //版本:V1.0
    5 V+ z% X6 d9 W- P& S  m$ Q
  138. //版权所有,盗版必究。2 C1 w; p3 G9 t3 ]! d; h
  139. //Copyright(C) 广州市星翼电子科技有限公司 2009-2019$ R6 {" @# |# ~4 J! w" z
  140. //All rights reserved                                                                          4 o3 N# G2 n6 p0 q& Q7 J* S  `0 D3 U
  141. //////////////////////////////////////////////////////////////////////////////////
    3 g0 U) `" c3 E% n* \$ v2 ~

  142.   z: S3 A: X# I: P$ X
  143. void Adc_Init(void);! x7 Y1 l& P/ K% V/ a. [( D: ^
  144. u16  Get_Adc(u8 ch);
    ) `+ D$ C# n- J* G
  145. u16 Get_Adc_Average(u8 ch,u8 times);
    ! P" A! X( l4 X' x* P. ?
  146. ! [! [1 K, M5 v6 [
  147. #endif
    % T4 ^1 T* w( j  r  |2 K8 f+ E" Z) O
复制代码
- N% C& h: U) A# [1 m% ?" q

1 H; L) }/ g+ m; B8 Z+ q
收藏 评论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 手机版