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

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

[复制链接]
STMCU小助手 发布时间:2021-11-15 22:02
AD转换即模拟信号转换为数字信号,一般在单片机中模拟信号对应电压,通过ADC口将相应的电压转换为二进制的数字信号,从而推算出测得电压。下面我介绍下STM32中L0系列调用库函数来实现AD转换。
' D+ V% U: j0 G. k9 `/ e  ^/ E: m; B) i6 T
        首先最基本的AD转换模式,即单次单通道检测,且不用到DMA。L0系列一共有19个AD口对应19个AD通道,其中16到18为检测内部模拟信号的通道。下面代码中用到是PA0即对应通道0,具体代码如下图:
: L" p, U8 T+ v' a/ z6 @2 @7 ^; N# i" j
     
  1.   Adc_init()
    " A, h& D. L& B! i

  2. % p- t; x5 R# _# K* a" a" |) k% a
  3. {
    2 k+ y8 ]& u  Y/ _6 y; |) _
  4. __HAL_RCC_ADC1_CLK_ENABLE();
    ; B& t! d4 o5 d  a$ _; b+ \* B
  5.     AdcHandle.Instance = ADC1;' r3 D4 A1 \$ Z0 r1 _
  6. * e/ h  O- k) v3 ~# z/ w: g
  7.   AdcHandle.Init.OversamplingMode      = DISABLE;
    0 d) [; {+ w- l8 ]0 D; d- T
  8. . o( @) M, b; A
  9.   AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV1;3 |* C3 R& b3 Z
  10.   AdcHandle.Init.LowPowerAutoPowerOff  = DISABLE;
    8 X9 V0 }% z" I# k( ^7 \
  11.   AdcHandle.Init.LowPowerFrequencyMode = ENABLE;, Y- `- H. b4 l' c7 }/ }( W7 j: N
  12.   AdcHandle.Init.LowPowerAutoWait      = DISABLE;
    2 q+ b- g: q/ ^9 A4 [5 j8 |( Z

  13. / |4 A8 S) k  |! u5 ^2 O
  14.   AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;; p) A9 Z% u2 `4 U! F
  15.   AdcHandle.Init.SamplingTime          = ADC_SAMPLETIME_7CYCLES_5;; \5 \0 I- w6 N; g, v3 s
  16.   AdcHandle.Init.ScanConvMode          = ADC_SCAN_DIRECTION_FORWARD;
    ! \  _2 O8 w6 c
  17.   AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;& j2 z9 Q: b/ s! ?/ L
  18.   AdcHandle.Init.ContinuousConvMode    = ENABLE;
    ) i0 K; u2 e0 F" K, @  D# r2 f
  19.   AdcHandle.Init.DiscontinuousConvMode = DISABLE;
    - v2 z9 [; N  T3 l) t
  20.   AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
    - I2 s5 \' [9 l6 F1 x
  21.   AdcHandle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;1 P+ p1 ^+ g2 l  v
  22.   AdcHandle.Init.DMAContinuousRequests = DISABLE;
    % x5 o8 U* N7 n9 k, W& e

  23. % H, {! D4 M4 n# u  z
  24.     HAL_ADC_Init(&AdcHandle);
    / l4 t- H+ q' m7 X3 `
  25.     HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED);6 k! ?/ {+ Z# f2 l: ?
  26.   o3 r, D% |. p; P
  27. }6 I9 K: I; P, t6 E- o0 G; i
  28. 3 s3 m& ^: d$ O( \  Q8 [7 b
  29. //配置ADC初始化
    ; \3 w6 t% C' R( p
  30. # R  [' [( X4 m# ^
  31. void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)1 f  K' g! C. u  @8 Q: l
  32. {+ T$ y, F4 t& A+ z
  33.   GPIO_InitTypeDef                 GPIO_InitStruct;
    ' ?0 v0 i/ x6 r1 r# p  y" D. p2 T
  34. / A6 X  R, x' J
  35.   /*##-1- Enable peripherals and GPIO Clocks #################################*/
    + X2 P) m& T' Y1 }% z1 `
  36.   /* Enable GPIO clock ****************************************/
    ' o( E7 u) m! Y0 f$ a5 r
  37.   __HAL_RCC_GPIOA_CLK_ENABLE();
    5 f1 p7 t5 i" p0 v6 Y
  38.   /* ADC1 Periph clock enable */
    " O: j; k- {* G' _  z" {
  39.   __HAL_RCC_ADC1_CLK_ENABLE();+ M1 v# R$ [( e: h8 M: u

  40. ! b. {* w8 J) U" V7 b! x
  41.   /*##- 2- Configure peripheral GPIO #########################################*/
    1 u4 Z8 |9 o* e# u8 s, A
  42.   /* ADC3 Channel8 GPIO pin configuration */  O2 {/ K* z6 s  b8 M
  43.   GPIO_InitStruct.Pin = GPIO_PIN_0;4 z  R: C1 E( `6 @4 j  Q) |8 }  v
  44.   GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    # J% O. x0 T; E1 l
  45.   GPIO_InitStruct.Pull = GPIO_NOPULL;& y3 i# @7 s4 s3 F% i4 n
  46.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    0 Q) }9 p* |2 r; X" L
  47. }& Z, n7 g- X  M( @/ t4 v7 ?
  48. ) u9 \3 R: U% u4 x8 B$ S
  49. //初始化ADC引脚PA0,开启时钟
    ) v* K4 {; h. I7 T
  50. & u: P  s4 C! f( i
  51. void get_voltage(void)
    0 v7 K# ?* g: U( p6 S: b3 g
  52. {: X" m5 q) }, b, \' X
  53.           bsp_adc_init();
    : a, O3 y( }# _2 V6 J, V
  54.           HAL_ADCEx_EnableVREFINT();
    ( k6 E# M' i+ s* @1 [6 H
  55.           HAL_ADC_Stop(&AdcHandle);! Y5 r" t/ n) H: L: g$ a. }" a
  56.           AdcHandle.Instance->CHSELR=0;
    . G. C% ]. b+ H1 R8 d: ^! {" y4 e* V
  57.           sConfig.Channel = ADC_CHANNEL_17;         //通道17专门测内部电压值$ Q7 V! e: F4 Q3 q
  58.            HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);( w( B4 \* y: x, H( M
  59.             HAL_ADC_Start(&AdcHandle);
    , X+ ?" @) a+ o
  60.             HAL_ADC_PollForConversion(&AdcHandle, 10);    $ ~+ G5 {5 k6 u  n
  61.             /* Check if the continous conversion of regular channel is finished */
    : r2 _5 b5 U1 A
  62.             if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
    * e7 ~/ e0 l6 t; a/ v; e8 R
  63.             {
    0 s. g# Z/ u' ]' z  ?9 O
  64.                 /*##-6- Get the converted value of regular channel  ########################*/
    0 S0 Z# f& R) F( V9 l2 N2 U
  65.                 uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);& k0 v- g9 Z2 @( ]' V
  66.             }) Q& D7 B6 D, n( q5 |8 e5 n

  67. & a  r, E+ p% o
  68.             vdd_value=VREF_IN_VALUE*FULL_ADC_DIGTIL_VALUE/uwADCxConvertedValue;    //内部电源电压
    % d' b0 |8 H8 W5 s
  69.             HAL_ADCEx_DisableVREFINT();
    : M& V: S: [7 R; a; Q3 q! N, ]1 e
  70.             HAL_ADC_Stop(&AdcHandle);
    ; a9 t/ `* v4 M5 ^8 M3 C
  71.             AdcHandle.Instance->CHSELR=0;$ ], ?/ w- K, I
  72.             sConfig.Channel = ADC_CHANNEL_0;             //ADC0,去测外部PA0口接的电压* b% \/ I' W' k" e6 J. p* T
  73.           HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);3 j( e7 A& D- ?, e7 {4 v3 s8 u
  74.             HAL_ADC_Start(&AdcHandle);( Z- Z8 N  ]6 P; s! T
  75.             HAL_ADC_PollForConversion(&AdcHandle, 10);   
    7 {5 D- |8 v; f' n
  76.             /* Check if the continous conversion of regular channel is finished */
      p, a- C& X; x; H3 g. }
  77.             if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)2 y  O' d4 `  I, i/ @
  78.             {0 ?+ v! S* B4 C# ?
  79.                 /*##-6- Get the converted value of regular channel  ########################*/9 Q+ F3 W8 d( Y7 V% c4 }
  80.                 uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
    - n6 [' i9 ^4 M2 T% X
  81.             }
    4 R, y: I& v8 ]/ Y3 l, G5 c
  82.               //直接获取的是二进制码,14位对应最大值4095,内部电压为vdd_value通过比例计算得到电压数值/ c7 V; D1 g8 J5 |# V9 k$ H
  83.             temp_voltage=(float)uwADCxConvertedValue*vdd_value/4095;( T" k! P, u: q. m; g: ~
  84.              //得到浮点型电压值            是乘了1000倍的            . }" z( Q8 T/ {0 {* S
  85.             HAL_ADC_Stop(&AdcHandle);) r* c! A- |1 [0 O, p" J2 l. T
  86.             //HAL_ADCEx_DisableVREFINT();2 i' C* a( H6 B7 O, x$ n
  87.             __HAL_RCC_ADC1_CLK_DISABLE();7 d) b8 i; ^0 x3 M) l3 y
  88.    }. L9 r9 o% L7 K
  89. }
复制代码
, h- U" Y- P2 F: u6 i: l; ~
* t3 Q! ~, u: [
  以上ADC检测,相当于一次连续检测了两次,第一次为内部电压用的特地通道17,第二次检测的是外部电压对应硬件连接的PA0对应通道0+ @1 [3 ^; M6 B( K' K* B8 m; V* b
; `6 w8 F; M: U
7 _4 F$ C/ Q1 C& \( N# \0 y0 a
收藏 评论0 发布时间:2021-11-15 22:02

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版