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

【经验分享】STM32L0系列之ADC采集

[复制链接]
STMCU小助手 发布时间:2021-11-15 22:02
STM32L0开发系列——01 ADC采集
% b" Q' `' s/ Q' ~前言3 k& b- m/ f: ]# A
使用芯片:STM32L051C8T6
4 q5 Z1 Z  f# c/ u( ]. x' u' h软件平台:KEIL V5、STM32CubeL0; W6 c9 R' G; z6 W7 D
库函数:HAL
( H. N9 D' J' c7 h7 w. ?7 ~+ G2 a8 |8 U
一、原理图
& K& e  E6 q, e1 c' W  N本文介绍在STM32上使用ADC1的第1通道,对电池电量进行采集。
; W1 q' K- X5 S+ P6 `
+ ?7 s& b, u# W
20190521154130328.png
9 |8 W: U$ c" m" I, L
' W( \* J, v  G) h
二、ADC通道与引脚对应关系" y- ?9 K$ U; g: i8 j
$ T2 F, i2 z2 g3 ^
_(KN]~}EBE`QX(}_V8}K%(1.png
5 T5 G4 [+ q9 ~: C' L
}U8X{E0K8E$YC3O(VLM3]QH.png
5 I, I5 S6 p% j3 v  E( l

' {5 {6 m4 n) y, O: P$ l* ?三、ADC相关5 @% p: N* `! P7 r7 c
1、 ADC 可由 APB 时钟或 HSI16 时钟提供。; |+ s& [/ e3 S* P/ h
2、 ADC 转换时间: 12 位分辨率对应的转换时间为 0.87 µs (1.14 MHz), 10 位分辨率/ U& K: i& V# m+ K
对应的转换时间为 0.81 µs,若降低分辨率,可进一步缩短转换时间。& H0 k7 F) z" N# q8 K/ R& B' r

! p4 f7 C8 y$ {5 Z! s+ g" L四、实验步骤  L3 a- k5 X* W' S6 J8 ^& W* {& S
1、系统时钟配置+ O  h3 i3 m2 e, v  ?1 C) ~

8 `& d+ b. d* ?6 w% L: G0 `8 i, A
  1. //******************************************************************************            : ~& ?% H+ J6 o3 [1 K, y  H- c: C
  2. //name:             SystemClock_Config           & R7 p. t6 s1 y% \
  3. //introduce:               系统时钟配置        . W4 R. ?$ B; `. n+ X
  4. //parameter:        none  . n4 K3 A# Q6 r/ y" R$ Z" Z% F
  5. //return:           none         5 @0 r+ t! L+ T7 c* b" u0 h! {3 B
  6. ; e( x1 _2 ?+ b( s- T' i
  7. //changetime:       2019.05.21                     
    ) r4 V: k) A2 E
  8. //******************************************************************************1 y  A: w+ B5 P6 K3 v, s* m' {
  9. void SystemClock_Config(void)& o& Z/ p1 |0 s4 p' [
  10. {
    ' J+ @, U: x, b- A8 Q8 t

  11. , L+ v; k% a" ^1 q- s/ g: X" k
  12.   RCC_ClkInitTypeDef RCC_ClkInitStruct;6 P, x2 k( C3 f! U/ j
  13.   RCC_PeriphCLKInitTypeDef PeriphClkInit;1 i9 P% a) b( p; d4 [
  14.   RCC_OscInitTypeDef RCC_OscInitStruct;
    4 ], w) [+ x' u& q* D: S$ `5 G* w

  15. ! H/ N2 c7 Y1 ]. g9 q' f7 A; A
  16.   __PWR_CLK_ENABLE();3 q; w, Z2 @: S  E
  17. 1 N$ u9 X9 K7 W! O( L4 s
  18.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    7 q% K7 ]  O; M+ D# L! ]6 p; @

  19. + a1 G2 E" Y8 |" I
  20.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;1 t. |: Z2 F& D( l+ c4 a" }! ?
  21. * `% d) [1 l& I
  22.         RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    0 Q8 x( j, h4 z4 f0 H
  23.   RCC_OscInitStruct.HSIState = RCC_HSI_ON; //ADC的时钟源5 @1 l+ ^/ Z: g) U6 d6 d
  24.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;2 |0 P' H  n3 J& e
  25.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    & s5 \, r' i3 s# j' P
  26.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8;
    ; q" ^# p, e! C
  27.   RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;
    $ c" C, e1 M1 G( a- Y+ w. Z% g
  28.   HAL_RCC_OscConfig(&RCC_OscInitStruct);/ s( l0 e' b+ m. x- {+ g0 p( `; W
  29. 9 i) S1 H. ~. e$ e; y
  30.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK3 C5 s  z9 }3 a: m5 C  z
  31.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    ( F/ j1 ]! f2 O+ a$ G
  32.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    - ~' z2 V, d5 c9 m
  33.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    0 Y* ]6 h! T" L8 B6 W  P
  34.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;5 b2 B* v3 ]  q! W( o1 ?
  35.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;7 s/ r$ J( k! G
  36.   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
    ( i: K8 G+ }: c
  37. 7 S' m' c! ^6 ~) I: z5 Q
  38.   PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
    + c6 e) N: _7 s* a
  39.   PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;( j$ x' n# f! }  H( H8 M6 G
  40.   HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);% u( c" s( A, D( P7 ~; O5 ?
  41. . q% |# {; I2 |; Z) \* S5 o4 L# @
  42.   __SYSCFG_CLK_ENABLE();
    2 B8 D6 v# ^# n4 q' M& O2 U
  43. ) O7 e4 v  v0 y' M
  44. }
