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

STM32 DMA USART ADC

[复制链接]
苏城123 发布时间:2017-8-29 14:48
这是一个综合的例子,演示了ADC模块、DMA模块和USART模块的基本使用。
我们在这里设置ADC为连续转换模式,常规转换序列中有两路转换通道,分别是ADC_CH10(PC0)和ADC_CH16(片内温度传感器)。因为 使用了自动多通道转换,数据的取出工作最适合使用DMA方式取出,so,我们在内存里开辟了一个u16 AD_Value[2]数组,并设置了相应的DMA模块,使ADC在每个通道转换结束后启动DMA传输,其缓冲区数据量为2个HalfWord,使两路通 道的转换结果自动的分别落到AD_Value[0]和AD_Value[1]中。
然后,在主函数里,就无需手动启动AD转换,等待转换结束,再取结果了。我们可以在主函数里随时取AD_Value中的数值,那里永远都是最新的AD转换结果。
如果我们定义一个更大的AD_Value数组,并调整DMA的传输数据量(BufferSize)可以实现AD结果的循环队列存储,从而可以进行各种数字滤波算法。
接着,取到转换结果后,根据V=(AD_Value/4096)*Vref+的公式可以算出相应通道的电压值,也可以根据  T(℃) =  (1.43 - Vad)/34*10^(-6) + 25的算法,得到片内温度传感器的测量温度值了。
通过重新定义putchar函数,及包含"stdio.h"头文件,我们可以方便的使用标准C的库函数printf(),实现串口通信。
相关的官方例程,可以参考FWLib V2.0的ADC\ADC1_DMA和USART\printf两个目录下的代码。本代码例子是基于万利199的开发板EK-STM32F实现,CPU=STM32F103VBT6
% q/ T8 m7 P1 U% V
  1. 本文件实现ADC模块的基本功能  w1 @. C5 s, D% \/ `+ R$ y
  2. * 设置ADC1的常规转换序列包含CH10和CH16(片内温度传感器)' z+ l* N4 m# s# s0 S
  3. * 设置了连续转换模式,并使用DMA传输7 O3 [4 J, Z: o! \% d
  4. * AD转换值被放在了AD_Value[2]数组内,[0]保存CH0结果,[1]保存CH16结果8 r+ B; x- a( [# E7 ^( j
  5. * GetVolt函数计算[0]的值对应的电压值(放大100倍,保留2位小数)
    ! ^* |1 {+ N+ L* g3 e
  6. * GetTemp函数计算[1]的值对应的温度值,计算公式在相应函数内有说明
    ' E8 N, _- L, e4 b- ?
  7. *  作者:jjldc(九九)
    1 f/ X: r) T- v; D. A9 H  u
  8. *******************************************************************************/. Q8 f  g+ E2 u3 y
  9. ! Z/ G4 |' K& ?* h
  10. /* Includes ------------------------------------------------------------------*/' K0 g1 j& U. L2 B( w
  11. #include "stm32f10x_lib.h"" d0 ^' ^4 B; }4 P/ ?6 s( w
  12. #include "stdio.h"0 z; M/ X9 a( a( C! N1 _8 m. Y

  13. ) J/ z; Y6 x& ^: ^, l
  14. /* Private typedef -----------------------------------------------------------*/
    ' j0 H7 U# r# @/ _: X5 r# u) |' B/ o
  15. /* Private define ------------------------------------------------------------*/
    7 G8 ?" ~- A; V  X! y
  16. #define ADC1_DR_Address    ((u32)0x4001244C)
    9 a2 O% I' k3 Q
  17. /* Private macro -------------------------------------------------------------*/
    - P. G2 `: p' c/ ]' n
  18. /* Private variables ---------------------------------------------------------*/( x# T9 }+ Z  U0 t
  19. vu16 AD_Value[2];
    ' q2 `, k9 s" R" D. t4 `* @
  20. vu16 i=0;
    / \' K' w2 G" }% {% F
  21. s16  Temp;, r+ m9 P( n6 S/ g" L$ m. ?
  22. u16  Volt;
    $ h, Y0 t. N; b1 [3 t) S7 K2 ^
  23. ( q( o) w4 q  E$ R" f" m
  24. /* Private function prototypes -----------------------------------------------*/
    7 m* l" |' b: K* o( i
  25. void RCC_Configuration(void);
    5 o5 s( ~& E9 L9 J
  26. void GPIO_Configuration(void);
    ! c, B  x1 ~+ e* I. T
  27. void NVIC_Configuration(void);$ R6 Y; L4 x8 q& h0 v  C
  28. void USART1_Configuration(void);
    2 P7 E- Y& B- U  a5 n5 {3 b0 s% Q
  29. void ADC1_Configuration(void);
    " Q( B9 p4 e5 B9 _/ c9 V3 X
  30. void DMA_Configuration(void);
    . H9 M5 O" U' R! e$ s

  31. & H* `: k1 n4 B
  32. int fputc(int ch, FILE *f);  f1 Z! J$ k# I' Z
  33. void Delay(void);. i" I0 ?2 r5 \& [8 d9 K. @
  34. u16 GetTemp(u16 advalue);' {; c9 f& ?6 b, h! a# a- l$ M
  35. u16 GetVolt(u16 advalue);
    4 x. G# o+ ]; O
  36. /* Private functions ---------------------------------------------------------*/+ B) q( M8 }' N2 u9 u
  37. /*******************************************************************************
    $ M" C) w# l$ I5 I/ r* f* X- v- i
  38. * Function Name  : main
    & F8 i9 t7 p3 }. D& B7 Q2 R) I
  39. * Description    : Main program.+ b, |! ]! d, w6 u2 q+ ]
  40. * Input          : None' _7 y. u: j1 q: M* b
  41. * Output         : None/ Z" \* _! b' ]
  42. * Return         : None8 \; S1 w. H3 y0 \% r& l
  43. *******************************************************************************/! X4 a- j, ~1 V' |- a
  44. int main(void)
    $ ?+ M1 l' g# q$ Y
  45. {: x* \( k8 z. F+ u$ [6 S3 p* U1 F) c
  46.     RCC_Configuration();
    ; J. Q) }2 `) ^& ]5 `0 Z! _5 e
  47.     GPIO_Configuration();
    ' z0 g& C. @% N+ I% ^) J
  48.     NVIC_Configuration();
    7 a: f* c" ~. k% V/ v5 O) V- Y
  49.     USART1_Configuration();4 S4 u. m0 w& A' ^
  50.     DMA_Configuration();5 s- K0 c/ |! m* `! O
  51.     ADC1_Configuration();
    0 u5 }$ N- ]+ x3 b- b2 j, W
  52.    * [/ @. N& L; [3 @" s% c% M5 k3 ]
  53.     //启动第一次AD转换$ A) @6 y: v( ]: m. A9 Y
  54.     ADC_SoftwareStartConvCmd(ADC1, ENABLE);$ o+ F. X  b! _. J2 B7 Q
  55.     //因为已经配置好了DMA,接下来AD自动连续转换,结果自动保存在AD_Value处  + D$ N" _" b# N/ ^0 A
  56.    , D4 B, t: @, o
  57.     while (1)7 P( H) a5 o7 u. ?! P: l% u
  58.     {
    * v( N9 P8 s! K- e# D
  59.         Delay();
    9 Y2 A6 Q, I: x& _2 Z2 W2 n
  60.         Temp = GetTemp(AD_Value[1]);
    ( H2 a7 m5 c$ m
  61.         Volt = GetVolt(AD_Value[0]);
    6 f9 }1 c7 k% ?. X8 Q7 G* Q" ^* a
  62.         USART_SendData(USART1, 0x0c);       //清屏
    # A; o- o, X( l2 d, k( W2 s+ X4 U9 a
  63.         //注意,USART_SendData函数不检查是否发送完成
    8 F8 }$ c" R( o: O$ @* I1 ~
  64.         //等待发送完成/ T0 X. R0 T! R( ~/ H
  65.         while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    - ]& G+ g; u0 C# l! r

  66. & G$ r$ W5 T+ g( ~2 r
  67.         printf("电压:%d.%d\t温度:%d.%d℃\r\n", \) K2 E$ U7 k3 f$ b1 R, \# a
  68.             Volt/100, Volt%100, Temp/100, Temp%100);
    ) P7 x5 x! F& D7 z
  69.        ) h; O  H) e" n# S* h& P" f; o" F; i
  70.     }* y; q0 U0 R0 l4 C" @1 |8 N9 ~. T
  71. }
    ; A  `) A! H4 p& D9 ~5 @: ]
  72. 0 t8 d6 `# k4 f
  73. /*******************************************************************************
    % o  N, V# T4 V0 E, K
  74. * Function Name  : 重定义系统putchar函数int fputc(int ch, FILE *f)7 A2 F  Z. y% f" ]8 X% G
  75. * Description    : 串口发一个字节  g0 E) p0 H, v0 R
  76. * Input          : int ch, FILE *f
    6 x8 H- {- h7 g1 l
  77. * Output         :# \' P. e3 ^' V% J- A5 m% \
  78. * Return         : int ch2 W- a2 ^3 t4 z/ I5 J* m% Y$ m; V
  79. *******************************************************************************/: K; }6 }7 N! a! W2 ]* m
  80. int fputc(int ch, FILE *f)
    9 q& J. J. M) @* n( }, D% ^
  81. {6 ~5 _! c( t& }  \4 l, u
  82.     //USART_SendData(USART1, (u8) ch);! ?# }' B$ ?' r4 q$ i: w7 I( z. ~: m
  83.     USART1->DR = (u8) ch;" A4 ~4 B% |* p6 A4 K  {( c
  84.    ; `' [3 V, R3 a" I  B1 Q
  85.     /* Loop until the end of transmission */6 M& A+ R% [/ F% \# S
  86.     while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)8 r" `. N0 \! w( t* z& U# f) ~
  87.     {
    7 W. p! W; y$ x2 A5 ~7 E3 j
  88.     }. y( F5 U  L) {# ~1 d
  89. 1 w, u8 I. q) A0 W
  90.     return ch;
    5 [2 ?* h1 h9 R: {& y4 \
  91. }6 M# m+ Z" l5 B9 C7 T' C

  92. 3 }7 F4 l& S. [/ i* W
  93. /*******************************************************************************+ T+ [5 T% A: i( Q  t3 A0 X$ A
  94. * Function Name  : Delay3 P8 }; ^% z& |/ @' q: {
  95. * Description    : 延时函数6 }" X) {3 Q- B2 H% l
  96. * Input          : None
    ( M! L/ G  Q, p+ z) A
  97. * Output         : None
    * f4 a/ O! `' y. j8 V/ ^
  98. * Return         : None
    $ |: B* c: W% s8 @+ S
  99. *******************************************************************************/
    5 l9 T2 S" w4 v: {2 o9 A& S
  100. void Delay(void)1 V& @/ r& L# P
  101. {
    1 y. I9 d, L5 y* z! x2 \1 ^- z
  102.     u32 i;
    ! l! {& Z0 }# {4 ]  C1 f5 n
  103.     for(i=0;i<0x4f0000;i++);* A* ]" S  W+ {
  104.     return;, \2 K; X% I1 X3 e7 m
  105. }                           
    % \* K$ f# r' S9 g* |# D

  106. 3 z! T$ B* o- Q7 M4 ~* \+ o. h: d
  107. /*******************************************************************************
    4 t( r* r0 {8 x/ k# H
  108. * Function Name  : GetTemp8 W( B# d9 w) f' ]
  109. * Description    : 根据ADC结果计算温度
    ( u4 E  ?0 U4 ]* X( E/ }
  110. * Input          : u16 advalue; q. A5 F" h& ?4 l0 I
  111. * Output         :
    ! Y" L5 w4 K% S! ]# y
  112. * Return         : u16 temp( s4 S( r% T5 ~, s1 ~  r
  113. *******************************************************************************/
    5 A. Q" v9 \" i! m6 Z) \
  114. u16 GetTemp(u16 advalue)3 \4 |! w0 A$ G4 _- J6 c' }7 H
  115. {$ U5 Y* |( g( K3 W4 T% d2 p
  116.     u32 Vtemp_sensor;
    / ^- t9 \! R9 k2 f8 w7 N  y$ Y. a
  117.     s32 Current_Temp;
    - l* L/ Z0 Q9 e) L
  118.    6 `1 _1 h2 z/ Z/ V; r% U0 }) N- e3 F. k
  119. //    ADC转换结束以后,读取ADC_DR寄存器中的结果,转换温度值计算公式如下:
    ; E4 B/ y- g8 ?
  120. //          V25 - VSENSE
    6 J6 O* A8 L9 U
  121. //  T(℃) = ------------  + 25
    ( E4 P) Q' p( I, D! Z% |# x
  122. //           Avg_Slope; r3 E1 [* f6 @
  123. //   V25:  温度传感器在25℃时 的输出电压,典型值1.43 V。
    & H0 m! |; E9 G& N( r% S. Y
  124. //  VSENSE:温度传感器的当前输出电压,与ADC_DR 寄存器中的结果ADC_ConvertedValue之间的转换关系为:$ q' ~! j$ A( b  ^# M; F0 Z
  125. //            ADC_ConvertedValue * Vdd
    * U( X: w4 b! o- S  F& R. w2 V. y
  126. //  VSENSE = --------------------------
    7 f9 |. \2 ?1 u
  127. //            Vdd_convert_value(0xFFF)
    ' Y" @# ~0 X& g6 z( Y- A8 o6 }+ ?
  128. //  Avg_Slope:温度传感器输出电压和温度的关联参数,典型值4.3 mV/℃。7 S1 @, y# y3 q4 S6 N6 q% x! C
  129. " c3 {( v: [5 B9 G/ o- j
  130.     Vtemp_sensor = advalue * 330 / 4096;
    : m' }. v& l9 e6 q
  131.     Current_Temp = (s32)(143 - Vtemp_sensor)*10000/43 + 2500;
    9 o3 _7 e6 p( e8 a; w/ f; Y* |4 G
  132.     return (s16)Current_Temp;& L9 ^: L$ l7 L. Z. w5 A# f3 S
  133. }
    ; Q: U; M/ Z# {  z# o

  134. 1 ]5 b- k: ?$ A
  135. . y8 I6 l" m3 w# z( f
  136. /*******************************************************************************7 n( ^/ O2 m- `, B. F, s, `+ H
  137. * Function Name  : GetVolt
    : W, F! o  x* B; }" s. i. v' w
  138. * Description    : 根据ADC结果计算电压
    8 Y$ ]( z  O2 }, P* W
  139. * Input          : u16 advalue
    9 t- l$ x) f: d, z! |( I6 [1 o0 S
  140. * Output         :
    ) p$ [  u' ~2 d1 L& I3 G' Q
  141. * Return         : u16 temp
    * A1 ^/ x$ Q+ y5 _2 W7 n* z/ T! y4 C
  142. *******************************************************************************/4 r& h5 Y0 t5 v$ r4 X
  143. u16 GetVolt(u16 advalue)
    : s; a3 V" l9 B- A- U: }
  144. {
    $ `8 S3 J5 R" T
  145.     return (u16)(advalue * 330 / 4096);% ~. A% A. |" g+ W
  146. }
    9 p9 \  z* E2 \6 g0 ]1 J
  147.                          2 {# G# u9 s/ ^+ ]
  148. 2 U8 I' ]- p$ q2 B  c- I
  149. /******************************************************************************** I3 [: r& R( z$ v: {& D
  150. * Function Name  : RCC_Configuration0 z2 i. m, h9 z4 D, K) _
  151. * Description    : 系统时钟设置
    7 H/ R# C7 E" a9 Y$ `* B1 c! N
  152. * Input          : None8 v4 f. R. T0 V, E( J" Q9 Q
  153. * Output         : None/ h- h8 a: J$ z  |. t0 u: e( Z
  154. * Return         : None% ?8 I3 X# ~. I* Q% Y0 g
  155. *******************************************************************************/, k8 X. w  M0 A) g7 o. g
  156. void RCC_Configuration(void)* i! C4 ~9 g2 _+ X
  157. {
    7 n, _1 t8 [# u4 L) L& w  J) H
  158.     ErrorStatus HSEStartUpStatus;5 E% v+ a5 `( x) S9 }1 l, T$ @

  159. 4 N0 B2 V2 T# ?
  160.     //使能外部晶振
    ( _* N5 w7 ]3 L
  161.     RCC_HSEConfig(RCC_HSE_ON);
    . g5 D# K4 j. t& ~' N
  162.     //等待外部晶振稳定
    5 I( u0 d2 S# r& ^/ p; r7 R2 O- _
  163.     HSEStartUpStatus = RCC_WaitForHSEStartUp();
    " I" ~/ W7 N7 ^! E+ B7 a( `
  164.     //如果外部晶振启动成功,则进行下一步操作
    9 ?6 z# X( `# [1 g# A! c* i; T
  165.     if(HSEStartUpStatus==SUCCESS)5 h. t! i) k% h, c  m- G' a) K5 ?% _  J
  166.     {! G0 `5 e! [( u, u9 P8 C2 Y1 W
  167.         //设置HCLK(AHB时钟)=SYSCLK
    - |% G2 v0 _; R% v1 A
  168.         RCC_HCLKConfig(RCC_SYSCLK_Div1);
    ' P) W; B; _* A: Z4 h, e$ A7 ?

  169. ; b- H7 k6 F6 v$ N8 J
  170.         //PCLK1(APB1) = HCLK/22 O# I) [% b( R/ Z
  171.         RCC_PCLK1Config(RCC_HCLK_Div2);
    , ?1 A. O' ?% j/ ?* ?

  172. * ?0 z" C7 t5 x9 F8 \
  173.         //PCLK2(APB2) = HCLK+ W1 b7 L7 h+ a
  174.         RCC_PCLK2Config(RCC_HCLK_Div1);: C: Z5 M* H3 _
  175.        ! c' ~8 d; B& z. D' ^
  176.         //设置ADC时钟频率
    3 b, o2 r1 h+ T+ n. G6 q
  177.         RCC_ADCCLKConfig(RCC_PCLK2_Div2);0 X) x6 q. r9 f. W& ^1 u

  178. 2 i  k( e, B* s5 e
  179.         //FLASH时序控制! Y3 N, ^( S; ?3 y
  180.         //推荐值:SYSCLK = 0~24MHz   Latency=05 A. K+ k2 ]  k* G4 D
  181.         //        SYSCLK = 24~48MHz  Latency=1* W  C7 F8 T5 J% P
  182.         //        SYSCLK = 48~72MHz  Latency=2
    2 L6 a; W1 j+ O0 C7 Q
  183.         FLASH_SetLatency(FLASH_Latency_2);
    + f5 c6 r4 ^9 U0 _3 c! @
  184.         //开启FLASH预取指功能( v9 H7 }0 ?! \( Z& D
  185.         FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);% \4 L3 l& K8 f+ t) o% q3 N
  186. $ c1 K0 |. Y4 Z( ]
  187.         //PLL设置 SYSCLK/1 * 9 = 8*1*9 = 72MHz& K2 z8 |) d1 d  b2 p2 S
  188.         RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);# Y, B$ ~) z2 t, f; K9 ?' ]" B
  189.         //启动PLL
    - A+ }4 c* q/ _- w
  190.         RCC_PLLCmd(ENABLE);! _, m4 F$ X! }% L5 r  Z" Y9 J
  191.         //等待PLL稳定
    # x0 s% T. O* i) I2 _! k
  192.         while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    9 @( H5 p7 u( T% e% P. x( f
  193.         //系统时钟SYSCLK来自PLL输出$ M: t5 n% d5 r; J0 E! O; `
  194.         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    ! X2 H: D) A% t. l3 s1 S* k0 Q
  195.         //切换时钟后等待系统时钟稳定
    & m7 _0 J$ X0 J$ ~' l: L2 x6 {
  196.         while(RCC_GetSYSCLKSource()!=0x08);8 m4 T7 X! G8 M
  197. 8 D: O/ J5 K5 ?
  198.       
    ) W( ?4 t: I/ G( z: U
  199.     }6 b" f7 H7 S5 q: r6 O/ @* P
  200. - K$ i8 C4 ^. v# E) P! m
  201.     //下面是给各模块开启时钟
      o' n2 o* }2 M; N
  202.     //启动GPIO
    $ e) s' g+ m0 x. O. x
  203.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | \6 t( t0 K& s  r9 a0 o
  204.                            RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD,\
    & W; N* Q2 H3 m8 j# F+ G
  205.                            ENABLE);9 I8 f$ y' J, N9 k  g
  206.     //启动AFIO
    7 n! b, _2 g, m* b
  207.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    ( V: r2 [: x  F  Y: J8 b  X# ~
  208.     //启动USART1
    " r/ A* x9 M7 U% Q$ h; N/ ~
  209.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    $ K, G( b* \4 `
  210.     //启动DMA时钟
    * v6 _- M- A' W: q0 W
  211.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    $ F3 Y, T6 z4 k+ k1 }2 Y# i
  212.     //启动ADC1时钟
    2 Z3 a9 {1 G# v
  213.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);0 c7 R! e8 G2 L* h+ W* Z. F/ z

  214. 4 Q5 ^7 D1 A4 f" Q% `7 H6 ~- i  R
  215. }2 [$ B- Z9 P, K& V( [5 A% X! J' K2 {

  216. 5 s: g+ B. D+ Q) t# R4 E( `
  217. 1 o5 b9 G/ Q3 a9 @- p  V
  218. /*******************************************************************************
    & W3 B/ \  }& r9 U3 H
  219. * Function Name  : GPIO_Configuration5 g+ b7 E0 U( H4 \* ^
  220. * Description    : GPIO设置
    ' ~6 m/ _' V! p: R; S: E
  221. * Input          : None) b5 ^: Y. g0 H6 i7 H2 Y
  222. * Output         : None5 V3 n: `8 O/ n% Z0 d
  223. * Return         : None
    6 u! {  P7 d# X3 b3 q" G
  224. *******************************************************************************/% s. ]2 p' p6 g2 R% t# F) U; `
  225. void GPIO_Configuration(void), f; T, W4 c; W: I0 `5 c
  226. {
    9 v5 W, \" t7 ^5 j' n
  227.     GPIO_InitTypeDef GPIO_InitStructure;
    # v/ c7 G( F. c8 Y: V: T
  228. ( H% u; C( }, @4 X% H
  229.     //PC口4567脚设置GPIO输出,推挽 2M
    ( Z: ?) ?# q$ Z' P, H# \
  230.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;: ^+ u+ Y; c; {! i0 ~2 ~( G
  231.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;* Q$ Q4 F9 d) H. ^0 [$ v
  232.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;* N1 L* v% K2 W* T: g6 u
  233.     GPIO_Init(GPIOC, &GPIO_InitStructure);' {  r5 T" o6 ^, t4 g

  234. , i$ M( w9 L0 u# [
  235.     //KEY2 KEY3 JOYKEY& z! U9 b" Z  n. u2 e: w& k
  236.     //位于PD口的3 4 11-15脚,使能设置为输入* O. Y7 _% @5 H  U6 c" g" Q9 E# }  m' _
  237.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_11 | GPIO_Pin_12 |\
    : i1 q( U* `1 o$ g0 F) g& g& F
  238.         GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    % D# z( ~' f) F& Q2 Y0 L9 o
  239.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;$ D" k& o" W, [0 t; ~0 ?
  240.     GPIO_Init(GPIOD, &GPIO_InitStructure);
    " X5 }5 K# N. Y/ k* w4 I) [& E' C

  241. ' R1 `/ d: S7 y/ g. @) `, Q
  242.     //USART1_TX
    9 R, t) y/ a) q* q9 C
  243.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;- _/ [4 C) E* g
  244.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;% @9 y0 L; g7 C- K6 t) m
  245.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;# w0 l2 }. V; f3 D1 V$ _7 i
  246.     GPIO_Init(GPIOA, &GPIO_InitStructure);! J) A: l5 P1 j% u& T& `
  247.    
    6 h4 O5 K6 p! M
  248.     //USART1_RX
    ! e3 {- S9 a2 g  \2 B" w
  249.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;8 D$ g8 g1 M5 G1 T, D5 _4 p# W+ Y
  250.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    - _  V3 B. p' Z, M
  251.     GPIO_Init(GPIOA, &GPIO_InitStructure);' W& P% s( \2 q# r
  252.    ( P9 s% g3 c6 K2 O& t% T
  253.     //ADC_CH10--> PC0
    3 O- Y  p$ F$ q+ o) ]( H4 A3 t
  254.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;5 @0 O" }. M4 o% c
  255.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;& J- ~: i4 b7 _( {: I* u5 \9 x1 d0 R
  256.     GPIO_Init(GPIOC, &GPIO_InitStructure);  @$ F# o9 |$ d3 n3 F# g) c
  257. # M2 u1 ~$ I5 r# @* N: F
  258. }) m5 Q3 ]1 @9 d  W/ y" b# _
  259. 7 j& A: k( A5 [$ `8 ^( v+ C$ e

  260.   n- {* t2 k& P/ y
  261. + `/ d( `5 k2 L8 u3 U
  262. /*******************************************************************************
    , y1 z) b! C1 C7 J  s% l
  263. * Function Name  : NVIC_Configuration
    3 U( J: }: I: R9 |, L* G
  264. * Description    : NVIC设置
    6 k( T6 Z) x- x6 u8 t' M
  265. * Input          : None* ?, n- M' m8 G" R2 k! o. S
  266. * Output         : None6 s( k# |* g' x* [; @) P6 X9 i
  267. * Return         : None
    " r2 d1 P; ?& h+ D* R
  268. *******************************************************************************/
    ( j( h- z* |6 H# P
  269. void NVIC_Configuration(void)
    1 ~% }3 b, o& S" W* Z- z# U
  270. {& v/ x1 i/ Q. @4 F
  271.     NVIC_InitTypeDef NVIC_InitStructure;9 M+ U. a' e8 j4 q+ W# h! S
  272. # U: z- W7 S- K; h" l. f1 }; m
  273. #ifdef  VECT_TAB_RAM
    0 k# ^) j) M: _+ M
  274.     // Set the Vector Table base location at 0x20000000$ A; t  g6 @6 g8 z
  275.     NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);. x# G9 n7 B. @# \
  276. #else  /* VECT_TAB_FLASH  */
    $ A, P" c5 F' @" d3 T9 r& s1 L
  277.     // Set the Vector Table base location at 0x08000000
    , D: c* j; }8 }* M6 O8 {
  278.     NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
    , W1 O% @. x3 i" H! s& Y2 S
  279. #endif
    8 q* r- m- c' S; T# Y5 j* S2 R

  280. 0 J) E" S" D: @- H/ l
  281.     //设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级! G! q" ?7 o: \4 I
  282.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    0 r" ^5 e6 Z, I. {
  283.     //串口中断打开
    ; D& Q* d  Z, p( S% b3 O! Y% e
  284.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;( N/ D' k0 V) x, B' Z1 y
  285.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;) x3 H, J5 h6 c; G! o8 J
  286.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    , v+ ~* `+ L7 H+ A) ~+ j
  287.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;: ]  f2 s" N; l" g. z0 f: x! B8 T
  288.     NVIC_Init(&NVIC_InitStructure);
    5 O7 u% e- {* O
  289. }
    4 ^# W/ ^/ z" T
  290. + v# I6 A" e/ l# T. ?
  291. 6 W0 C0 F, J+ {. M& Z
  292. /*******************************************************************************
    1 l$ J" \# V0 E6 K# t+ F4 P, @
  293. * Function Name  : USART1_Configuration$ w4 o' ~7 q! W+ r/ a
  294. * Description    : NUSART1设置1 S7 Z4 I1 Q/ w
  295. * Input          : None& f7 l' F% N3 H
  296. * Output         : None$ z+ _, G" P& m
  297. * Return         : None
    - a6 a9 B% ~9 W$ q, U: a' T
  298. *******************************************************************************/# j' \  E( |& a4 c+ o
  299. void USART1_Configuration(void)+ r; @+ B2 D3 c) P
  300. {" Z6 N7 g9 G$ m8 W5 m1 G  L
  301.     USART_InitTypeDef USART_InitStructure;$ t; y. y! @% V' b. ?0 K
  302.    
    % o. x6 i" Q0 D$ y9 N2 I9 }9 T
  303.     USART_InitStructure.USART_BaudRate = 19200;& b: c! _; i( c4 ]$ _. q
  304.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;' G$ W( r; q- t
  305.     USART_InitStructure.USART_StopBits = USART_StopBits_1;- z1 s6 }9 t8 @
  306.     USART_InitStructure.USART_Parity = USART_Parity_No;
    3 g* r8 Q, r  \1 t6 O$ L
  307.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;' ^7 J' ^6 `! E. n* v
  308.     USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;% i& j6 t2 u! H; M. p! o! p5 v
  309.     USART_Init(USART1, &USART_InitStructure);
    ) R! n9 G, Z$ l" K2 ?  ~* p2 S+ r
  310.    ( g# t; N5 [3 U' A( L
  311.     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);% g* G5 Q2 e8 W/ U: s, E& B
  312.    
    ( p, g/ q2 ~, ~' m; B
  313.     USART_Cmd(USART1, ENABLE);5 `& {) i: {: h9 x. k. G( r/ N
  314. }! G5 r4 \/ r+ M5 e- |- u' l" T
  315. 7 q9 `+ k9 h& F0 I0 p; {. Q
  316. /*******************************************************************************
    5 _5 {/ \# u" q* B
  317. * Function Name  : ADC1_Configuration
    . }4 i$ q& v8 B) H
  318. * Description    : ADC1设置(包括ADC模块配置和自校准)
    4 X# g/ u, q1 t: R) k- n% R
  319. * Input          : None/ T9 u6 T+ J/ ?1 I& X
  320. * Output         : None
    2 e; H0 j, Q8 U' {
  321. * Return         : None8 F: L7 c( m* l) u& u
  322. *******************************************************************************/2 o$ j. s. q: G
  323. void ADC1_Configuration(void)
    % m% j, C- z. w" [$ n: Z: P
  324. {8 g7 k" g( e) {
  325.     ADC_InitTypeDef ADC_InitStructure;2 i5 B0 z2 j: B" Y- r3 t/ W

  326. ( g% o2 f" q1 z6 h( h
  327.     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    7 E3 G; E. Z: u- Q; G( f3 t
  328.     ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    0 R9 C& ~; a. M) o. Q/ x
  329.     ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  //连续转换开启
    ' ~5 i) Z6 T* d5 t4 [; R$ P
  330.     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    : @9 A+ ~( {5 v- E7 I
  331.     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;$ R0 T' j# J+ R% l4 b/ ?! X3 E2 z
  332.     ADC_InitStructure.ADC_NbrOfChannel = 2;     //设置转换序列长度为26 q$ ]! d4 p5 t! N8 t. G5 k- P' F9 u
  333.     ADC_Init(ADC1, &ADC_InitStructure);: V" n! _; F2 T' ]. Z
  334.    
    1 ^8 J1 d: _" U7 i/ P) W& x  F
  335.     //ADC内置温度传感器使能(要使用片内温度传感器,切忌要开启它)
    % G1 \5 B+ B- b7 S8 I. y
  336.     ADC_TempSensorVrefintCmd(ENABLE);/ Y8 C( x* K: Z
  337.    ! @, }* e3 |' y$ E' V. l
  338.     //常规转换序列1:通道103 d* H. L, F: g) [  h
  339.     ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_13Cycles5);# ?, H% ]3 K) H$ _: l& O8 M
  340.     //常规转换序列2:通道16(内部温度传感器),采样时间>2.2us,(239cycles)
    ( x) s4 K! ]5 Y2 R9 D' ?$ l
  341.     ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_239Cycles5);) a0 W: z0 R. L/ H
  342.    
    + N" R4 t/ ?' v
  343.     // Enable ADC1
    . i( {( ?3 X& D' Z  C
  344.     ADC_Cmd(ADC1, ENABLE);& K( }: U" \: U" Z9 T: `0 X8 r* }
  345.     // 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)- U8 J. h# }3 o- C- U
  346.     ADC_DMACmd(ADC1, ENABLE);
    6 M  Y; ]3 x) D) Z1 n, z' |! e
  347.    + m6 ]- k4 J: C0 i2 p
  348.     // 下面是ADC自动校准,开机后需执行一次,保证精度- i0 F$ b' d+ B+ l  L* ^* ?
  349.     // Enable ADC1 reset calibaration register+ N4 A0 w0 g& U; I# y
  350.     ADC_ResetCalibration(ADC1);$ |% }% j3 K6 j
  351.     // Check the end of ADC1 reset calibration register
    # ^% i5 i0 r4 j- M+ a# I' b
  352.     while(ADC_GetResetCalibrationStatus(ADC1));
    4 S4 }9 X  \6 q+ p) R5 u

  353. : U$ {5 ]% X8 \" z
  354.     // Start ADC1 calibaration
    " B' }1 x/ @, S# z/ W
  355.     ADC_StartCalibration(ADC1);, H2 {5 Q: J+ J8 L: n3 y' B
  356.     // Check the end of ADC1 calibration
    7 H$ S: t2 S& z& k9 m. Z% M9 D1 q
  357.     while(ADC_GetCalibrationStatus(ADC1));
    1 g, g5 H, V) u/ x
  358.     // ADC自动校准结束---------------! M& @8 a3 N4 @9 G7 A, F
  359.    & L) u3 e7 l& m  J/ {" X1 Z
  360. }
    2 e0 u2 |$ p: q/ g/ ~
  361. 7 N. Z' J; l7 ?# y, {
  362. /*******************************************************************************9 w* N0 o( L1 C5 v2 u. g8 x  I8 P# ?& W
  363. * Function Name  : DMA_Configuration2 \4 |4 |4 `) X
  364. * Description    : DMA设置:从ADC模块自动读转换结果至内存
    , |. K9 h; d! I2 O
  365. * Input          : None: G3 Q# ~1 F' x* g) H( E2 w
  366. * Output         : None' B2 w+ R6 \2 I" J6 Q9 B
  367. * Return         : None  \6 b" h2 ~0 ^/ P/ c- I9 t
  368. *******************************************************************************/* d+ D: g) w1 {5 a, r8 ]
  369. void DMA_Configuration(void)
    6 k* C7 d* }$ M; E! G$ x
  370. {! p; f: ^3 g: j# {( _* ]
  371.     DMA_InitTypeDef DMA_InitStructure;8 }4 e& g. c' Y- u$ B
  372.    $ y% y) U4 j: a, D1 e- X: t
  373.     DMA_DeInit(DMA1_Channel1);
    - h3 P- a9 `/ y0 D
  374.     DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;0 w7 q, c3 B! E" `
  375.     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&AD_Value;% o9 [9 [& ^/ P" ]0 P% G9 w/ P
  376.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;- w4 q+ E, T: C1 f8 k
  377.     //BufferSize=2,因为ADC转换序列有2个通道% @# k/ J% V3 f3 C7 s0 E
  378.     //如此设置,使序列1结果放在AD_Value[0],序列2结果放在AD_Value[1]
    ' O4 w. g$ j% b& V
  379.     DMA_InitStructure.DMA_BufferSize = 2;
    ' x9 V& E; l" {- q2 F3 |. s
  380.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;8 b8 ~9 b5 W) E* ~( ~0 Q
  381.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    ! a6 u. m- r8 a4 p" V
  382.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    9 n2 _9 k. O; Z# ^5 S$ L* m
  383.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
      s+ J1 |, K8 [7 }; d" m/ r
  384.     //循环模式开启,Buffer写满后,自动回到初始地址开始传输
    $ C- ]: \; e' h0 u; R% ]8 w( p# b
  385.     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    . T- M2 T4 ~  d/ Z
  386.     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    5 o% D. Q3 k7 C7 ~' g
  387.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;8 K$ v2 L! Q) W  G
  388.     DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    ( @3 H) f) I( X$ P
  389.     //配置完成后,启动DMA通道
    2 [0 Q- B, r2 s1 c# D$ s8 E7 K
  390.     DMA_Cmd(DMA1_Channel1, ENABLE);
    1 {( ?9 K1 D. u& ~9 [0 p+ C/ T
  391. }
    * j8 n: e; c: F; _3 U* G
复制代码

2 c9 v: I2 J8 Z3 l7 I2 k+ l4 `" u* A+ h$ P  m
收藏 1 评论0 发布时间:2017-8-29 14:48

举报

0个回答

所属标签

相似分享

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