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

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

[复制链接]
STMCU小助手 发布时间:2021-11-15 22:02
AD转换即模拟信号转换为数字信号,一般在单片机中模拟信号对应电压,通过ADC口将相应的电压转换为二进制的数字信号,从而推算出测得电压。下面我介绍下STM32中L0系列调用库函数来实现AD转换。* P3 h: W. L8 \( o' v
- D2 R- @8 h- k) L" o
        首先最基本的AD转换模式,即单次单通道检测,且不用到DMA。L0系列一共有19个AD口对应19个AD通道,其中16到18为检测内部模拟信号的通道。下面代码中用到是PA0即对应通道0,具体代码如下图:
2 [" v0 w  @, O! p1 r$ I! a! ^) q5 P) c
     
  1.   Adc_init()+ S) \# q: [' L8 o7 v' J

  2. ( }+ J6 d( g8 n& d, M2 v8 k8 _) h
  3. {4 q0 u5 ]# \+ d; i  b9 o) X2 X
  4. __HAL_RCC_ADC1_CLK_ENABLE();( k( b+ W& L' t+ N& \/ c
  5.     AdcHandle.Instance = ADC1;" j# u% ~+ I4 Y" b2 C; |- U& R. }: S
  6. 4 i8 M* P# r5 i0 b. T: T
  7.   AdcHandle.Init.OversamplingMode      = DISABLE;- S! R! q' s$ I3 r! t

  8. 5 a- X$ Q# L7 r6 d; ]
  9.   AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV1;
    0 y0 j' d5 X1 G
  10.   AdcHandle.Init.LowPowerAutoPowerOff  = DISABLE;6 x; w$ ~4 \9 p
  11.   AdcHandle.Init.LowPowerFrequencyMode = ENABLE;
    7 @9 O. y. H0 s% K1 J: W
  12.   AdcHandle.Init.LowPowerAutoWait      = DISABLE;
    9 L+ E, S1 H8 k
  13. 3 \' ~. ^: v' Z0 p7 |5 o
  14.   AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;
    4 k1 }1 d) W' o" m
  15.   AdcHandle.Init.SamplingTime          = ADC_SAMPLETIME_7CYCLES_5;' V# U1 G' `7 F' e% `, @$ G3 O
  16.   AdcHandle.Init.ScanConvMode          = ADC_SCAN_DIRECTION_FORWARD;, H# m  q1 p* [% _1 ~/ f
  17.   AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;! V+ ]& ^* D: P9 B$ F7 G
  18.   AdcHandle.Init.ContinuousConvMode    = ENABLE;
    2 S: O7 E0 [4 m$ M" s" Y3 B
  19.   AdcHandle.Init.DiscontinuousConvMode = DISABLE;
    ! Q$ A% L. [& ~0 `' C
  20.   AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;$ B4 ^  t# M/ n& j/ Z- s* v' d
  21.   AdcHandle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;1 u4 V! t. }$ e; f4 L
  22.   AdcHandle.Init.DMAContinuousRequests = DISABLE;
    % F2 \8 z6 |: ~
  23. 0 k- b1 J% a" B7 Y) g8 ^, |
  24.     HAL_ADC_Init(&AdcHandle);" o( t; Z6 g. m  {2 T$ {
  25.     HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED);
    ! ~* Q7 j9 i$ O0 A$ Z$ \. G

  26. $ y; R' J  X1 q) s  J
  27. }" k$ D& m0 _8 ^; H

  28. 0 y( c" N% \' E: f- n1 [! A% \
  29. //配置ADC初始化' q- M' x$ b+ v) D8 @
  30. ! N, m! D5 V, M' q
  31. void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)8 w+ Q; C( S  {
  32. {
    % h7 e1 F, q6 [+ p, O9 \$ ~
  33.   GPIO_InitTypeDef                 GPIO_InitStruct;$ a0 l  C" s" P9 M# ], T6 j
  34. * t& l# t% W0 o  Y
  35.   /*##-1- Enable peripherals and GPIO Clocks #################################*/
    5 _- u; S2 Z6 P, k0 \- M
  36.   /* Enable GPIO clock ****************************************/; q, w4 s5 C; d  t: t1 Q
  37.   __HAL_RCC_GPIOA_CLK_ENABLE();
    / B( R& R- w  U3 M
  38.   /* ADC1 Periph clock enable */
    8 u% s) \5 q9 A! Y
  39.   __HAL_RCC_ADC1_CLK_ENABLE();
    $ R+ e% ^7 W! ?- T

  40. 2 M# l  u& s6 f: Z$ P
  41.   /*##- 2- Configure peripheral GPIO #########################################*/# I2 |' O- I, e$ E
  42.   /* ADC3 Channel8 GPIO pin configuration */3 E" P- V4 y  r$ {# e1 e0 \* F
  43.   GPIO_InitStruct.Pin = GPIO_PIN_0;
    5 s* P* b: e- J7 |& W! v& o3 G2 E" b
  44.   GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    / p4 _0 W' ^! W9 v! }4 V0 T- N
  45.   GPIO_InitStruct.Pull = GPIO_NOPULL;) Y$ `+ |" i2 O& T3 y
  46.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    & V/ H+ v: M0 ]+ _: V/ L
  47. }/ z3 B: F; n% R1 v) \- g: G" \3 M$ V) Z
  48. 4 f4 C# O6 K+ [' v) B7 T
  49. //初始化ADC引脚PA0,开启时钟: [  H/ V- {$ e: X
  50. ( Z* |. b. ?; G4 |
  51. void get_voltage(void)
    $ [1 P5 X+ }5 S
  52. {& j$ K2 I' `  U7 `) r- \% a+ {
  53.           bsp_adc_init();
    & Y5 v) l  y. a) q
  54.           HAL_ADCEx_EnableVREFINT();
    4 {, f0 S7 ~' c! y9 j0 ?# D
  55.           HAL_ADC_Stop(&AdcHandle);
    " V" ?/ {5 h! U; ?  \5 i
  56.           AdcHandle.Instance->CHSELR=0;
    7 \& N8 O' K4 U$ P- j
  57.           sConfig.Channel = ADC_CHANNEL_17;         //通道17专门测内部电压值
    + W' y1 {2 N* b( C  o
  58.            HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
    , t  o: f3 F" g- V& U
  59.             HAL_ADC_Start(&AdcHandle);3 N; @% C' C# V1 l4 N
  60.             HAL_ADC_PollForConversion(&AdcHandle, 10);   
    0 h1 D' @& B# ?% U5 j8 z% Q
  61.             /* Check if the continous conversion of regular channel is finished */+ N; E2 f! h4 m, I
  62.             if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)1 Y  i/ r. I( w2 z
  63.             {4 t* Z2 z0 q! U1 h: v
  64.                 /*##-6- Get the converted value of regular channel  ########################*/5 J6 `4 n* a- j$ \; s9 F
  65.                 uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);% _  s$ {" _' V& {
  66.             }
    3 w$ u. O9 U8 }$ [# E% \

  67. % o9 d+ K  X# y7 Q9 u+ d4 d6 v
  68.             vdd_value=VREF_IN_VALUE*FULL_ADC_DIGTIL_VALUE/uwADCxConvertedValue;    //内部电源电压
    , u, K% Z7 l( C, i: I, p
  69.             HAL_ADCEx_DisableVREFINT();
    / ?, E( q, {2 z/ W$ _
  70.             HAL_ADC_Stop(&AdcHandle);- E0 m/ B+ q, A1 j0 d  s( Z1 \
  71.             AdcHandle.Instance->CHSELR=0;5 M7 I8 T/ F" E& c) x: u* Y
  72.             sConfig.Channel = ADC_CHANNEL_0;             //ADC0,去测外部PA0口接的电压
    ( M3 Z1 M  Y. `: Q, q; t
  73.           HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);" ^, X; Y) G$ F7 `6 i: e. L8 ]
  74.             HAL_ADC_Start(&AdcHandle);
    # T% H) Q- r* B2 d  `, a
  75.             HAL_ADC_PollForConversion(&AdcHandle, 10);    7 f8 K+ j; |, O, ^1 E2 M- E
  76.             /* Check if the continous conversion of regular channel is finished */
    ; n6 |) e# T- T
  77.             if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
    # ?- ?: q: n$ ^+ \
  78.             {* o+ E/ b$ Y, P4 K! Z! z+ P7 w
  79.                 /*##-6- Get the converted value of regular channel  ########################*/" j7 `. D8 ^4 i! ~4 ]
  80.                 uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);5 H3 F) [* A5 @) J* \' a9 }
  81.             }
    / e7 D, {! @7 M4 p/ U8 {
  82.               //直接获取的是二进制码,14位对应最大值4095,内部电压为vdd_value通过比例计算得到电压数值
    ! C1 p$ D( A8 N8 J! u
  83.             temp_voltage=(float)uwADCxConvertedValue*vdd_value/4095;! G0 o" r2 n: p" z
  84.              //得到浮点型电压值            是乘了1000倍的            
    8 h8 M4 T+ d% V) h* e/ R& @
  85.             HAL_ADC_Stop(&AdcHandle);
    + [+ {$ ]" ~0 o3 Q2 ?) P- k
  86.             //HAL_ADCEx_DisableVREFINT();
    / z2 f; o) u2 h9 y2 m" H- f* I
  87.             __HAL_RCC_ADC1_CLK_DISABLE();
    2 F: {. r: y# I- A5 K# Y* G' g2 B
  88.    }
    - K/ x' N) M4 L* O, R; M
  89. }
复制代码
0 F" \  S5 {, x9 H+ Z/ ?) b7 K

! N9 y2 e: m4 \# r" I; L$ m  以上ADC检测,相当于一次连续检测了两次,第一次为内部电压用的特地通道17,第二次检测的是外部电压对应硬件连接的PA0对应通道0' R- M* x) A) ]9 B

" e: m6 f6 A0 k: u4 G) \8 i& g( c8 r& y9 X8 V( {9 c
赞 收藏 评论0 发布时间:2021-11-15 22:02

举报

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