复制代码
% P4 Z7 w2 H( I
注意:一开始程序中没有配置HSI时钟,采集不到电压2 P6 P7 Y& O3 f9 p+ g3 b" F
" m* o9 q: e7 ?! S2 _
2、ADC文件
6 F' k6 d6 D2 G5 y  D9 u( \! v& ~' I! u
( ~, I: k: w0 o7 l# b1 u7 z7 D# Y, A8 r
  1. #include "main.h", B; h# v: D: Q; f0 H! x
  2. 0 `& [! r" v) ~0 m5 M
  3. ADC_HandleTypeDef hadc;
    ; T- o0 }! _5 W& k# x2 U3 l
  4. GPIO_InitTypeDef GPIO_InitStruct;
    / [- N' y1 v5 k" ^% D6 Y
  5. ADC_ChannelConfTypeDef sConfig;' Q3 U* a" V2 [) L1 D# _9 R- s
  6. ( _# u9 C; S* J; v& w
  7. # G! l5 `' h/ a. O& @
  8. //******************************************************************************            & l5 m3 A+ E7 W9 l7 }
  9. //name:             ADC_Init           . Y7 m" B; s/ I9 V5 d
  10. //introduce:               ADC初始化       6 t2 v6 _( D1 R8 |
  11. //parameter:        none  
    * d8 g2 g2 u" K/ {. s# w/ l
  12. //return:           none         ) k6 ]: G/ B" @  z* K; p( ]
  13. 6 I- J) C4 R- m1 X8 m( t
  14. //changetime:       2019.05.21                      ( {8 A, c! B# a  p7 F9 C- j
  15. //******************************************************************************( P& r2 A7 u& b3 D+ c- s+ E% ~8 }
  16. void ADC_Init(void)
    9 j2 ?! e9 H: _0 V' u
  17. {8 l9 g3 y) i, v/ B* @& s
  18.         uint32_t Calibration=0;  q( X5 |4 y7 v6 h  L
  19.         ! ]4 ?0 H! e- F: r6 z  u9 z' b) t* V. G
  20.         __HAL_RCC_ADC1_CLK_ENABLE();: t, p/ J8 P; z2 G9 U; v
  21.         __HAL_RCC_GPIOB_CLK_ENABLE();
    8 R/ N  Y3 Z" U. ?/ G
  22.         
    2 z. d  L' S# y* u, L% |$ T
  23.         GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
    ( G6 |  m; N% R( }  D
  24.         GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;+ Z$ C! Z1 _* t7 Y' F, s
  25.         GPIO_InitStruct.Pull = GPIO_NOPULL;
    ' j9 k' x2 s" g4 Z( j
  26.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);! W+ Q% M  t+ O& V; c: X1 f8 v
  27.         
    1 @% E! X7 @% H: L( Q3 F
  28.         hadc.Instance = ADC1;
    0 w6 I8 l9 f0 D% {+ n0 F
  29.   hadc.Init.OversamplingMode = DISABLE;
    * I5 i* }7 _/ g# t
  30.   hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;: z; R! C' B7 p  c' _) _
  31.   hadc.Init.Resolution = ADC_RESOLUTION_12B;. b/ M+ }0 v9 H. N# E- m
  32.   hadc.Init.SamplingTime = ADC_SAMPLETIME_79CYCLES_5;7 M; Q8 x' p# B' Z* T8 G9 [
  33.   hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
    * s- _7 z- H& q* m- T
  34.   hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    , p* Z& ^/ \% @1 s
  35.   hadc.Init.ContinuousConvMode = DISABLE;7 n% C+ ]; \4 a( Z
  36.   hadc.Init.DiscontinuousConvMode = DISABLE;
    # X% G. R; v# ?4 Z/ R4 k" [
  37.   hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;% {& _0 o' d3 G
  38.   hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;. u& F) t3 K' W$ C) ]
  39.   hadc.Init.DMAContinuousRequests = DISABLE;
    # o9 ]. S: o0 F' H2 s
  40.   hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
    ( H+ T& ?3 H  |, y0 r0 y
  41.   hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;8 T* a) u$ A; i& E
  42.   hadc.Init.LowPowerAutoWait = DISABLE;
    1 Q2 r* j" H& N% ~' U- {
  43.   hadc.Init.LowPowerFrequencyMode = DISABLE;
    . k4 Q& B4 E" b1 i8 t* [/ h: z
  44.   hadc.Init.LowPowerAutoPowerOff = DISABLE;
    : j5 Q% m! A( q9 v7 N% z( q
  45.   HAL_ADC_Init(&hadc) ;
    ( Z( H" K4 \- x. t
  46.           M( D, F7 a; P( B$ b: q6 _
  47.         //启动ADC校验功能# I; l& m& p) ?7 P& v0 i
  48.         HAL_ADCEx_Calibration_Start(&hadc,ADC_SINGLE_ENDED);
    4 ]: ~) o# T5 E' ?+ O% P
  49.         //获取校验值" z4 }( C* `1 P$ P0 c1 J) [
  50.         Calibration = HAL_ADC_GetValue(&hadc);
    $ f% P4 p; y+ r1 Q! P
  51.         7 b  d" M( v. U! C5 G7 K
  52.         // 清除之前通道9 e4 ^: z; [6 Y5 l* W- r
  53.         sConfig.Channel = ADC_CHANNEL_1|ADC_CHANNEL_2|ADC_CHANNEL_3;
    0 D. g( U; Q& f8 J3 f/ K" z3 x
  54.           sConfig.Rank = ADC_RANK_NONE;        // 清除通道属性4 r. O9 X' I$ J" g6 v/ {1 R
  55.         HAL_ADC_ConfigChannel(&hadc, &sConfig);
    5 u. n- K  h7 L' H+ n

  56. ! n. }2 b& C$ l' |! t, I
  57. }
    2 K2 H5 Q: x- _9 p3 M, I

  58. 9 F7 C4 W- I" H* C( c
  59. //******************************************************************************            - A; R3 B" M+ b. v. c$ H% v  s3 Z
  60. //name:             GET_ADC           
    / z; L6 u3 w5 {# h
  61. //introduce:               单通道采集ADC的值       & n0 k* ?4 d* i
  62. //parameter:        CH:ADC采集通道
    - q& x( m) R' i3 y' W! Z* V
  63. //return:           ADC采集值         % \( G2 F% L" @8 j' G# @

  64. 3 d5 G) v9 T" |
  65. //changetime:       2019.05.21                      1 B! M  u9 j  g/ J/ e
  66. //******************************************************************************
    ' c1 r6 M) v3 f8 ~* J" i! I
  67. uint32_t GET_ADC(uint32_t CH)# A5 r1 C# V% [. M6 ?5 z% M
  68. {) n* U, a2 d. [8 o& {
  69.         uint32_t adc_conv_var;2 T9 R8 N6 \& H7 m( y7 p
  70.         sConfig.Channel = CH;3 e& o/ m6 |8 u& U
  71.         sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;        // 设置通道* q) w, T' H! V& f3 ~9 Q9 B- G
  72.         HAL_ADC_ConfigChannel(&hadc, &sConfig);- ]& u& Q+ S. F$ O- O
  73. 5 f6 _4 W  g$ p1 \  H- ~/ Q1 p, |
  74.         // 启动转换
    # z4 n$ J# L6 E2 q
  75.         HAL_ADC_Start(&hadc);
    6 k* V: K1 s, k- x+ m5 A5 U% H
  76.         ! m0 F2 w* W0 @5 a# V& T% T$ T
  77.         // 等待转换结束; n# v; Z& P' x1 C+ K5 j
  78.         HAL_ADC_PollForConversion(&hadc,20);// 超时20ms9 e; J5 ~& M% U% N
  79.         2 A- o) R3 \9 K4 f+ [/ l
  80.         // 读取结果
    7 |, P& ?5 p# _
  81.         adc_conv_var = HAL_ADC_GetValue(&hadc);
    7 v0 C5 b5 L* Q& ?1 C: K
  82.         
    % n1 C0 V0 S4 @( S# K- x8 I
  83.         // 清除通道3 I$ D' l' p/ w/ ~1 S
  84.         sConfig.Rank = ADC_RANK_NONE;        // 清除通道
    ' Y: O. Z/ W0 b  {  |; C
  85.         HAL_ADC_ConfigChannel(&hadc, &sConfig);
    / o. ~3 P# @0 O  A# O
  86.         1 X+ f  Q1 E7 u8 d  u+ R7 P
  87.         return adc_conv_var;) x( H: |0 W6 x3 ]/ d/ B
  88. }9 k- ~' j) }# H, i
  89. 2 r3 f" X- _4 e* o: U- Z) t
  90. //******************************************************************************            
    # O2 R2 A3 e4 ?% z( h  }
  91. //name:             Get_Adc_Average         
    " C: n# }* P  ?: K- j0 E
  92. //introduce:               多次采集求平均值      
    6 f$ S" _4 }. G9 j9 l: o
  93. //parameter:        CH:ADC采集通道
    0 Q! }5 k8 r2 W1 N: B
  94. //return:           ADC采集值         ! w/ n( Z  |: T' q2 P

  95. 9 g$ @: T; U  {* i
  96. //changetime:       2019.05.21                      ! S8 U9 R4 ]7 [4 F0 \* X* e
  97. //******************************************************************************
    ; f8 E' m2 W- ^; u4 d% f
  98. ' R9 C$ g3 z- ^' X
  99. void Get_Adc_Average(uint32_t *ch,uint32_t *adcx,uint8_t times)
    8 O$ l8 Z5 y1 f
  100. {. P9 M. O; T3 ~# Z1 C6 {
  101.         uint32_t temp_val[9]={0};
    - l7 V2 [# z! a- p' {/ ~% @( b9 H
  102.         uint8_t t,i;
    4 j9 a* Y" H% J0 e, \) ~3 O1 T4 i7 H
  103.         for(t=0;t<times;t++)
    3 \+ R1 A+ Y: ^2 E
  104.         {
    5 I/ j4 A% l3 d0 f- h
  105.                 for(i=0;i<9;i++)
    " J6 `1 w! V( B8 O0 x
  106.                 {2 j) a" ^8 C2 g) ~& h+ l4 C
  107.                         temp_val<i style="font-style: italic;">+=GET_ADC(ch);, w3 \+ ~" I. G7 j3 r" N
  108.                  </i> HAL_Delay(5);
    ( f- k3 ?" n( y9 o. p
  109.                 }
    ) R. `+ P" A, d* h
  110.                
    $ y8 I- y$ c+ ^, E" x- h: w3 C
  111.         }' }' R% ?4 x0 f; ~
  112.         
    6 q% S' u# m8 l/ b8 ^
  113.         for(i=0;i<9;i++)4 R* K; D; K" W$ ~! X! k* _. D
  114.                 {% q# \2 g6 D, D- R+ y2 i8 j+ K+ u
  115.                         adcx = temp_val/times;9 Z& E: m- n) f; L/ b( \
  116.                 }# }  _* y8 `' \9 U
  117.   N. n% B/ z2 o7 _7 O4 F5 C+ s/ _
  118. }          ( m: b6 H' C* _2 j) k' i+ H
复制代码
: {; T/ u; P* z9 ]  c
3、main中测试4 A, o1 l! p" {2 K- R4 }4 x
  1. while(1); U1 t: Y1 o. L8 P
  2. {
    # E# e, g' U6 y
  3.         BATTER_VALUE = GET_ADC(ADC_CHANNEL_1);4 Z. N9 i$ ^6 M
  4.         temp=(float)BATTER_VALUE*(3.3/4096)*2;        
    3 S& r$ u+ K" M4 g: t
  5.         printf("temp=%0.2f\r\n",temp);, ^5 a4 _& q, Q, m1 N5 }$ F# d
  6.                         
    6 x) h2 ?  q2 b5 ], r% S
  7.         HAL_Delay(100);
    ; @, `8 y  _) z, x4 _
  8. }
复制代码
$ f  R0 y( |: n" x3 g6 \+ [

6 N$ A' y- [4 h( j, O四、实验结果; q) ?9 \1 U& k
) \+ p5 N# @6 _7 g0 \! w6 m
由于ADC的精度是12bit(4096)、参考电压为3.3V,因此实际读出的电量值为BATTER_VALUE3.3/40962.! w" `% G$ _  u7 `* w* m- {( q- p
试验成功
. ^* }9 K" f3 t2 h% P- c1 b+ _5 x, }2 H+ W# T: v

8 H# Q8 f7 A$ w1 \
  \7 Y8 J& D' H8 V) X4 r9 V9 H0 v
20190521162423578.png
赞 收藏 评论0 发布时间:2021-11-15 22:02

举报

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