项目上要用到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- /* ADC init function */
' i( i( R h, N! B" T - void MX_ADC_Init(void)8 w; r$ `% `( u( J
- {
( a; ?8 ]; U1 {+ u* J - ; t% S* @, ~! T) \( O
- ADC_ChannelConfTypeDef sConfig;2 ? G, p5 t- d& T
- 6 D# ^5 g9 A) C1 {
- /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) + d7 U# ]6 k x# d% Q* V e
- */; X' \& } ~0 W9 E$ F: t9 @
- hadc.Instance = ADC1;
0 d" Z5 _' P: u! j n+ k' q2 }) _- `9 o - hadc.Init.OversamplingMode = DISABLE;5 A% k9 O t1 s. u8 F2 u3 P6 m( F8 ~
- hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
0 Y# ~1 K- Q% j - hadc.Init.Resolution = ADC_RESOLUTION_12B;2 J* V2 A$ @( t
- hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
1 A# u: U" I; c) J/ Y: |, t* g- }7 ~- y - hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;) v7 r( c. R0 `
- hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;; O# C1 D& Q+ ^/ _
- hadc.Init.ContinuousConvMode = DISABLE;
- N$ l! A, D, o1 m Z$ ` - hadc.Init.DiscontinuousConvMode = ENABLE;0 Z4 t4 }8 G* {
- hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
( L+ C; S6 ^' {2 F' r( ] - hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
6 L5 ]4 o+ h8 P9 ]! v# J* p - hadc.Init.DMAContinuousRequests = DISABLE;- m% {- D- Q( [: T5 B2 o; ?
- hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
- V2 [ m, T, y6 b s) \ - hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
' ^6 e. o& Q% D4 D8 R7 V- D m& j - hadc.Init.LowPowerAutoWait = DISABLE;& U& D* d/ u3 W2 o% M. G" I! Y
- hadc.Init.LowPowerFrequencyMode = DISABLE;' U# s& Y3 V& k5 u3 C% e8 C
- hadc.Init.LowPowerAutoPowerOff = DISABLE;% l; x& v, x x; @: y2 G
- if (HAL_ADC_Init(&hadc) != HAL_OK)+ S3 V2 e2 W/ B$ E" s( n' D
- {- k1 U Y$ v- A3 O
- _Error_Handler(__FILE__, __LINE__);
6 p$ P# ?! s3 n2 x0 a/ S, U5 J - }
7 [# y" N/ |5 s+ E: l& K" i - /* 校正ADC */$ G% W! [4 H3 v) A4 c3 f
- if(HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED) != HAL_OK)2 M5 L7 H* Z8 k/ z# k' I
- {2 x: l' P# l% y0 _$ E+ G' i
- _Error_Handler(__FILE__, __LINE__);
1 X1 o) g0 F6 o* t - }% ^6 ?7 i) r' {+ ]: L2 y: i
- 1 a7 O" ^7 }4 u
- /**Configure for the selected ADC regular channel 0 to be converted.*/
' Q3 T9 ^* v# e! @" [4 O- R - sConfig.Channel = ADC_CHANNEL_0;9 |, u* O& |; D: d+ I
- sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;1 ~ {) B; ~- J( G; A
- if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK), ^% d- H/ p! d& R5 Q
- {
( m& ~& X4 g7 O3 @* A - _Error_Handler(__FILE__, __LINE__);8 p& K4 N2 u3 Y" u3 x+ O4 l
- }/ \. u# m( y* c* f
- /**Configure for the selected ADC regular channel 1 to be converted.*/3 n9 n6 C. e7 Q7 D
- sConfig.Channel = ADC_CHANNEL_1;7 J8 @! _ P( B6 H, A! M
- if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK): P: \6 ^: d& b4 U! y8 q* {3 q
- {0 [- ?; K# t) A$ ` `/ H
- _Error_Handler(__FILE__, __LINE__);
* Y+ ^5 H' ?" u) {3 o - }
; N. L6 Z/ Q9 O# o0 j - ' t- ]1 e: L0 v+ h0 E* M
- /**Configure for the selected ADC regular channel 17 to be converted.*/
8 f! O4 {" }* }. B; k' a! N - sConfig.Channel = ADC_CHANNEL_VREFINT;4 S: C) Y1 x J/ `7 S
- if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK); g/ x+ j- r7 G) w' w& N( q% y
- {) R% H, Z5 }) S8 B$ G* \0 h
- _Error_Handler(__FILE__, __LINE__);
" }0 |; t8 {: {4 @% v; R# {- g" ` - }
5 j/ ?! U% x5 z5 G -
) j: ?0 F8 F t( Z" D+ O/ k! t - /**Configure for the selected ADC regular channel 18 to be converted.*/1 ?; i f( P) A1 R$ G( J
- sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
# r& _4 A" _2 p# t3 D5 \) ` - if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)9 o B, `" B( S) x2 [
- {
6 i! r; ]4 t% T5 u% o/ J7 Y - _Error_Handler(__FILE__, __LINE__);
% H4 j5 L w% r" p6 j - }
|! z: e3 i! @% ]9 o' D -
& c) N1 F \$ D) ~0 Q0 L - HAL_ADCEx_EnableVREFINT();
! _& j. r' l. c; x( X$ I& G - HAL_ADCEx_EnableVREFINTTempSensor();
8 g$ p3 _. H; p8 i7 r$ n8 }/ r. @/ Q - }
复制代码
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- /* Private functions ---------------------------------------------------------*/3 g# l6 N0 u6 q) V7 W' `3 G0 D
- #define RES1 10000 //分压电阻R1,10K x' K- X/ D3 z4 K2 M- w
- #define RES2 10000 //分压电阻R2,10K% e+ G2 c7 X) ]; M8 f% m" R
- #define PRATIO (RES1+RES2)/(RES2); i; E% s4 I& s9 F {6 R% d9 Z
- 7 x3 I2 L! y2 F: k, `- E( _9 F
- #define ADC_12BIT 4095.0
, _( f, M; u1 X; [8 |: @1 ] - #define ADC_REF 3.3' r# N. Y9 l9 I1 N) |. Z
- : x$ T4 `' ?0 s& [! d' v/ n* [! S% `; F/ B
- #define VOL_RADIO ADC_REF/ADC_12BIT //无电阻分压模式系数
: R! T" `. k$ x! d% Y# E, S: t - #define BAT_RADIO (ADC_REF*PRATIO)/ADC_12BIT //电阻分压模式系数
' C0 M0 g) p5 i; [4 U$ c9 W
3 T# u4 ?, K% O/ n- `; p) K8 B- //温度校正( K% Q2 \! @2 b6 V& d$ k
- #define TEMP130_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007E))
9 r8 E0 q" l0 ]1 }% D5 | - #define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007A))" _& Z) Y( ~9 D& f* `' d; f
- #define VDD_CALIB ((uint16_t) (300))
$ [' L" A" d; k; d, D$ \ - #define VDD_APPLI ((uint16_t) (330))
; {* ~2 Z( _6 j' p9 v7 { L f3 G - /*******************************************************************************
( o5 J2 w; |( A - * Function Name : ComputeTemperature
; V( X; E1 }6 S5 z' B - * Description : Compute STM32 Temperature
) m4 W3 O! y- l+ @0 g5 L! V - * Input : None
X3 G$ X- O( Q2 X4 m% L$ b - * Output : None
` r* f2 }2 a* `# x: k6 r- d# s6 x - * Return : None
0 G6 H+ Y6 o+ D: g4 P9 h$ R* z G - *******************************************************************************/
4 V6 O2 v9 X, ~ - int32_t ComputeTemperature(uint32_t measure)
; m: i" _, \& p6 F6 b% Y: Y" l# @2 W - {
9 \0 {' {4 v" g1 U+ G5 p - int32_t temperature;* R! Z+ p T: o; d
- temperature = ((measure * VDD_APPLI / VDD_CALIB)- (int32_t) *TEMP30_CAL_ADDR );
$ J* w& u9 }: W! L: ?! a8 A - temperature = temperature * (int32_t)(130 - 30);
4 W3 b* ^$ D1 }# B) J2 g$ w$ B - temperature = temperature / (int32_t)(*TEMP130_CAL_ADDR - *TEMP30_CAL_ADDR);6 U- @6 G7 p2 w! C: o* i
- temperature = temperature + 30;4 ?: Z/ {/ E: r5 s& O7 _% W
- return(temperature);
! m) j+ y: l' K3 [" j - }& l2 G5 B. [! j, ?
- /*******************************************************************************: H( P' u8 T' f( o' U0 m
- * Function Name : Get_Adc
: N0 v, D: @6 H - * Description : get voltage
8 {% b/ f& w0 Z0 Q - * Input : None
1 S7 N7 P6 z* C4 m+ ?, Q) w, C - * Output : None
9 [+ a4 e( Z& k5 K* m! V( [ - * Return : None
- A H: ~1 e0 Q1 c' b I - *******************************************************************************/
8 F" L# v! O+ K6 j# Q - void Get_Adc(void)
$ N0 A7 C6 O$ Y& W2 v" e( S0 ?' K% I - {
6 T% V/ Y0 C* c, k: q0 | - u32 adc_value;
9 X- t2 x: `' k: W$ z: y- B+ s3 m - adc_value = 0;' t7 M8 e& l# B: ~4 e: G& R
5 H6 g0 Q2 \ a: [6 f Q- /*Start the conversion process*/
- F$ S* s- ] J8 L) { - if (HAL_ADC_Start(&hadc) != HAL_OK)
" e) Q3 Z) V- A) [3 A- {6 q: f2 A - {+ Y9 R9 R/ h2 Y( W
- /* Start Conversation Error */& M1 \% g' l6 R( x s
- Error_Handler();) L' E" d! d- f
- }$ Z( k2 K# i7 {/ U9 U8 F+ n' |
- HAL_ADC_PollForConversion(&hadc, 50);
& J) h0 E# y( y& e; o7 X$ z2 P- e - /* Check if the continous conversion of regular channel is finished */* s* o" _ n( o* r' H
- if ((HAL_ADC_GetState(&hadc) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)2 A% L0 \4 d: v; _, _9 D
- {
: f8 M% Z- o8 R% e; ~ - /*Get the converted value of regular channel */1 ?( o8 ?4 r9 ~9 j" o( u
- adc_value = HAL_ADC_GetValue(&hadc);
1 x8 b0 J: B( \0 v9 T - }7 B- \# C: h1 @. k7 U* H
- 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
- : u- b7 u+ K7 Q+ v3 g U) C, p
-
' @2 @; |1 K* K0 Y0 _ - /*Start the conversion process*/
+ v4 u4 A! S, {: o% Z4 z( g2 {& S - if (HAL_ADC_Start(&hadc) != HAL_OK)
3 H- N0 q3 S b6 T/ p6 r3 J: C$ [ - {
* A" ]+ s4 X/ _. w) E b - /* Start Conversation Error */, I+ `/ v' `# h- N$ v
- Error_Handler();
( P% H. u& \1 ~/ p2 Q - }
3 N% ], d, Z4 q& d$ | - HAL_ADC_PollForConversion(&hadc, 50);
1 ?% V. P' {3 } - /* Check if the continous conversion of regular channel is finished */
1 A+ f' Z0 U5 `( ^& l. ^ - if ((HAL_ADC_GetState(&hadc) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)9 _1 C5 s; ?6 A$ W
- {
, f: u. J$ Z8 t, [: d - /*Get the converted value of regular channel */
/ l6 |* }, d, ~0 a+ p - adc_value = HAL_ADC_GetValue(&hadc);
$ r2 V, `8 M7 t1 ]8 W" U' {5 S - }0 N% w$ g X( Y9 m
- 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 - ) ~5 q/ G- ?4 y0 F; _
- 5 M- T- T' l+ g, _6 Y
- /*Start the conversion process*/
" p1 d7 R8 S4 l - if (HAL_ADC_Start(&hadc) != HAL_OK)7 }( q& q G8 L, |
- {
; e, `% M4 J5 M: e4 } - /* Start Conversation Error */
, t9 Y* V" b3 l% h* O' V' ` - Error_Handler();- R: V+ A; U, U3 @9 v) y
- }2 {6 L; C0 J% y7 R8 c
- HAL_ADC_PollForConversion(&hadc, 50); O/ [3 _$ Z2 d3 m! F7 J5 h
- /* Check if the continous conversion of regular channel is finished */, d2 a" g, p: J6 @& s
- if ((HAL_ADC_GetState(&hadc) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC); h- k ~- ~( ^" x$ w
- {
`( w2 O/ B- w6 y - /*Get the converted value of regular channel */+ p8 M9 n' h0 y& @6 c+ d: h
- adc_value = HAL_ADC_GetValue(&hadc);
# e: O& G1 p) g& A1 s+ g - }
5 e2 Q1 Y; U x9 |9 ]( @5 K3 I% w6 R5 k" t - printf("DEBUG: ADC CHANNEL 17 = %fV\r\n", VOL_RADIO*adc_value); //内部Vref = 1.2V
# o7 i, ~% ?. ^, } - 9 [1 I7 w1 `9 o2 c' Q# _* C6 D8 E
-
/ M+ {, p" l1 F6 y - /*Start the conversion process*/ ! O1 M t2 C$ J
- if (HAL_ADC_Start(&hadc) != HAL_OK)5 l6 T7 R. X, \2 n4 j+ |9 u
- {
' M1 z/ e- V( C1 D! S; @ - /* Start Conversation Error */
% I& r5 X" [8 t - Error_Handler();4 }' _$ y4 @* u) G
- }
' h5 I9 L/ _( v& {5 g/ r# M% { - HAL_ADC_PollForConversion(&hadc, 50); _& Q! g; k7 H$ o' u
- /* Check if the continous conversion of regular channel is finished */
! ` F( R3 k3 `& D" _& M. m& T - if ((HAL_ADC_GetState(&hadc) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
7 m1 v `! q. j% g! |% U5 d, T - {' u2 M% o5 i* L0 h
- /*Get the converted value of regular channel */# [5 w {6 |5 O% o. m3 P) ]- r5 N
- adc_value = HAL_ADC_GetValue(&hadc);7 w. E" `. L0 M u6 U' v2 j
- }; g/ |. T. ^2 B# I
- printf("DEBUG: ADC CHANNEL 18 = %d℃\r\n", ComputeTemperature(adc_value)); //内部温度传感器6 C. t, ?* G6 a B4 S
-
, J6 E% H% N" a( \/ W - HAL_ADC_Stop(&hadc);
/ r. _) U1 m/ o9 a
: s0 r* [! c) _ L+ v- }
复制代码 * T7 o; q0 p- W. P, q6 Y2 x- p! X. h
3 e( f2 u o. q. V$ ] K3 b8 r# |
|
ST 给的很多历程太复杂,其实大家的应用都很简单。
楼主这个怎么报错呀