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

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

[复制链接]
STMCU小助手 发布时间:2021-11-15 22:02
AD转换即模拟信号转换为数字信号,一般在单片机中模拟信号对应电压,通过ADC口将相应的电压转换为二进制的数字信号,从而推算出测得电压。下面我介绍下STM32中L0系列调用库函数来实现AD转换。
  G( K, C5 ^7 q# g( B+ R: q& G9 ?$ a" y$ T
        首先最基本的AD转换模式,即单次单通道检测,且不用到DMA。L0系列一共有19个AD口对应19个AD通道,其中16到18为检测内部模拟信号的通道。下面代码中用到是PA0即对应通道0,具体代码如下图:- b) V% D7 I" B( U5 V9 h
9 C( v/ a, v0 [0 q. k  c! s
     
  1.   Adc_init()
    ' _8 V) D! L6 F! k

  2. $ ?6 @4 y+ |$ P4 O# p( \
  3. {6 I4 f+ Q5 d$ ^1 W
  4. __HAL_RCC_ADC1_CLK_ENABLE();
    ' h2 \& t0 U  s2 T; q0 m- Z2 y
  5.     AdcHandle.Instance = ADC1;
    6 M+ u; ^! L5 ]2 \9 q, k
  6. 7 c: F$ f$ _4 A8 Y/ |
  7.   AdcHandle.Init.OversamplingMode      = DISABLE;
    3 z8 S8 Z$ M( D7 b  z1 d4 f

  8. , C- i, R* @8 |0 g( F/ S
  9.   AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV1;* b% b. b. d4 n$ Q& g6 k8 ^4 `
  10.   AdcHandle.Init.LowPowerAutoPowerOff  = DISABLE;
    9 n. H3 d, U- M; N4 j
  11.   AdcHandle.Init.LowPowerFrequencyMode = ENABLE;4 ^; _7 H( o2 O- n6 X( y
  12.   AdcHandle.Init.LowPowerAutoWait      = DISABLE;# d- t3 [. @. C8 [9 n
  13. 7 {/ Y+ x  @+ B; ?+ L
  14.   AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;
    + L% _) B. r4 k; H* U
  15.   AdcHandle.Init.SamplingTime          = ADC_SAMPLETIME_7CYCLES_5;
      G( ?) s7 D! i& R' _! i
  16.   AdcHandle.Init.ScanConvMode          = ADC_SCAN_DIRECTION_FORWARD;
    ; ?0 Q7 v+ Y4 }# ?. I0 U0 m1 q2 J
  17.   AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;. n; f( s. O# R1 M
  18.   AdcHandle.Init.ContinuousConvMode    = ENABLE;) p2 v% d! m1 i9 X$ ^* p7 j7 C
  19.   AdcHandle.Init.DiscontinuousConvMode = DISABLE;# B! d" q* m) e6 X1 A' K. c. w
  20.   AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;, F# P) E" e4 Z$ U2 ^+ i" G$ [
  21.   AdcHandle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;
    0 j# \' ?; O0 Q- X# y
  22.   AdcHandle.Init.DMAContinuousRequests = DISABLE;
    " E+ Q& {7 k; O8 a( P0 I

  23. , y' J2 s9 [6 x, }: j
  24.     HAL_ADC_Init(&AdcHandle);8 C  j* ^) \9 N: m. D0 g/ D7 q6 j
  25.     HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED);3 o3 c: H, A* H9 q% ~" b- }, e9 u
  26. + @3 y6 U8 Q7 Z' c5 v
  27. }
    6 Z$ L1 j. H% }
  28. 7 c! K; L) k' i3 Z: F
  29. //配置ADC初始化
    : G2 p6 E3 O- d4 o1 b- B1 o

  30. * t5 a, P3 |4 O7 X7 V4 @
  31. void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
    ' m, H& p+ [1 N1 d4 a9 p
  32. {
    * T3 N' I( W4 T/ S8 W4 k' p
  33.   GPIO_InitTypeDef                 GPIO_InitStruct;8 R, m; ^9 r2 A% J& z7 F$ o: o8 r

  34.   w/ I/ `3 Y; n% y: x
  35.   /*##-1- Enable peripherals and GPIO Clocks #################################*/
    8 z2 Z% s3 F. p# h; T; }2 {7 @
  36.   /* Enable GPIO clock ****************************************/
    $ ^& j& R/ o) P: }5 A0 X8 ?
  37.   __HAL_RCC_GPIOA_CLK_ENABLE();- W/ x) a* N; ?# ~% v! X
  38.   /* ADC1 Periph clock enable */
    ! W7 W1 k( j' r% X: C
  39.   __HAL_RCC_ADC1_CLK_ENABLE();  b1 H, V% d7 X: ^1 e
  40. 2 c1 ?1 |- r* p% f# p
  41.   /*##- 2- Configure peripheral GPIO #########################################*/
    5 p" N% E4 J  L/ q" W
  42.   /* ADC3 Channel8 GPIO pin configuration */
    ' [) I3 R8 {& }+ h* L& I
  43.   GPIO_InitStruct.Pin = GPIO_PIN_0;
    / o  |; U/ [9 u9 M
  44.   GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    - W  c6 `2 L( ~) g- e
  45.   GPIO_InitStruct.Pull = GPIO_NOPULL;
    % V( V5 y2 p4 I- _2 G
  46.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    5 z$ N7 J6 H% Q
  47. }' b% U+ r5 v0 o- ~; C, }3 g
  48. # A+ E) ~) e- P
  49. //初始化ADC引脚PA0,开启时钟
    / O( L" q) K- ~- m1 k! t
  50. ( E+ y% }! j! }# V" e5 k; l
  51. void get_voltage(void)
    1 |: Q' u) u" U
  52. {" A7 {, i6 ]. S3 `, ?! y2 h
  53.           bsp_adc_init();7 p0 I5 D( w0 f
  54.           HAL_ADCEx_EnableVREFINT();. @, V2 P& a) K* n# t6 E; |% Y, z0 J
  55.           HAL_ADC_Stop(&AdcHandle);
    9 z) N8 Y3 f# q( Y
  56.           AdcHandle.Instance->CHSELR=0;5 \: D. H0 H4 o4 k5 D8 g
  57.           sConfig.Channel = ADC_CHANNEL_17;         //通道17专门测内部电压值
    : e& S3 u, C, P; f' U  s' \, v
  58.            HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
    7 z8 k6 t( C7 o+ u
  59.             HAL_ADC_Start(&AdcHandle);5 n. m* X* ^. w9 n- w+ Q5 z7 P
  60.             HAL_ADC_PollForConversion(&AdcHandle, 10);    1 p4 A: Y; o+ L: y2 T8 D% T
  61.             /* Check if the continous conversion of regular channel is finished */+ I3 S9 v; n* y
  62.             if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)5 q+ I7 D/ |1 [
  63.             {8 v: ]" u' K% p% }* _/ _
  64.                 /*##-6- Get the converted value of regular channel  ########################*/* f" O- s9 n+ ^4 W4 q1 Z
  65.                 uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
    ! K* x$ F! N/ C! d/ Y: G; M4 S* @
  66.             }
    , ?( x& m" c) B
  67. / k* p. }& e* G7 s, S8 X' h
  68.             vdd_value=VREF_IN_VALUE*FULL_ADC_DIGTIL_VALUE/uwADCxConvertedValue;    //内部电源电压
    : @+ {5 a6 ~2 n
  69.             HAL_ADCEx_DisableVREFINT();7 g( m8 y; U$ c9 m
  70.             HAL_ADC_Stop(&AdcHandle);1 b' |& |" j0 y+ T, T
  71.             AdcHandle.Instance->CHSELR=0;8 l5 S+ E' N* z: J$ Y! j" }
  72.             sConfig.Channel = ADC_CHANNEL_0;             //ADC0,去测外部PA0口接的电压
    / X5 l2 @+ f- T2 Z0 x
  73.           HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
    + u' K! u* I, p; a$ A
  74.             HAL_ADC_Start(&AdcHandle);# c; x7 D+ M5 T6 J9 P8 n8 I2 y
  75.             HAL_ADC_PollForConversion(&AdcHandle, 10);   
    0 _4 A9 G$ x4 V0 Q3 _
  76.             /* Check if the continous conversion of regular channel is finished */# D, O" x1 u8 j: r
  77.             if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)$ K3 W3 t# {; D4 \( a2 t
  78.             {
    5 \1 Q& q4 u; M5 h5 u
  79.                 /*##-6- Get the converted value of regular channel  ########################*/! d; a* Y& e0 e% R/ a' _
  80.                 uwADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
    5 t& `9 C. O6 `' P% X
  81.             }
    ; Z9 {6 ^# ^% |1 D2 D
  82.               //直接获取的是二进制码,14位对应最大值4095,内部电压为vdd_value通过比例计算得到电压数值8 P2 Y  |/ ?6 {$ q( F8 u# R. z
  83.             temp_voltage=(float)uwADCxConvertedValue*vdd_value/4095;' w' q2 }; t+ x. V
  84.              //得到浮点型电压值            是乘了1000倍的            
    2 \) W9 s) l3 I
  85.             HAL_ADC_Stop(&AdcHandle);
    " r6 V  `) I7 D! P
  86.             //HAL_ADCEx_DisableVREFINT();5 S6 m" ^1 \0 u* `8 |- z
  87.             __HAL_RCC_ADC1_CLK_DISABLE();. |" k" C7 i3 z; K; c. t
  88.    }
    , I, Y6 Z- x3 I# G3 ]* m  w; H4 c
  89. }
复制代码
) a% n; ~, {! [
* x9 ~0 n8 u: z2 b5 ~
  以上ADC检测,相当于一次连续检测了两次,第一次为内部电压用的特地通道17,第二次检测的是外部电压对应硬件连接的PA0对应通道0
& V) t& t) l4 y. l% J, \" Y; t$ Q3 h9 u! _4 O. x: o8 N2 u
, p* F9 ?8 Y# z' I( ^9 r; \
赞 收藏 评论0 发布时间:2021-11-15 22:02

举报

0个回答

所属标签

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