开发平台:KEIL5( R9 q# e; V0 @! c/ S
7 g o% b2 Y V [( n4 P
芯片:STM32G031
/ ^& l. ^/ s1 M: R5 T) t. n
. Q2 M, V+ F8 S) A* Y3 q描述:近日使用STM32G031给客户做一款产品,在使用ADC时出现,采集的数值一直为0的情况。分享给大家。( ^! m( E! ]- N
$ d y) s) K: Z o使用STM32CubeMX生成代码。配置ADC引脚,PB0为ADC1_8,PA11[PA9]为ADC1_15.
5 w$ u I1 s, Q: V K$ j8 n* y- Y0 z3 Y
5 M5 P* S( _4 ?& K9 B( q
! R8 z' u& `. ?, D" V
生成代码如下:) U/ `/ ^3 f0 s4 U8 f
" o9 Q7 x& b" M$ v1 [. j- int main(void)
9 }( s0 v. a" k2 K9 t1 { - {
# M8 h& t0 J' p: D/ U - HAL_Init(); d/ q4 S0 i$ R. `2 w
- SystemClock_Config();
$ _+ x4 U: B; ~: V6 @4 x - MX_DMA_Init();
* Z3 P) L; S$ I. G H$ u - MX_ADC1_Init();/ t" e: F( f% _" N* k
- MX_NVIC_Init();( m; q1 V" h! O. h! w* M
- HAL_ADCEx_Calibration_Start(&hadc1);7 l* \+ s3 S; }( ~
- HAL_ADC_Start_DMA(&hadc1,(uint32_t *)&adcbuf,2);
/ b4 l. c. N" e2 p4 @& ]3 x6 D - while (1)
; d2 Q: W% M. n" O2 f1 e; q - {
0 l$ d* e* D) X( A! U1 Q9 H0 I - if(get_sys_time_us() % 1000 == 0)
0 P$ {% f0 ~7 z. N6 t4 w9 Z - { $ B; G$ f- b7 r8 `" v
- printf("adc1 = %d\r\n", adcbuf[0]);
6 C! r* R* A8 x7 \- p T - printf("adc1 = %d\r\n", adcbuf[1]);
; |/ X) @3 W( w* \$ U; ] - }, P9 m; `( [0 Y/ X4 ?+ z
- - y- }' u+ b0 H. h
- }
复制代码- ADC_HandleTypeDef hadc1;3 z' y- V) U+ Y, O# b, \$ T+ M
- DMA_HandleTypeDef hdma_adc1;7 N/ c% {) w& P2 K$ H9 }
/ N( r' M7 f: h- /* ADC1 init function */
! r4 k+ _; [' ?0 B9 c, C - void MX_ADC1_Init(void)& J% q* Z8 m" z N+ E1 X+ U2 G
- { P# T5 g7 w1 f
- ADC_AnalogWDGConfTypeDef AnalogWDGConfig = {0};
( g# G4 m3 A6 {+ Q - ADC_ChannelConfTypeDef sConfig = {0};
4 G4 V% d- b* G - # v: {' u7 k- w$ Q% B
- /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
* _, W, E- z9 A, J. @. {3 d/ s9 v - */
5 y. \0 t/ \2 q( T& l - hadc1.Instance = ADC1;
" |$ m. A) A* @. o - hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;& B! g0 c! l: M! R, x9 C
- hadc1.Init.Resolution = ADC_RESOLUTION_12B;
& n$ c* |# w- F* A! F; Z- A - hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;, L. }( g( b7 D( ?- I
- hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
, S; }9 @' d* V: ^! j3 D - hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
* S) g4 j5 L8 F" G% s - hadc1.Init.LowPowerAutoWait = DISABLE;' n8 t7 u6 N* A2 G; J: F( r# D6 o
- hadc1.Init.LowPowerAutoPowerOff = DISABLE;
W4 b! T. W2 {- ` - hadc1.Init.ContinuousConvMode = ENABLE;- c, s% q8 B$ Z5 y1 o
- hadc1.Init.NbrOfConversion = 2;
( L# G! ? X# k3 K2 k - hadc1.Init.DiscontinuousConvMode = DISABLE;
) g$ E$ D# G1 z7 T - hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;5 T8 ~2 @& X) p2 V9 e) z
- hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
- d$ `. v6 H, m8 j& K - hadc1.Init.DMAContinuousRequests = ENABLE;
" H8 m8 n0 i. `3 } - hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;7 U2 e* d) \2 H2 ~# a: h5 o
- hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;; m4 r2 e! E) c
- hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;: F3 s( m/ k& T$ ]) P6 e
- hadc1.Init.OversamplingMode = DISABLE;
" E4 d2 _$ M1 ?( C - hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
' }) B; K0 u& e8 c6 k# z# Y - if (HAL_ADC_Init(&hadc1) != HAL_OK)2 P s! i! q& J) U' {+ k
- {" L/ @; F" b7 }' g8 l
- Error_Handler();
m6 H/ h& n+ @, t; `# Z& Z - }
* _: \1 c+ Y4 N+ U2 O% ^% _2 T - /** Configure Analog WatchDog 2
& r2 H; }0 L' P4 f6 Q+ E - */
) k3 U+ D/ b0 v5 }+ l - AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_REG;* ?1 Y9 E0 e; h, _) @
- if (HAL_ADC_AnalogWDGConfig(&hadc1, &AnalogWDGConfig) != HAL_OK)
. W! T2 B/ x' r9 f3 x - {
# w! ~3 ?" t0 ]+ t' x - Error_Handler();. C% N3 G( u" Y1 N
- }
4 i# q" }3 q- \* L+ y) p3 S - /** Configure Regular Channel 3 C& r8 r- C& U2 T, a# ]% H
- */
' x. W) V! k) }3 X8 ^ - sConfig.Channel = ADC_CHANNEL_15;
& r5 M f4 _6 y5 |. A+ U - sConfig.Rank = ADC_REGULAR_RANK_1;0 a1 }. {+ {8 }6 U) y' H* S/ _8 q
- sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
7 B; X- B2 g% ]* A$ ^( }0 L" v$ P - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
L9 p' A' R: m - {
& m. Q, x- Q! q - Error_Handler();
1 e$ G3 w/ k1 R* V/ S - }
2 d* [5 H1 l7 D, P: P2 _3 t, W - /** Configure Regular Channel 0 [% \& o. U: T" f ~8 [
- */
& `& F" o ^, b( _9 M6 R - sConfig.Channel = ADC_CHANNEL_8;
1 W3 S/ u. \$ I0 f7 e6 [ - sConfig.Rank = ADC_REGULAR_RANK_2;6 U# H+ E. D$ y7 s9 \. t! f: M
- sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;
9 s/ y4 m& g4 k/ {! ^) y1 | - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
: W0 S. _/ u' ?: Q - {
( U8 v1 n) g6 B# y7 C+ D - Error_Handler();% Q( `4 ~% \ ?5 G( t9 P/ K4 s2 K$ f
- }
: J! ]5 s! Z+ k) Z% \ - ( A" Z3 n; x6 [0 Y( u! }
- }
: H, p$ Z4 e" l! r5 t* J - q. j8 ^! J3 F4 I: n
- void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle): w* \( n+ z( a) Z
- {
" j" w `5 \$ {2 y/ u7 r4 z8 e - % g0 h+ V$ e" r2 t% j9 y+ S" \
- GPIO_InitTypeDef GPIO_InitStruct = {0};
3 c1 `' E3 _6 _# ~7 q - if(adcHandle->Instance==ADC1)
0 }% T; ]: @1 Z7 ^( a" ~3 g: M - {5 m; d# H; o. B) d
- /* USER CODE BEGIN ADC1_MspInit 0 */
3 Z3 K% W3 L1 B9 H5 Q
3 x- ?" I! j; L1 O( I" v- /* USER CODE END ADC1_MspInit 0 */: A- E9 ]# c: N' [* Z3 B6 V# n" f
- /* ADC1 clock enable */" h8 g9 _# A# S7 R) [% f- q- u
- __HAL_RCC_ADC_CLK_ENABLE();
' C' U# j" m5 }6 }% X
' x" C& M9 |2 _5 ?- __HAL_RCC_GPIOB_CLK_ENABLE();
9 b c$ N# t$ {9 K6 [( ?. E - __HAL_RCC_GPIOA_CLK_ENABLE();
3 o- p& P2 M% L4 O - /**ADC1 GPIO Configuration
' f& { z. a, J, Z - PB0 ------> ADC1_IN8
3 S# T) R1 l! ]& d+ U0 v: `8 u5 \# Z - PA11 [PA9] ------> ADC1_IN15 ( o. F" ?2 \6 a+ T0 Q6 ~& ~
- */: h0 x) \ v2 V% \
- GPIO_InitStruct.Pin = GPIO_PIN_0;0 H7 \* l/ ^+ C
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;/ q/ s* u a$ [+ G+ h4 L) U
- GPIO_InitStruct.Pull = GPIO_NOPULL;
9 i+ R" N/ K Q& w# d) {& j: n - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
, R% p% J( M+ x6 F2 L. B
- \# L0 p# S% h- GPIO_InitStruct.Pin = GPIO_PIN_11;
+ l3 y. U$ b4 ?: z - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
8 N; V* o" \, O( I5 {7 V - GPIO_InitStruct.Pull = GPIO_NOPULL;
2 E) `* \5 r* {6 F7 @3 W! s- a/ V - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);: E9 C; y( u, b" X2 j1 x. [
. C9 v/ f. ]% c8 S# n8 a" M- /* ADC1 DMA Init */* y# \# }" V$ m% |! \
- /* ADC1 Init */
9 P8 W7 F, E' |% N - hdma_adc1.Instance = DMA1_Channel1;& h% ]4 i! _* s' N: h
- hdma_adc1.Init.Request = DMA_REQUEST_ADC1;4 ^# K# ^) y) x9 d" X$ s- d9 c& r/ ?
- hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;/ T0 h# a0 u" F/ L4 H o
- hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;& |. Q! J P3 j' E7 `* ?
- hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;0 l# w2 R7 r1 }7 Q. A
- hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
; q! D- R5 E# a) [/ L2 ]$ Q - hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
- P& @) i5 n5 B) W, f0 @9 u - hdma_adc1.Init.Mode = DMA_CIRCULAR;
e1 q2 a$ ?: p F - hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;' B" h1 j. T4 `! T( P
- if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)3 c E: M& i# e" M% h. A: z
- {+ w* @' Q$ T' r8 X) c5 B. a; r- F
- Error_Handler();
I# z {& {' ^ - }
7 ] d( K9 e( C/ H4 A( c - # k& J: _) Q- q H+ s
- __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);. `- I& v* s! E) m5 W
- ; |2 a. }7 n9 |% B
- /* USER CODE BEGIN ADC1_MspInit 1 */* n/ ^9 ^7 [3 z/ c# D! ^1 _+ f
- 5 s/ \9 y5 `$ ]3 n: e3 U
- /* USER CODE END ADC1_MspInit 1 */9 @7 X4 a; d4 E
- }1 y, d! S) U4 X+ [; E
- }
复制代码 ; e2 q) E+ t8 Z& m
把STM32CubeMX生成的代码下载到芯片中运行,结果ADC1_8的值可以读到,但是ADC1_15的值却一直为0.
" j. ]' K$ @" |' |9 ]) h. w6 k6 L- j6 m
出现上述问题的原因是因为STM32G031的 ADC 序列器配置成完全可配置时,只能使用通5 p7 d& E% V* d) B
道 0-14,不能使用通道 15,16,17,18;所以在有使用到通道 15,16,17,18 的情况下,ADC 序列) A: _( U( v# r# n. N3 J
器要配置成不完全可配置。Sequencer 选项选择为:Sequencer not fully configurable
* @3 ^5 b0 g' e; {0 J7 y U8 q3 ] \如果是多通道则 Discontinuous Conversion Mode 要使能/ \3 L% J7 C9 W' s, n' K% c7 F
1 t) [0 r2 p, b7 R2 ?$ E8 \; E; Z1 [
. {+ R% Y! e7 Q, `# I5 U. o& n
|