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

【经验分享】STM32L0系列的ADC用法

[复制链接]
STMCU小助手 发布时间:2021-11-15 22:02
AD转换即模拟信号转换为数字信号,一般在单片机中模拟信号对应电压,通过ADC口将相应的电压转换为二进制的数字信号,从而推算出测得电压。下面我介绍下STM32中L0系列调用库函数来实现AD转换。+ M$ s7 h; g( E, P* G- z# K
$ d' m2 e2 k# }1 X. I
        首先最基本的AD转换模式,即单次单通道检测,且不用到DMA。L0系列一共有19个AD口对应19个AD通道,其中16到18为检测内部模拟信号的通道。下面代码中用到是PA0即对应通道0,具体代码如下图:: C# C  x, x. {" j2 d' c2 f. e

# p+ M% z+ y' V     
  1.   Adc_init()
    8 U2 Z' G1 m  R+ x# u6 n
  2. 3 g" z3 S) ?/ r" H5 C5 a& e+ F
  3. {7 o9 R% z+ w3 x' F6 N# h
  4. __HAL_RCC_ADC1_CLK_ENABLE();
    8 O2 B) ?0 l. J3 `/ B2 E& a( J
  5.     AdcHandle.Instance = ADC1;
    * T' ?* U' K1 y
  6. - b  e$ W3 s$ @* p# B
  7.   AdcHandle.Init.OversamplingMode      = DISABLE;1 {  _% e) Z& u( v- f6 P7 M4 M

  8. " H7 J) N% I( G7 {: [; M2 Q. Z9 K
  9.   AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV1;8 J6 S7 o# N# d: f
  10.   AdcHandle.Init.LowPowerAutoPowerOff  = DISABLE;
    . p; {$ M  I( n1 }  E+ `  o) d
  11.   AdcHandle.Init.LowPowerFrequencyMode = ENABLE;7 N2 @* e7 U6 H5 d! N0 O
  12.   AdcHandle.Init.LowPowerAutoWait      = DISABLE;, ^% x! S/ m' N$ E- Z
  13.   Y( V2 v4 F; ~( @8 a1 x* A5 i! S
  14.   AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;2 S7 E: ]+ W# x' V& a
  15.   AdcHandle.Init.SamplingTime          = ADC_SAMPLETIME_7CYCLES_5;; S1 |  [  D" f( I. O
  16.   AdcHandle.Init.ScanConvMode          = ADC_SCAN_DIRECTION_FORWARD;, D3 }5 c* G" V) \0 N) Q: i1 O4 W1 s9 D
  17.   AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
    : O" R0 \' H0 F3 V/ O
  18.   AdcHandle.Init.ContinuousConvMode    = ENABLE;
    ' w" a  A$ l/ B$ F* K5 o. [
  19.   AdcHandle.Init.DiscontinuousConvMode = DISABLE;
    $ i. F6 }4 w. s3 O
  20.   AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
    1 a4 T) O# R  Y% f) q# r5 P! H4 B# S
  21.   AdcHandle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;
    / v) @$ Y+ {" h4 `# |+ t
  22.   AdcHandle.Init.DMAContinuousRequests = DISABLE;* t% v  E5 L& p8 a) R
  23. . P6 @! s1 f* Z, p
  24.     HAL_ADC_Init(&AdcHandle);& f4 c& n; J8 h; Z) ~
  25.     HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED);
    9 b( V7 h! X: v, X4 L

  26. & P' S" Y5 o- t- u+ k4 S" J! l
  27. }
    . w/ I0 ^% e' P- I: O
  28. 8 [% ^* Y) e$ p8 G2 S7 z) s
  29. //配置ADC初始化. C8 a8 B7 @- m2 ]# V

  30. . S/ g% R, |8 s0 i2 h; Z9 W+ c; L. {- T
  31. void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
    ; q; x* @( e- Z. z
  32. {6 t9 `" o; t. {
  33.   GPIO_InitTypeDef                 GPIO_InitStruct;
    4 Z* `( C' U" I

  34. + o" n- W: L2 R- L- x
  35.   /*##-1- Enable peripherals and GPIO Clocks #################################*/
    $ [, R/ z1 N/ w$ }' R8 J1 G
  36.   /* Enable GPIO clock ****************************************/6 M9 R# U- W8 r
  37.   __HAL_RCC_GPIOA_CLK_ENABLE();
    + P" q8 [5 O( ]6 H1 p' g
  38.   /* ADC1 Periph clock enable */! ~! n0 b! d- H8 G$ S/ X# v
  39.   __HAL_RCC_ADC1_CLK_ENABLE();
    9 j( p8 v2 v8 Y+ `" v( i% W, R
  40. 7 u4 f# C7 D6 R2 s3 E" g& q
  41.   /*##- 2- Configure peripheral GPIO #########################################*/
    " h" _! M# s/ q6 A
  42.   /* ADC3 Channel8 GPIO pin configuration */
    # {; z. O7 ]7 x2 ~
  43.   GPIO_InitStruct.Pin = GPIO_PIN_0;) T5 P$ ?! f( D1 K9 ]6 B1 a# x6 [
  44.   GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;* Q% p& c0 d7 ^/ p: s: L
  45.   GPIO_InitStruct.Pull = GPIO_NOPULL;" a: p& O9 d0 P+ G3 I  S% |4 C
  46.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);1 R$ c. v' @* l* R
  47. }
    " C* ]2 L, A! g
  48. ; }. u& q, l. q# s+ Y/ P
  49. //初始化ADC引脚PA0,开启时钟
    0 G# Z( ^- y6 h# i
  50. % M- o/ }: M* t
  51. void get_voltage(void)
    ( r4 F4 z+ n. I  @5 h$ q* {
  52. {8 V0 U" O1 d  f5 z7 c# M; [
  53.           bsp_adc_init();% a2 u! T0 F! i( ?0 B
  54.           HAL_ADCEx_EnableVREFINT();
    ; F, Z2 ]8 b( W( @+ l0 |
  55.           HAL_ADC_Stop(&AdcHandle);
    ) h- e; \. \. g( I7 N
  56.           AdcHandle.Instance->CHSELR=0;
    ( h# {3 Y& }7 C' }5 T0 b- D
  57.           sConfig.Channel = ADC_CHANNEL_17;         //通道17专门测内部电压值
    9 h: u  w9 {. h  h& p, p
  58.            HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);: d% ?* G6 i4 k
  59.             HAL_ADC_Start(&AdcHandle);
    8 P) h( H, v/ k' i, T5 v# l) o
  60.             HAL_ADC_PollForConversion(&AdcHandle, 10);    / _3 n5 E: x) ?8 J
  61.             /* Check if the continous conversion of regular channel is finished */
    7 _( B2 T2 P  m) \/ _- ]
  62.             if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC). R! U% Q2 c2 ]& {7 t: e/ F
  63.             {
    ; ^/ I. [: s/ @1 s. p% J; S
  64.                 /*##-6- Get the converted value of regular channel  ########################*/
    - h' b& q: m+ v8 R' S% n
  65.                 uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
    % v' O8 i6 M( \- }' W
  66.             }
    / s& `2 j; F2 q3 e

  67. 9 ?* a" N  d( |8 o+ d' c
  68.             vdd_value=VREF_IN_VALUE*FULL_ADC_DIGTIL_VALUE/uwADCxConvertedValue;    //内部电源电压
    $ C$ z8 A* N; J/ A6 o
  69.             HAL_ADCEx_DisableVREFINT();& J1 W1 c6 Q% m3 z, K1 E& z
  70.             HAL_ADC_Stop(&AdcHandle);' W: t* L) O4 H5 {
  71.             AdcHandle.Instance->CHSELR=0;; R# m9 w6 b% k" d
  72.             sConfig.Channel = ADC_CHANNEL_0;             //ADC0,去测外部PA0口接的电压; L4 x1 N9 r4 X4 h$ d" t
  73.           HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
    . ^" n$ ^9 @8 I# y
  74.             HAL_ADC_Start(&AdcHandle);
    % D5 T/ X8 h: O7 F  g: @9 t
  75.             HAL_ADC_PollForConversion(&AdcHandle, 10);   
    4 _. N. s9 G9 S, Y3 X
  76.             /* Check if the continous conversion of regular channel is finished */
    : U0 L; R# z, w
  77.             if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
    : c- F  }3 r! j! i$ w1 U
  78.             {
    8 F2 l3 _1 [$ l- `$ G3 g( m7 `) n: N
  79.                 /*##-6- Get the converted value of regular channel  ########################*/
    . Z  N9 B6 E/ R2 f
  80.                 uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
    ' V7 h3 F2 v. _% [) F
  81.             }  I0 h2 N) v7 ~- S
  82.               //直接获取的是二进制码,14位对应最大值4095,内部电压为vdd_value通过比例计算得到电压数值6 p0 ^; K7 N2 D) ?# C( h
  83.             temp_voltage=(float)uwADCxConvertedValue*vdd_value/4095;
    " E' g9 A7 a5 i0 s  X# l$ S
  84.              //得到浮点型电压值            是乘了1000倍的            
    " `4 z  W. y" l6 o# D7 Z! \! Z2 H
  85.             HAL_ADC_Stop(&AdcHandle);! [5 @4 L8 p2 D& I8 X% [; P
  86.             //HAL_ADCEx_DisableVREFINT();5 }0 n  `" m1 A( l  w3 J( N! A5 V
  87.             __HAL_RCC_ADC1_CLK_DISABLE();
    & ?* @  q# i) g5 L/ Y+ B6 |& J$ X
  88.    }
    : p% r, s( K* R# r! S; H
  89. }
复制代码
6 A# n+ k; ]5 ]5 E( d

: |! I* z  X8 Q$ c  以上ADC检测,相当于一次连续检测了两次,第一次为内部电压用的特地通道17,第二次检测的是外部电压对应硬件连接的PA0对应通道0
6 b# V4 x& |: @( w. v
4 ^  j3 b5 J' M: S$ F
+ |7 h7 Q- S2 x' o! \- j; N0 C
赞 收藏 评论0 发布时间:2021-11-15 22:02

举报

0个回答

所属标签

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