请选择 进入手机版 | 继续访问电脑版

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

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

[复制链接]
STMCU小助手 发布时间:2021-11-15 22:02
AD转换即模拟信号转换为数字信号,一般在单片机中模拟信号对应电压,通过ADC口将相应的电压转换为二进制的数字信号,从而推算出测得电压。下面我介绍下STM32中L0系列调用库函数来实现AD转换。: A3 t, X( N5 r! G- L3 b

5 X& y# {+ p! ^4 W        首先最基本的AD转换模式,即单次单通道检测,且不用到DMA。L0系列一共有19个AD口对应19个AD通道,其中16到18为检测内部模拟信号的通道。下面代码中用到是PA0即对应通道0,具体代码如下图:! n1 N+ v+ M0 V0 E6 Y2 x; f
' e7 L4 d" E# b7 v
     
  1.   Adc_init()
    , Q$ o" P3 A8 q1 j! O4 S
  2. 9 M% {  O- @6 B; P) r9 G
  3. {! f8 O2 p, R% {
  4. __HAL_RCC_ADC1_CLK_ENABLE();& R! L1 _, O; v5 M+ Q9 G2 Q0 h4 A
  5.     AdcHandle.Instance = ADC1;
    ) f, r0 l2 y1 y- v& g4 n/ \- s

  6. - e6 G3 ^8 c7 g1 p; G
  7.   AdcHandle.Init.OversamplingMode      = DISABLE;4 I& p  H* l  `/ D

  8. $ C  K% M' J0 I7 i8 e. _6 \- w
  9.   AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV1;
    0 Q* m; _$ d0 V4 `3 _5 X( |
  10.   AdcHandle.Init.LowPowerAutoPowerOff  = DISABLE;
    , w" f; c/ }# W/ W6 o$ T, E
  11.   AdcHandle.Init.LowPowerFrequencyMode = ENABLE;
    ' _( ~' N' N$ h& U$ U8 k
  12.   AdcHandle.Init.LowPowerAutoWait      = DISABLE;+ j5 ?2 G7 E" k' t* {
  13. 6 s3 a! G$ ?' Y" C. e5 c7 t
  14.   AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;
    . p( c+ G- S3 {1 f
  15.   AdcHandle.Init.SamplingTime          = ADC_SAMPLETIME_7CYCLES_5;- W& _2 b# S( g. W% V0 _
  16.   AdcHandle.Init.ScanConvMode          = ADC_SCAN_DIRECTION_FORWARD;4 S4 A" l; Y1 H6 e: b
  17.   AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
    ; \9 _9 r) S; l
  18.   AdcHandle.Init.ContinuousConvMode    = ENABLE;
    1 K) v# m6 G( P; A' B
  19.   AdcHandle.Init.DiscontinuousConvMode = DISABLE;! ?9 G8 T' U  Z" ]  Y, ^
  20.   AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;' R8 G9 y# x% B6 ]( ^
  21.   AdcHandle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;
    ! r2 h6 d" @9 k: S$ U  t+ h
  22.   AdcHandle.Init.DMAContinuousRequests = DISABLE;9 H9 g( g% Y# F( j5 V; e& s3 P
  23. 3 x+ S5 G' X2 s2 {# D
  24.     HAL_ADC_Init(&AdcHandle);9 e) S$ j8 c2 L" x5 ~
  25.     HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED);
    6 U' q! ]8 i5 W1 `& x! y
  26. , R* N" h% O' L9 \$ q
  27. }
    % Z) v7 s& M" }, o$ q
  28. 3 o; z  U; ^$ b
  29. //配置ADC初始化4 S3 d, D' e8 K
  30. / k, u+ D! e4 [( q: g5 ]6 s
  31. void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
    . d0 R# k+ s# e  ?$ P, l+ q
  32. {2 b' k. E6 p$ y5 @! m5 a* M
  33.   GPIO_InitTypeDef                 GPIO_InitStruct;/ i: d' P' F; O1 O' `) P: _
  34. # _3 z  J7 X+ |! B. Z
  35.   /*##-1- Enable peripherals and GPIO Clocks #################################*/  A; }3 W) Y$ F4 j
  36.   /* Enable GPIO clock ****************************************/3 L4 @3 `! a" y
  37.   __HAL_RCC_GPIOA_CLK_ENABLE();; I" v( ?+ `" j% a5 I% ~) C
  38.   /* ADC1 Periph clock enable */% A- g+ f' r$ N3 D6 I
  39.   __HAL_RCC_ADC1_CLK_ENABLE();
    $ _4 i, x& W( w& [: N

  40. 0 z! v0 K3 B, [. u: ^: E8 g
  41.   /*##- 2- Configure peripheral GPIO #########################################*/
    . w6 }5 g1 ]& a9 v) l
  42.   /* ADC3 Channel8 GPIO pin configuration */
    1 h- s7 v* k# c* x& o2 P! X
  43.   GPIO_InitStruct.Pin = GPIO_PIN_0;
    % Z& B3 p/ G: i3 K
  44.   GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    ( t- K. |( p: C+ D% i' S' l  }9 k
  45.   GPIO_InitStruct.Pull = GPIO_NOPULL;, F/ p, M' K" b( P/ ~1 x
  46.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    * Y6 f% m; j$ z( b, N2 ^5 x
  47. }
    0 v3 @. V) D6 ?" [7 R' C- X

  48. 6 V: K. R2 ^# y
  49. //初始化ADC引脚PA0,开启时钟3 r8 t0 R5 H& s
  50. 3 s8 J) p0 L. h# c
  51. void get_voltage(void)
    0 o% o% B4 w, f9 V# u8 V  K0 s9 P
  52. {( x; c* O+ F" T1 [
  53.           bsp_adc_init();
    ! I( L1 w# v2 N
  54.           HAL_ADCEx_EnableVREFINT();5 r. n. z% k" D  t5 m+ j
  55.           HAL_ADC_Stop(&AdcHandle);
    0 E% ~9 W5 s7 [
  56.           AdcHandle.Instance->CHSELR=0;0 t, A) a+ [! i5 b
  57.           sConfig.Channel = ADC_CHANNEL_17;         //通道17专门测内部电压值
    ( O) ?& D4 Z$ l2 G; |- u7 o
  58.            HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
    % n- w1 H* c# {  u% `" H
  59.             HAL_ADC_Start(&AdcHandle);
    ) z0 J( I& v* b% `
  60.             HAL_ADC_PollForConversion(&AdcHandle, 10);   
    7 c3 s- e6 [3 I1 e
  61.             /* Check if the continous conversion of regular channel is finished */
    : ^) @" A8 _  M1 }
  62.             if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)" g2 u* l) u5 `+ O3 V/ z
  63.             {8 m* B% H2 `3 z; M& j
  64.                 /*##-6- Get the converted value of regular channel  ########################*/$ q; }6 E# f8 L+ H$ P
  65.                 uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);2 }. M' T! W) [% V" l
  66.             }0 H/ s" R7 y4 v4 V7 e% s
  67. 9 s3 d+ D* P- Z* H
  68.             vdd_value=VREF_IN_VALUE*FULL_ADC_DIGTIL_VALUE/uwADCxConvertedValue;    //内部电源电压/ R( _; Z# Z  ?5 T: P' c- V
  69.             HAL_ADCEx_DisableVREFINT();
    8 C9 \3 A" V; k
  70.             HAL_ADC_Stop(&AdcHandle);0 u( Y6 a( @' v& b
  71.             AdcHandle.Instance->CHSELR=0;% g/ l  D0 s* m5 G# A
  72.             sConfig.Channel = ADC_CHANNEL_0;             //ADC0,去测外部PA0口接的电压
    . u# U; m, w- j! o4 c& g/ S
  73.           HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);) M& S6 m$ E- j9 M  n
  74.             HAL_ADC_Start(&AdcHandle);
    ) Q' A. f# U' H! k1 G) f* q
  75.             HAL_ADC_PollForConversion(&AdcHandle, 10);   
    0 @/ \% y8 o' t, S' x
  76.             /* Check if the continous conversion of regular channel is finished */6 c" t: Q3 ?3 U# q4 N( i
  77.             if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)- E# H. z! E3 i  E$ c2 F
  78.             {& h+ g1 J  m6 ]' m7 r& A  Q
  79.                 /*##-6- Get the converted value of regular channel  ########################*/
    6 T( B: h- h0 n5 Q
  80.                 uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
    ' J6 |5 f+ g' M( m& H; ~
  81.             }% i* T9 }  d# I8 D4 a: S
  82.               //直接获取的是二进制码,14位对应最大值4095,内部电压为vdd_value通过比例计算得到电压数值
    , t+ T- v6 e8 \& R2 ?, f
  83.             temp_voltage=(float)uwADCxConvertedValue*vdd_value/4095;
    - X4 i( w4 e: S+ w* W+ M  A9 ^
  84.              //得到浮点型电压值            是乘了1000倍的              ^1 v- m% b; Q+ F# E! e! h0 t4 U
  85.             HAL_ADC_Stop(&AdcHandle);' j  f: `* F. o3 e* f9 h
  86.             //HAL_ADCEx_DisableVREFINT();) g4 x. l, X2 b1 E
  87.             __HAL_RCC_ADC1_CLK_DISABLE();
    : q9 X" I7 I, P
  88.    }$ J( }8 y: Z8 R+ ^: b, C* B" Q
  89. }
复制代码
' [* @# b* o/ K& f, {

* H2 v3 c' z& E  以上ADC检测,相当于一次连续检测了两次,第一次为内部电压用的特地通道17,第二次检测的是外部电压对应硬件连接的PA0对应通道0
2 p/ N" i0 y: k$ K# A) t. j% [; o1 K2 u, ?. x

8 ~$ O. V* {' D
收藏 评论0 发布时间:2021-11-15 22:02

举报

0个回答

所属标签

相似分享

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