开发平台:KEIL5 r- b( Z/ j4 u2 }( D- T d* W4 @
5 }. V1 C5 c, W( W8 Y7 t
芯片:STM32G031
o# ]: J6 k/ B; P+ y3 e1 X
& m, o1 w& `3 U4 m, B1 U8 {8 ?. P* z描述:近日使用STM32G031给客户做一款产品,在使用ADC时出现,采集的数值一直为0的情况。分享给大家。
. W+ A7 Z+ A0 T' u) ^# F' B: b2 T0 j; Y6 w% f
使用STM32CubeMX生成代码。配置ADC引脚,PB0为ADC1_8,PA11[PA9]为ADC1_15.
) `* [0 n; ^/ g; ~( P9 `7 m0 ^- |- w8 x$ a
' F/ ~1 Z* d0 i- y2 N3 U0 Q
( n5 h" F2 B" a" _3 @生成代码如下:: m, h M* S3 r
' V, K3 R+ g$ {9 f% N0 }
- int main(void)% @8 B6 d |* u
- {- n; `; k2 @- N% A6 W* f
- HAL_Init();* K! x; O. X2 A0 I; w" d9 }
- SystemClock_Config();1 K: }: G% Y* e# l% H* w1 x/ |* j
- MX_DMA_Init();+ g& p9 Q2 \3 {; n9 R: u
- MX_ADC1_Init();
& p+ } m* O/ ]: R0 D7 }8 a9 H - MX_NVIC_Init();
! [6 g& V: d3 T; {$ k" R - HAL_ADCEx_Calibration_Start(&hadc1);& w% e( D) a1 C/ l5 @
- HAL_ADC_Start_DMA(&hadc1,(uint32_t *)&adcbuf,2);
2 a" I' x' l a9 d/ f! d - while (1)7 l4 q5 s# x& ~3 I$ l1 ^" `
- {5 }0 s9 Y* s& q, Z. t. Y
- if(get_sys_time_us() % 1000 == 0)7 A; l2 _# s9 x) B
- {
9 ]; l3 p; l2 _3 L& j3 _ - printf("adc1 = %d\r\n", adcbuf[0]);
/ {! Q+ g; H! x. I - printf("adc1 = %d\r\n", adcbuf[1]);9 F: C2 d7 c7 e) u# _5 K
- }# x8 a) ?/ N. }3 G/ z
- : i7 g' F" P! k6 V0 L# \
- }
复制代码- ADC_HandleTypeDef hadc1;5 P( K/ Q$ x1 n0 D
- DMA_HandleTypeDef hdma_adc1;
: D0 H, N K' Z- ?
# N ^% g5 g M; h- T5 ~- /* ADC1 init function */
2 x& T7 r8 }& d4 F! | - void MX_ADC1_Init(void)
/ _) P1 Y5 J- S5 U! r! L - {
/ [+ S# | r% Z6 X) W - ADC_AnalogWDGConfTypeDef AnalogWDGConfig = {0};
. h% f8 ?- w1 [7 o* c - ADC_ChannelConfTypeDef sConfig = {0};
% G! g5 ~# ?0 w - 9 ^; A% e/ y+ \% l
- /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 9 t8 a, U! u+ [0 A
- */
' c5 j: R1 _- c7 a# e/ }' I - hadc1.Instance = ADC1; e" S4 S0 w L- f l$ i# q* Y `
- hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;/ C$ Q! x* q7 c2 l
- hadc1.Init.Resolution = ADC_RESOLUTION_12B;
8 k8 t# `- F% I' G/ {; z( j, b; Y - hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
0 v; f/ R' Z8 y3 T0 }2 G3 b - hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
+ l. V0 x1 W& g; _ - hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
5 q e# I) V( q7 u7 c. S( c$ ~, L9 H - hadc1.Init.LowPowerAutoWait = DISABLE;
3 P% `# w% g. h, ]& X! C - hadc1.Init.LowPowerAutoPowerOff = DISABLE;
?6 f: T, y: A" {1 U% F8 } - hadc1.Init.ContinuousConvMode = ENABLE;
3 d* a5 r a- g - hadc1.Init.NbrOfConversion = 2;3 H& L6 Z! ]6 U. P# i" X
- hadc1.Init.DiscontinuousConvMode = DISABLE;
8 Z+ L g* U/ y- L8 p1 A - hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;4 t, }7 [* S1 r+ H0 `
- hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;. L; S- V5 O) Q0 j+ J" r9 z# C
- hadc1.Init.DMAContinuousRequests = ENABLE;
( }& h. S# b7 b! J9 G7 t9 C) r - hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
5 |$ o5 T3 M# G9 @- L3 O - hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;* ~' v$ r: l2 f/ K; V
- hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
8 C* O% ] S) T - hadc1.Init.OversamplingMode = DISABLE;
/ S+ F5 m" D, \! X7 } - hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
% T! r( }7 O- n1 V. j3 L0 o - if (HAL_ADC_Init(&hadc1) != HAL_OK)
( p! {- X l$ c - {6 a7 V6 M. d* ]0 a+ S. t
- Error_Handler();2 r7 Z% I' ^5 w p) @* k+ Z
- }; S T k9 S% ?
- /** Configure Analog WatchDog 2 & z3 R. |; l/ S M; v
- */ w# i% g) u! A: l! |
- AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_REG;/ Z8 H2 O( m) C$ G1 S" X% R3 X
- if (HAL_ADC_AnalogWDGConfig(&hadc1, &AnalogWDGConfig) != HAL_OK)
3 ~8 D' H( g0 Y: D. K- u3 {8 {" B - {
' B4 B8 F1 g) _* w5 [ \% @, ? - Error_Handler();
* D ^: |' L) n) a S - }
9 L( Z0 s& z) Y! X - /** Configure Regular Channel
8 a. L9 ]$ q4 p - */
8 l; x) d( X6 C" w - sConfig.Channel = ADC_CHANNEL_15;7 ~+ m3 n- \& e, b
- sConfig.Rank = ADC_REGULAR_RANK_1;0 ^( K# U* A/ q: v5 O
- sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
; o: Y0 e y% W5 d O. L: ~0 X1 f - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)9 y# a4 N2 r& {/ R
- {4 D3 G7 B5 T( G+ U) D8 o
- Error_Handler();1 `6 G; G% }3 N/ D' D. j* E- w& p
- }7 c$ o; X4 ^& n9 \0 D, F0 n$ {: b& [
- /** Configure Regular Channel
m6 f$ z; m* p F2 { - */
$ a, B: @% ^* [ n4 s - sConfig.Channel = ADC_CHANNEL_8;' Z5 j4 d# }, E3 C/ {6 s
- sConfig.Rank = ADC_REGULAR_RANK_2;
5 v' h5 \/ e2 L4 ~: z( Q" z0 _- o - sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;, F8 t, S/ f; k1 u4 X$ S% m ]
- if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
) z9 s5 U3 ~3 G- I+ I2 U - {
/ v- h$ k& l$ ~ - Error_Handler();7 P+ E6 J h) ^) b/ O# Y3 H2 F
- }$ Z( p" m9 a6 `9 S4 A; D% ?- U
( @& \8 \, x1 q( n% o- }
- W* [; ~7 p8 z6 N! J% | - 0 J( x0 V" h4 }, G% z( s t$ a
- void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)" x: l/ G% z( h$ e/ C& i7 A
- { x9 _ B" C# `6 d
- 6 M* x# U# O) H1 s7 u9 ~4 o
- GPIO_InitTypeDef GPIO_InitStruct = {0};
7 C2 q- Y$ }# W% w& S, @* }6 m1 R4 [ - if(adcHandle->Instance==ADC1)0 P y; n/ h. k( D% q% t( [
- {, d, ~! r1 y* d2 X
- /* USER CODE BEGIN ADC1_MspInit 0 */
, h5 |. e! u* _) c% [ - : W0 V4 p9 [ D
- /* USER CODE END ADC1_MspInit 0 */
0 I4 @3 m1 s( Y8 y% ^0 k - /* ADC1 clock enable */% P8 [% B7 d% y8 V4 H- z. S3 u
- __HAL_RCC_ADC_CLK_ENABLE();
2 ~* j" u& A; m2 P
4 t3 e# c; C. y: ?4 ?' k- g- __HAL_RCC_GPIOB_CLK_ENABLE();2 r8 P' o7 d* x- p0 ^( b$ j
- __HAL_RCC_GPIOA_CLK_ENABLE();
8 J; l7 p! c& S q) r ^ - /**ADC1 GPIO Configuration : p* B' J; [* ^5 Z7 B% Z. Q4 t N. `
- PB0 ------> ADC1_IN8
]; c' i! n/ m9 y. S - PA11 [PA9] ------> ADC1_IN15 0 u3 ~+ i: `' \
- */% _& ?3 D8 a6 O5 V- ~
- GPIO_InitStruct.Pin = GPIO_PIN_0;
& J; V- I- N5 H( |% F - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;, R, b$ Q( @6 Z/ D9 c/ s R+ c
- GPIO_InitStruct.Pull = GPIO_NOPULL;: s; M) K: ?& s4 w" ]
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
8 o3 q: n! V( S
/ g& l, C& b6 X0 D L0 m- w- GPIO_InitStruct.Pin = GPIO_PIN_11;
: b3 _; z9 w6 ?9 o5 g4 P. W7 B - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;+ H( V5 g$ O6 j
- GPIO_InitStruct.Pull = GPIO_NOPULL;3 h# j% E- g* q$ B
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
; ~* _0 w' ^) D% F
0 I, }' a" F \( X- /* ADC1 DMA Init */
6 x! F& t0 k- M1 \ - /* ADC1 Init */- `$ i5 ?6 B+ X2 v
- hdma_adc1.Instance = DMA1_Channel1;5 K3 H! G z4 P; e/ m
- hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
$ p: _( A4 j7 |/ S1 f% |# O) | - hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
, m1 z7 w# R5 O. C: f. S - hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;# f5 U P B( @' K7 y
- hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
' d/ t% A% |5 F. _ - hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;7 Q9 ?1 E* u9 ?- A% [
- hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
' a M/ x8 `! }/ U - hdma_adc1.Init.Mode = DMA_CIRCULAR;- `# s# S1 e. ^! V, V6 L6 Z: _5 T$ T
- hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;" t3 N/ a8 r4 P; F
- if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) b% ~1 z, R9 e
- {
* s% j f7 ^) U* r$ h, ] @ - Error_Handler();
2 m7 S" Z" u* |) u - }
* d- R2 S/ J& n. U V - ) i9 P U- U& E4 {
- __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
2 f* W0 T) ]* I: i. o4 O - 9 X( R+ M+ X0 b3 b
- /* USER CODE BEGIN ADC1_MspInit 1 */( [: n, D5 i$ |& g& L; x
, B4 t( H# E$ j4 f# m- /* USER CODE END ADC1_MspInit 1 */( C* f) @' b+ o* c) r
- }
- k4 P6 x% k8 I$ }& Z - }
复制代码
( ^; T7 N# T' @6 I7 k把STM32CubeMX生成的代码下载到芯片中运行,结果ADC1_8的值可以读到,但是ADC1_15的值却一直为0.
3 ^+ H- B! w6 a+ ^, d& @+ U7 l# @! q9 A/ B( V2 n G, \# N x
出现上述问题的原因是因为STM32G031的 ADC 序列器配置成完全可配置时,只能使用通
3 ^' Z) U: ], s$ ]* f( o& ~道 0-14,不能使用通道 15,16,17,18;所以在有使用到通道 15,16,17,18 的情况下,ADC 序列% W* ] a! k+ C4 a1 t
器要配置成不完全可配置。Sequencer 选项选择为:Sequencer not fully configurable
+ p0 ~ W) u: n5 ?5 g如果是多通道则 Discontinuous Conversion Mode 要使能2 [1 b, @6 S) e; h, Y( k2 T0 n% K9 G2 M
8 a- S! K4 g4 e. F% y7 Q0 X1 g% Y; U: \3 |
|