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

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

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

- J7 X1 _9 N& ~; W+ i        首先最基本的AD转换模式,即单次单通道检测,且不用到DMA。L0系列一共有19个AD口对应19个AD通道,其中16到18为检测内部模拟信号的通道。下面代码中用到是PA0即对应通道0,具体代码如下图:
3 S: f" Q+ S5 A: O1 `: @2 s
& ]5 O  s; G7 P+ n3 w& K     
  1.   Adc_init()
    5 X0 R+ X. f/ Y! n' E1 V, |

  2. 3 n2 k4 M2 y  ~7 A: n; z1 r
  3. {% r1 v( B/ |! |9 ~! }' J
  4. __HAL_RCC_ADC1_CLK_ENABLE();, H' x5 r% w  H% b$ L
  5.     AdcHandle.Instance = ADC1;
    ! y( \0 Y  h8 E. Z( R( A0 ]9 G

  6. 5 c2 w& f2 Q4 |8 f& c
  7.   AdcHandle.Init.OversamplingMode      = DISABLE;
    # m4 C( C- t8 K- h# k$ i4 a

  8. ( X- l' p% @( T% m7 h9 a! }
  9.   AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV1;) m0 H  g/ {" Z9 W5 g8 p2 r: `; f
  10.   AdcHandle.Init.LowPowerAutoPowerOff  = DISABLE;
    $ k9 _5 n" J+ [/ L, @* x
  11.   AdcHandle.Init.LowPowerFrequencyMode = ENABLE;
    : p  M* j+ T7 B
  12.   AdcHandle.Init.LowPowerAutoWait      = DISABLE;
    % r$ G% s' f* S

  13. + w; F% d1 Z$ \4 m
  14.   AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;- k$ G; c) G- R! ^
  15.   AdcHandle.Init.SamplingTime          = ADC_SAMPLETIME_7CYCLES_5;
    5 x# m' Q' i) U( v( s  k2 P
  16.   AdcHandle.Init.ScanConvMode          = ADC_SCAN_DIRECTION_FORWARD;* F8 s) }% g" B% L
  17.   AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
    + x. u/ W2 i8 j6 X
  18.   AdcHandle.Init.ContinuousConvMode    = ENABLE;
    , u  F" o! k( U3 R
  19.   AdcHandle.Init.DiscontinuousConvMode = DISABLE;. ]% q* Y. n' T& _' K4 \
  20.   AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
    $ Z  ]8 c( A0 s) e7 ]
  21.   AdcHandle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;' U3 h7 `$ R% I2 t! `- A; O) l5 |4 q
  22.   AdcHandle.Init.DMAContinuousRequests = DISABLE;
    $ ?! C6 n% k& ^& f
  23. " u- P( d  l1 ]5 N
  24.     HAL_ADC_Init(&AdcHandle);4 o$ a5 v+ y% E: E+ v* k* {& J; X
  25.     HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED);5 C5 F  i* V: I2 u

  26. . d$ W8 e8 i& H# V; u
  27. }! g( G" u5 W& F2 X0 _

  28.   Q7 \, V$ I/ p( s
  29. //配置ADC初始化
      R/ \0 ]7 o- L6 ^

  30. 6 j* a( h5 G" j/ u  N6 K5 ]3 Z
  31. void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)% o( V' s, [% |8 w
  32. {
    # \! W8 F* D! x: K$ C
  33.   GPIO_InitTypeDef                 GPIO_InitStruct;
    7 C! e8 q0 H' B: a; O2 B2 H4 d4 p0 T  f

  34. 2 }' _7 j9 C( @
  35.   /*##-1- Enable peripherals and GPIO Clocks #################################*/
    6 C* ~. s; C" q
  36.   /* Enable GPIO clock ****************************************/( v/ O2 x* P0 R( E) h
  37.   __HAL_RCC_GPIOA_CLK_ENABLE();1 o) S- S6 b8 M/ ?' H# j; C
  38.   /* ADC1 Periph clock enable */
    ; m& E2 `0 |% v, s( H; d5 J
  39.   __HAL_RCC_ADC1_CLK_ENABLE();
    9 E. g' y! v; H9 A

  40. 1 _7 F3 j2 r& O" x
  41.   /*##- 2- Configure peripheral GPIO #########################################*/" U" ]( g2 q9 T( ]9 F# y
  42.   /* ADC3 Channel8 GPIO pin configuration */
    8 S8 p, B% v% q
  43.   GPIO_InitStruct.Pin = GPIO_PIN_0;/ X: z) B2 t' F0 o' {3 H+ \
  44.   GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    & f% m1 `# P1 V  W3 Y1 U
  45.   GPIO_InitStruct.Pull = GPIO_NOPULL;& e9 U% L! N' h& P6 f/ T% h- T, o' \
  46.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);8 f! u4 n' X. X9 l
  47. }
    3 ^; F& d) M' v% P" b& U( K

  48. , b0 \! K: `# Z
  49. //初始化ADC引脚PA0,开启时钟
    ) Z7 o" ?# A" O

  50. 5 e4 X2 x! U* f8 y; I  F8 Q' b4 x, u
  51. void get_voltage(void)2 ^1 L8 J2 J9 z$ \; L
  52. {
    0 Z  |' }, E: J* ~* D% @
  53.           bsp_adc_init();% X/ a( M8 Y; n' ?' \& A
  54.           HAL_ADCEx_EnableVREFINT();* }- k; o: i. x: @$ l6 S) A  z
  55.           HAL_ADC_Stop(&AdcHandle);9 ~8 D4 m( U: D& a: ]( F  z/ |
  56.           AdcHandle.Instance->CHSELR=0;
    " |9 D  E* \, }' V
  57.           sConfig.Channel = ADC_CHANNEL_17;         //通道17专门测内部电压值% {- z2 F7 E# f
  58.            HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
    * h/ p! g( A5 V3 E/ B) W. f
  59.             HAL_ADC_Start(&AdcHandle);# [2 p2 t* M; B* c( ]- X
  60.             HAL_ADC_PollForConversion(&AdcHandle, 10);    + L# E& \4 ^1 w; X4 i9 v' T
  61.             /* Check if the continous conversion of regular channel is finished */* j: g" b2 K* k, Q. Y4 z4 A
  62.             if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)4 j0 Z, s5 [, e3 Y% O; j
  63.             {3 T  v! Z6 V' b  C9 ]
  64.                 /*##-6- Get the converted value of regular channel  ########################*/
    ) G1 c7 I2 h2 t+ i2 p% X& m$ Z) G
  65.                 uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
    9 U, Z$ q. p% t
  66.             }. b% f) c: n! c1 a" A+ E4 _
  67. " \$ Q: d" O; a( m0 S- z  m
  68.             vdd_value=VREF_IN_VALUE*FULL_ADC_DIGTIL_VALUE/uwADCxConvertedValue;    //内部电源电压( J1 I3 Q3 l) q/ F0 @1 n
  69.             HAL_ADCEx_DisableVREFINT();4 c: {6 x* M% X, O+ Y& X
  70.             HAL_ADC_Stop(&AdcHandle);
      [1 N9 l1 V: j8 e# z5 @
  71.             AdcHandle.Instance->CHSELR=0;
    , \4 u, d% M& v% ?0 z' w- g
  72.             sConfig.Channel = ADC_CHANNEL_0;             //ADC0,去测外部PA0口接的电压" j# y4 o8 r: X. z+ i# ^
  73.           HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);/ U9 k) y: K; ^1 a+ }
  74.             HAL_ADC_Start(&AdcHandle);/ k7 {. `# i# V% p% e
  75.             HAL_ADC_PollForConversion(&AdcHandle, 10);    & t1 {& U( h) q6 l% s
  76.             /* Check if the continous conversion of regular channel is finished */0 C% i; J2 O: b0 n) F: ^# R% G
  77.             if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
    ) q) c: }# Y( u9 @5 K$ M$ P
  78.             {3 V! {& Y8 F+ }0 ^! }7 X) d" Y
  79.                 /*##-6- Get the converted value of regular channel  ########################*/
    ) _0 U$ C( _: ]7 C
  80.                 uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
    0 S/ j4 V7 L) K* {6 g
  81.             }) k) F! N& V7 ]
  82.               //直接获取的是二进制码,14位对应最大值4095,内部电压为vdd_value通过比例计算得到电压数值) }; F/ V/ }( R: b. o1 p! C: R9 j
  83.             temp_voltage=(float)uwADCxConvertedValue*vdd_value/4095;& x# m, U3 I6 d* B
  84.              //得到浮点型电压值            是乘了1000倍的            0 R! A" T, t/ E- }
  85.             HAL_ADC_Stop(&AdcHandle);
    $ O0 y; M4 o  {2 `" X0 ?! o6 C) h1 w
  86.             //HAL_ADCEx_DisableVREFINT();6 \9 M/ D: W( ^: q( `6 M4 U
  87.             __HAL_RCC_ADC1_CLK_DISABLE();
    . y8 S6 D5 k( w" `! ~& S* j0 P9 J
  88.    }
    8 x! O' A' A6 K
  89. }
复制代码
( v9 O# n. S' s9 ~5 P

% x7 Q- r; @3 v  以上ADC检测,相当于一次连续检测了两次,第一次为内部电压用的特地通道17,第二次检测的是外部电压对应硬件连接的PA0对应通道0
' c: N+ k/ S( O$ O4 i2 h" D" [) I2 n
/ n1 B# a8 T; h8 b5 n
收藏 评论0 发布时间:2021-11-15 22:02

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版