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

STM32L071RB ADC 多通道模式

[复制链接]
hellolinux-2302 发布时间:2018-10-20 20:56
项目上要用到STM32L071 ,很简单的采集4个通道的ADC值。网上找了一下什么IT模式,DMA模式.....太多了,太麻烦。我们的应用很简单,就是每隔1秒采集一下ADC IN0,ADC IN1, 内部参考电压, 内部温度传感器4个通道。5 l8 P4 P  f0 x* G5 A" P8 P
首先是ADC初始化,用到了Vrefint,和内部温度传感器。
9 G' O/ y* V5 z$ m- k8 Q' Q, W
9 F! m" Q$ v0 K3 b
  1. /* ADC init function */
    ' i( i( R  h, N! B" T
  2. void MX_ADC_Init(void)8 w; r$ `% `( u( J
  3. {
    ( a; ?8 ]; U1 {+ u* J
  4. ; t% S* @, ~! T) \( O
  5.   ADC_ChannelConfTypeDef sConfig;2 ?  G, p5 t- d& T
  6. 6 D# ^5 g9 A) C1 {
  7.     /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) + d7 U# ]6 k  x# d% Q* V  e
  8.     */; X' \& }  ~0 W9 E$ F: t9 @
  9.   hadc.Instance = ADC1;
    0 d" Z5 _' P: u! j  n+ k' q2 }) _- `9 o
  10.   hadc.Init.OversamplingMode = DISABLE;5 A% k9 O  t1 s. u8 F2 u3 P6 m( F8 ~
  11.   hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
    0 Y# ~1 K- Q% j
  12.   hadc.Init.Resolution = ADC_RESOLUTION_12B;2 J* V2 A$ @( t
  13.   hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
    1 A# u: U" I; c) J/ Y: |, t* g- }7 ~- y
  14.   hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;) v7 r( c. R0 `
  15.   hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;; O# C1 D& Q+ ^/ _
  16.   hadc.Init.ContinuousConvMode = DISABLE;
    - N$ l! A, D, o1 m  Z$ `
  17.   hadc.Init.DiscontinuousConvMode = ENABLE;0 Z4 t4 }8 G* {
  18.   hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    ( L+ C; S6 ^' {2 F' r( ]
  19.   hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    6 L5 ]4 o+ h8 P9 ]! v# J* p
  20.   hadc.Init.DMAContinuousRequests = DISABLE;- m% {- D- Q( [: T5 B2 o; ?
  21.   hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
    - V2 [  m, T, y6 b  s) \
  22.   hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
    ' ^6 e. o& Q% D4 D8 R7 V- D  m& j
  23.   hadc.Init.LowPowerAutoWait = DISABLE;& U& D* d/ u3 W2 o% M. G" I! Y
  24.   hadc.Init.LowPowerFrequencyMode = DISABLE;' U# s& Y3 V& k5 u3 C% e8 C
  25.   hadc.Init.LowPowerAutoPowerOff = DISABLE;% l; x& v, x  x; @: y2 G
  26.   if (HAL_ADC_Init(&hadc) != HAL_OK)+ S3 V2 e2 W/ B$ E" s( n' D
  27.   {- k1 U  Y$ v- A3 O
  28.     _Error_Handler(__FILE__, __LINE__);
    6 p$ P# ?! s3 n2 x0 a/ S, U5 J
  29.   }
    7 [# y" N/ |5 s+ E: l& K" i
  30.   /* 校正ADC */$ G% W! [4 H3 v) A4 c3 f
  31.   if(HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED) != HAL_OK)2 M5 L7 H* Z8 k/ z# k' I
  32.   {2 x: l' P# l% y0 _$ E+ G' i
  33.     _Error_Handler(__FILE__, __LINE__);
    1 X1 o) g0 F6 o* t
  34.   }% ^6 ?7 i) r' {+ ]: L2 y: i
  35.   1 a7 O" ^7 }4 u
  36.   /**Configure for the selected ADC regular channel 0 to be converted.*/
    ' Q3 T9 ^* v# e! @" [4 O- R
  37.   sConfig.Channel = ADC_CHANNEL_0;9 |, u* O& |; D: d+ I
  38.   sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;1 ~  {) B; ~- J( G; A
  39.   if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK), ^% d- H/ p! d& R5 Q
  40.   {
    ( m& ~& X4 g7 O3 @* A
  41.     _Error_Handler(__FILE__, __LINE__);8 p& K4 N2 u3 Y" u3 x+ O4 l
  42.   }/ \. u# m( y* c* f
  43.   /**Configure for the selected ADC regular channel 1 to be converted.*/3 n9 n6 C. e7 Q7 D
  44.   sConfig.Channel = ADC_CHANNEL_1;7 J8 @! _  P( B6 H, A! M
  45.   if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK): P: \6 ^: d& b4 U! y8 q* {3 q
  46.   {0 [- ?; K# t) A$ `  `/ H
  47.     _Error_Handler(__FILE__, __LINE__);
    * Y+ ^5 H' ?" u) {3 o
  48.   }
    ; N. L6 Z/ Q9 O# o0 j
  49.   ' t- ]1 e: L0 v+ h0 E* M
  50.   /**Configure for the selected ADC regular channel 17 to be converted.*/
    8 f! O4 {" }* }. B; k' a! N
  51.   sConfig.Channel = ADC_CHANNEL_VREFINT;4 S: C) Y1 x  J/ `7 S
  52.   if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK); g/ x+ j- r7 G) w' w& N( q% y
  53.   {) R% H, Z5 }) S8 B$ G* \0 h
  54.     _Error_Handler(__FILE__, __LINE__);
    " }0 |; t8 {: {4 @% v; R# {- g" `
  55.   }
    5 j/ ?! U% x5 z5 G
  56.   
    ) j: ?0 F8 F  t( Z" D+ O/ k! t
  57.   /**Configure for the selected ADC regular channel 18 to be converted.*/1 ?; i  f( P) A1 R$ G( J
  58.   sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
    # r& _4 A" _2 p# t3 D5 \) `
  59.   if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)9 o  B, `" B( S) x2 [
  60.   {
    6 i! r; ]4 t% T5 u% o/ J7 Y
  61.     _Error_Handler(__FILE__, __LINE__);
    % H4 j5 L  w% r" p6 j
  62.   }
      |! z: e3 i! @% ]9 o' D
  63.   
    & c) N1 F  \$ D) ~0 Q0 L
  64.   HAL_ADCEx_EnableVREFINT();
    ! _& j. r' l. c; x( X$ I& G
  65.   HAL_ADCEx_EnableVREFINTTempSensor();
    8 g$ p3 _. H; p8 i7 r$ n8 }/ r. @/ Q
  66. }
复制代码

4 w# @# C& A$ [
' A- T. t/ d+ X3 H3 t9 v" r; x) s) |9 ~5 H
# N3 J8 A7 H5 X
ADC采样函数
2 R) _/ u2 `, F6 m
  1. /* Private functions ---------------------------------------------------------*/3 g# l6 N0 u6 q) V7 W' `3 G0 D
  2. #define RES1  10000   //分压电阻R1,10K  x' K- X/ D3 z4 K2 M- w
  3. #define RES2  10000   //分压电阻R2,10K% e+ G2 c7 X) ]; M8 f% m" R
  4. #define PRATIO  (RES1+RES2)/(RES2); i; E% s4 I& s9 F  {6 R% d9 Z
  5. 7 x3 I2 L! y2 F: k, `- E( _9 F
  6. #define ADC_12BIT     4095.0
    , _( f, M; u1 X; [8 |: @1 ]
  7. #define ADC_REF       3.3' r# N. Y9 l9 I1 N) |. Z
  8. : x$ T4 `' ?0 s& [! d' v/ n* [! S% `; F/ B
  9. #define VOL_RADIO     ADC_REF/ADC_12BIT                                                //无电阻分压模式系数
    : R! T" `. k$ x! d% Y# E, S: t
  10. #define BAT_RADIO     (ADC_REF*PRATIO)/ADC_12BIT  //电阻分压模式系数
    ' C0 M0 g) p5 i; [4 U$ c9 W

  11. 3 T# u4 ?, K% O/ n- `; p) K8 B
  12. //温度校正( K% Q2 \! @2 b6 V& d$ k
  13. #define TEMP130_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007E))
    9 r8 E0 q" l0 ]1 }% D5 |
  14. #define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007A))" _& Z) Y( ~9 D& f* `' d; f
  15. #define VDD_CALIB ((uint16_t) (300))
    $ [' L" A" d; k; d, D$ \
  16. #define VDD_APPLI ((uint16_t) (330))
    ; {* ~2 Z( _6 j' p9 v7 {  L  f3 G
  17. /*******************************************************************************
    ( o5 J2 w; |( A
  18. * Function Name  : ComputeTemperature
    ; V( X; E1 }6 S5 z' B
  19. * Description    : Compute STM32 Temperature
    ) m4 W3 O! y- l+ @0 g5 L! V
  20. * Input          : None
      X3 G$ X- O( Q2 X4 m% L$ b
  21. * Output         : None
      `  r* f2 }2 a* `# x: k6 r- d# s6 x
  22. * Return         : None
    0 G6 H+ Y6 o+ D: g4 P9 h$ R* z  G
  23. *******************************************************************************/
    4 V6 O2 v9 X, ~
  24. int32_t ComputeTemperature(uint32_t measure)
    ; m: i" _, \& p6 F6 b% Y: Y" l# @2 W
  25. {
    9 \0 {' {4 v" g1 U+ G5 p
  26.   int32_t temperature;* R! Z+ p  T: o; d
  27.   temperature = ((measure * VDD_APPLI / VDD_CALIB)- (int32_t) *TEMP30_CAL_ADDR );
    $ J* w& u9 }: W! L: ?! a8 A
  28.   temperature = temperature * (int32_t)(130 - 30);
    4 W3 b* ^$ D1 }# B) J2 g$ w$ B
  29.   temperature = temperature / (int32_t)(*TEMP130_CAL_ADDR - *TEMP30_CAL_ADDR);6 U- @6 G7 p2 w! C: o* i
  30.   temperature = temperature + 30;4 ?: Z/ {/ E: r5 s& O7 _% W
  31.   return(temperature);
    ! m) j+ y: l' K3 [" j
  32. }& l2 G5 B. [! j, ?
  33. /*******************************************************************************: H( P' u8 T' f( o' U0 m
  34. * Function Name  : Get_Adc
    : N0 v, D: @6 H
  35. * Description    : get voltage
    8 {% b/ f& w0 Z0 Q
  36. * Input          : None
    1 S7 N7 P6 z* C4 m+ ?, Q) w, C
  37. * Output         : None
    9 [+ a4 e( Z& k5 K* m! V( [
  38. * Return         : None
    - A  H: ~1 e0 Q1 c' b  I
  39. *******************************************************************************/
    8 F" L# v! O+ K6 j# Q
  40. void Get_Adc(void)
    $ N0 A7 C6 O$ Y& W2 v" e( S0 ?' K% I
  41. {
    6 T% V/ Y0 C* c, k: q0 |
  42.   u32 adc_value;
    9 X- t2 x: `' k: W$ z: y- B+ s3 m
  43.   adc_value = 0;' t7 M8 e& l# B: ~4 e: G& R

  44. 5 H6 g0 Q2 \  a: [6 f  Q
  45.   /*Start the conversion process*/  
    - F$ S* s- ]  J8 L) {
  46.   if (HAL_ADC_Start(&hadc) != HAL_OK)
    " e) Q3 Z) V- A) [3 A- {6 q: f2 A
  47.   {+ Y9 R9 R/ h2 Y( W
  48.     /* Start Conversation Error */& M1 \% g' l6 R( x  s
  49.     Error_Handler();) L' E" d! d- f
  50.   }$ Z( k2 K# i7 {/ U9 U8 F+ n' |
  51.   HAL_ADC_PollForConversion(&hadc, 50);   
    & J) h0 E# y( y& e; o7 X$ z2 P- e
  52.   /* Check if the continous conversion of regular channel is finished */* s* o" _  n( o* r' H
  53.   if ((HAL_ADC_GetState(&hadc) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)2 A% L0 \4 d: v; _, _9 D
  54.   {
    : f8 M% Z- o8 R% e; ~
  55.     /*Get the converted value of regular channel */1 ?( o8 ?4 r9 ~9 j" o( u
  56.     adc_value = HAL_ADC_GetValue(&hadc);
    1 x8 b0 J: B( \0 v9 T
  57.   }7 B- \# C: h1 @. k7 U* H
  58.   printf("DEBUG: ADC CHANNEL 0  = %fV\r\n", BAT_RADIO*adc_value);                //ADC 通道0 用10K,10K电阻分压& g" h3 p* N! O! T9 l) B" K9 L  s
  59. : u- b7 u+ K7 Q+ v3 g  U) C, p
  60.   
    ' @2 @; |1 K* K0 Y0 _
  61.   /*Start the conversion process*/  
    + v4 u4 A! S, {: o% Z4 z( g2 {& S
  62.   if (HAL_ADC_Start(&hadc) != HAL_OK)
    3 H- N0 q3 S  b6 T/ p6 r3 J: C$ [
  63.   {
    * A" ]+ s4 X/ _. w) E  b
  64.     /* Start Conversation Error */, I+ `/ v' `# h- N$ v
  65.     Error_Handler();
    ( P% H. u& \1 ~/ p2 Q
  66.   }
    3 N% ], d, Z4 q& d$ |
  67.   HAL_ADC_PollForConversion(&hadc, 50);   
    1 ?% V. P' {3 }
  68.   /* Check if the continous conversion of regular channel is finished */
    1 A+ f' Z0 U5 `( ^& l. ^
  69.   if ((HAL_ADC_GetState(&hadc) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)9 _1 C5 s; ?6 A$ W
  70.   {
    , f: u. J$ Z8 t, [: d
  71.     /*Get the converted value of regular channel */
    / l6 |* }, d, ~0 a+ p
  72.     adc_value = HAL_ADC_GetValue(&hadc);
    $ r2 V, `8 M7 t1 ]8 W" U' {5 S
  73.   }0 N% w$ g  X( Y9 m
  74.   printf("DEBUG: ADC CHANNEL 1  = %fV\r\n", VOL_RADIO*adc_value);                //ADC 通道1 没用电阻分压
    % q1 ?" Y9 Z8 m! s& q! X% g8 Y; [6 O
  75. ) ~5 q/ G- ?4 y0 F; _
  76.   5 M- T- T' l+ g, _6 Y
  77.   /*Start the conversion process*/  
    " p1 d7 R8 S4 l
  78.   if (HAL_ADC_Start(&hadc) != HAL_OK)7 }( q& q  G8 L, |
  79.   {
    ; e, `% M4 J5 M: e4 }
  80.     /* Start Conversation Error */
    , t9 Y* V" b3 l% h* O' V' `
  81.     Error_Handler();- R: V+ A; U, U3 @9 v) y
  82.   }2 {6 L; C0 J% y7 R8 c
  83.   HAL_ADC_PollForConversion(&hadc, 50);      O/ [3 _$ Z2 d3 m! F7 J5 h
  84.   /* Check if the continous conversion of regular channel is finished */, d2 a" g, p: J6 @& s
  85.   if ((HAL_ADC_GetState(&hadc) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC); h- k  ~- ~( ^" x$ w
  86.   {
      `( w2 O/ B- w6 y
  87.     /*Get the converted value of regular channel */+ p8 M9 n' h0 y& @6 c+ d: h
  88.     adc_value = HAL_ADC_GetValue(&hadc);
    # e: O& G1 p) g& A1 s+ g
  89.   }
    5 e2 Q1 Y; U  x9 |9 ]( @5 K3 I% w6 R5 k" t
  90.   printf("DEBUG: ADC CHANNEL 17 = %fV\r\n", VOL_RADIO*adc_value);        //内部Vref = 1.2V
    # o7 i, ~% ?. ^, }
  91. 9 [1 I7 w1 `9 o2 c' Q# _* C6 D8 E
  92.   
    / M+ {, p" l1 F6 y
  93.   /*Start the conversion process*/  ! O1 M  t2 C$ J
  94.   if (HAL_ADC_Start(&hadc) != HAL_OK)5 l6 T7 R. X, \2 n4 j+ |9 u
  95.   {
    ' M1 z/ e- V( C1 D! S; @
  96.     /* Start Conversation Error */
    % I& r5 X" [8 t
  97.     Error_Handler();4 }' _$ y4 @* u) G
  98.   }
    ' h5 I9 L/ _( v& {5 g/ r# M% {
  99.   HAL_ADC_PollForConversion(&hadc, 50);      _& Q! g; k7 H$ o' u
  100.   /* Check if the continous conversion of regular channel is finished */
    ! `  F( R3 k3 `& D" _& M. m& T
  101.   if ((HAL_ADC_GetState(&hadc) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
    7 m1 v  `! q. j% g! |% U5 d, T
  102.   {' u2 M% o5 i* L0 h
  103.     /*Get the converted value of regular channel */# [5 w  {6 |5 O% o. m3 P) ]- r5 N
  104.     adc_value = HAL_ADC_GetValue(&hadc);7 w. E" `. L0 M  u6 U' v2 j
  105.   }; g/ |. T. ^2 B# I
  106.   printf("DEBUG: ADC CHANNEL 18 = %d℃\r\n", ComputeTemperature(adc_value));        //内部温度传感器6 C. t, ?* G6 a  B4 S
  107.   
    , J6 E% H% N" a( \/ W
  108.   HAL_ADC_Stop(&hadc);
    / r. _) U1 m/ o9 a

  109. : s0 r* [! c) _  L+ v
  110. }
复制代码
* T7 o; q0 p- W. P, q6 Y2 x- p! X. h
3 e( f2 u  o. q. V$ ]  K3 b8 r# |
赞 收藏 评论5 发布时间:2018-10-20 20:56

举报

5个回答
fanyao-367090 回答时间:2018-10-25 08:56:04
楼主这是吐槽么
hejun1203 回答时间:2018-10-27 15:48:43
shinyzhuo 回答时间:2019-1-4 16:54:20
楼主可以啊,刚好我这就要用ADC来采集电压,先收藏了
hellolinux-2302 回答时间:2019-1-4 17:13:41
fanyao-367090 发表于 2018-10-25 08:562 G* l6 Y, G, X! ~# v9 \* m
楼主这是吐槽么

- o, B/ O: o) a* g0 v0 {ST 给的很多历程太复杂,其实大家的应用都很简单。
shinyzhuo 回答时间:2019-1-14 16:57:20
“Error[Pe020]: identifier "u32" is undefined ”
+ D6 [2 D, Y9 G5 W+ X1 |楼主这个怎么报错呀

所属标签

相似技术帖

官网相关资源

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