开发平台:KEIL5! W& D$ D$ m% \: d$ w+ m! N* o( |$ n; M
, r0 H V+ D- b0 w+ j; q- |芯片:STM32G031, Q3 u( ~0 n: ^- w/ V) @/ b
; P% y& ~* u. M; H" j$ U
描述:近日使用STM32G031给客户做一款产品,在使用ADC时出现,采集的数值一直为0的情况。分享给大家。
9 Q# Y$ C* T2 M' T3 L3 t9 \# n& E( b' o( }, v
使用STM32CubeMX生成代码。配置ADC引脚,PB0为ADC1_8,PA11[PA9]为ADC1_15.
4 v. P, ~/ l4 y& M) k0 Z( k* G& y( e
- H, o$ b* i' Y
' J8 F& g8 H5 |! ^9 C: i: G8 k. |生成代码如下:* ^- z* d* d0 e2 D7 [
+ j. L$ m. i. b, E- ~ |) z
- int main(void)0 _5 ^! E0 P0 i. Z! m* x
- {
( W; m2 v( g- A/ G0 T9 ]4 f - HAL_Init();+ A6 q& }4 n: f! _9 E4 l
- SystemClock_Config();
& n: ~+ X5 J9 m - MX_DMA_Init();
1 V) U7 m8 \8 w7 e - MX_ADC1_Init();
; K& J s( b- H& w/ b- m - MX_NVIC_Init();: k% N$ L% a3 h2 R( q+ \
- HAL_ADCEx_Calibration_Start(&hadc1);3 p$ w. s" n0 x$ J
- HAL_ADC_Start_DMA(&hadc1,(uint32_t *)&adcbuf,2);
0 Q2 I1 a+ Q+ f" J0 b3 D. X% C - while (1)
5 \ w/ Q( {- S$ A- J - {% I, I; M/ a6 S5 E' K
- if(get_sys_time_us() % 1000 == 0)8 v0 Q/ H: W9 X) o
- { 1 ]# q0 n" B6 q9 R* j
- printf("adc1 = %d\r\n", adcbuf[0]);
. \" F% f# O$ p - printf("adc1 = %d\r\n", adcbuf[1]); T/ K; H, Q$ `! ~" e% k6 R
- }
8 W2 _2 \7 `& Z. [5 K
7 \/ F- y0 m7 a- }
复制代码- ADC_HandleTypeDef hadc1;
S1 x$ q9 e( Y" a; \ - DMA_HandleTypeDef hdma_adc1;
: ?; I+ v' Y+ O! `- n/ p
1 l1 z; B9 Z& j2 q- /* ADC1 init function */
8 \8 o8 c/ E, \3 s" s$ T5 m - void MX_ADC1_Init(void)
9 g- s8 q; R8 S% ~6 M - {( Z- c* z% X+ i$ i9 G a
- ADC_AnalogWDGConfTypeDef AnalogWDGConfig = {0}; y* z9 j% k/ k
- ADC_ChannelConfTypeDef sConfig = {0};
6 w# ~. [4 I/ F+ b$ w - ! C! D$ n d. ^! T6 y
- /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) * j0 }) u. P( ]" [: d, J
- */' }% h4 }" J8 p( q4 {
- hadc1.Instance = ADC1;6 h$ d! \& _" `4 K9 K
- hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;. J. v4 f f& l( G# V
- hadc1.Init.Resolution = ADC_RESOLUTION_12B;% b# O8 T a2 r; h5 W& O
- hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;) w; @' v' i/ e m5 E8 ^
- hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
5 O4 O( v0 n Q f X. d - hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
6 y$ j) f1 J. _" L: {% [ - hadc1.Init.LowPowerAutoWait = DISABLE;( F) s- ?! F# g
- hadc1.Init.LowPowerAutoPowerOff = DISABLE;) v7 c/ l* X9 r$ r' U h# ]
- hadc1.Init.ContinuousConvMode = ENABLE;3 G! k+ D2 ?% |; J0 I0 v( D
- hadc1.Init.NbrOfConversion = 2;
+ G! Y, t2 F2 r9 @! n" a5 h" q - hadc1.Init.DiscontinuousConvMode = DISABLE;. p, C: A4 m2 _; o: i6 C
- hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
9 o0 [5 d2 B7 \% |9 p& \; U- _1 k - hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;+ q: v/ a3 K/ ]' e. s* S
- hadc1.Init.DMAContinuousRequests = ENABLE;1 Z/ o9 K0 ^: J
- hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
8 J5 X& D0 ]. c/ J. `4 Y- \ - hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;
; Y: Q% q/ t4 k) s - hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;5 n/ b- Y6 w/ v. ~; r2 e/ p
- hadc1.Init.OversamplingMode = DISABLE; }' |! Q7 W+ O( P( o
- hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
/ {4 B: N \3 n0 c - if (HAL_ADC_Init(&hadc1) != HAL_OK)
( e) ?' ?( V3 D% A- P; W - {
1 ]* y* D8 Q6 P0 L0 B - Error_Handler();
% w u- k; W$ S7 {3 t$ x) n$ |+ Z5 f - }
0 l/ C8 U& ]& K! X6 q$ R. v - /** Configure Analog WatchDog 2 - `2 W# l1 U/ z+ G8 y& l* A
- */: s2 h, X1 t6 u3 ^
- AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_REG;
( `5 R3 E5 }8 E( o8 c) v - if (HAL_ADC_AnalogWDGConfig(&hadc1, &AnalogWDGConfig) != HAL_OK); ]' ?7 J% p& d" h7 W
- {
9 _, V, ]# q8 J/ \6 |; x - Error_Handler();
7 L, p3 i/ I! i8 B3 e* z- W } - }* H; W7 B% I5 @
- /** Configure Regular Channel : l$ n. \' h# A, D
- */9 k7 ]9 @5 Y1 M
- sConfig.Channel = ADC_CHANNEL_15;, `# ^) K+ {- Y/ Z) ^
- sConfig.Rank = ADC_REGULAR_RANK_1;8 s1 G* d! o% Z
- sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
2 l/ b8 C8 t1 ^0 P! u1 b/ r. o8 a - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)0 ?% L$ p" a& u, n1 [
- {
; y. P! c7 o+ J, h2 B8 i - Error_Handler();
( h( ~/ X B5 Q. e- A - }4 F; I: D' e; f8 x9 g
- /** Configure Regular Channel : l) ^# y/ Q% ~8 T! t
- */
% `1 z. E# Q' \2 c. Y - sConfig.Channel = ADC_CHANNEL_8;
& J9 \6 n. s% ]! D" ^+ U, _* T9 | - sConfig.Rank = ADC_REGULAR_RANK_2;
/ R; C3 n: {& p, z( r - sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;
6 W: b: V$ F" g2 ]7 S6 I% B8 _* ^" { - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
5 w: |2 x0 B) M9 f Q _ - {
0 G8 D. ^" j: H! X0 o: x* w - Error_Handler();
4 I* c8 e3 s! y6 O& J - }
4 n! P) _; m6 o* q. D9 ~% h
7 o' _) u1 F, W$ t5 t2 A( S- }+ f7 n W* b9 t5 m( @
- 1 ]: D# w( F) w2 s
- void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
5 H* D# E/ @; q) v0 ?3 N, [ - {1 ]& B- k$ y y/ o4 S/ V) v* ], h
4 w9 k0 t; B( ~. t- GPIO_InitTypeDef GPIO_InitStruct = {0};
9 L: N; p4 i1 q7 n - if(adcHandle->Instance==ADC1)
. I% q$ }. w$ W8 y- r* l - {1 W) F( ^. _. a2 R" L' a7 H
- /* USER CODE BEGIN ADC1_MspInit 0 */( q8 K2 J# o8 T
1 H% l+ M$ K, j( c% R& C9 a0 W0 Q- /* USER CODE END ADC1_MspInit 0 */+ j, F' ~, A* B
- /* ADC1 clock enable */
( P% Z9 L% z2 B" k# j* m - __HAL_RCC_ADC_CLK_ENABLE();+ Y: ?& f5 m+ n% W: Z4 }* b' v
0 `/ |6 l$ i) Y4 j- __HAL_RCC_GPIOB_CLK_ENABLE();- Q( L( b7 n; {- x
- __HAL_RCC_GPIOA_CLK_ENABLE();
6 r3 Q, P0 u6 k' n4 m/ Z - /**ADC1 GPIO Configuration
2 \* h3 ^9 i0 Q- D: r9 s+ p5 X - PB0 ------> ADC1_IN8
1 R/ j' U; |, h* `' x4 m - PA11 [PA9] ------> ADC1_IN15 6 |$ b9 W0 l" v0 H
- */1 k9 V0 S1 w' q: L9 o
- GPIO_InitStruct.Pin = GPIO_PIN_0;
2 p4 @: ?. F, h; Z - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;1 Z2 e& H: r' w& a7 n) O
- GPIO_InitStruct.Pull = GPIO_NOPULL;6 v3 i3 c/ S |3 S7 }* n
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
( c( Q @+ G& g p& R. Q9 K5 \& t1 d
, z" r. X. n' d8 n" h" G8 [- GPIO_InitStruct.Pin = GPIO_PIN_11;: p, Q! I2 H- R. c5 F# R1 N
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;% ], R. A7 ^ V1 h; Z
- GPIO_InitStruct.Pull = GPIO_NOPULL;
; W7 O1 k; d, Z- F4 U; j3 \ - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
, ^, i& y* `1 j g k
! R6 v7 p, G. U+ d" W- /* ADC1 DMA Init */
+ N6 P6 p9 K& _: v/ C. \ - /* ADC1 Init */7 j3 v9 k# t( ~6 C2 L
- hdma_adc1.Instance = DMA1_Channel1; {# @' m; n" E% W+ m0 E/ M
- hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
- L/ Z" ]1 ?) g" M& e4 d" E - hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;3 `( Y: y! q( b
- hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;; Z* c9 v8 a' |
- hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
: n5 y0 K4 q! v+ I. g0 e* V |* B - hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ Q, x! S2 ~/ R4 Q - hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;5 h& L8 v- ~2 H
- hdma_adc1.Init.Mode = DMA_CIRCULAR;
! P4 J6 w, V, f$ \$ W/ v - hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
# _7 G, [, @) M4 ?$ D) w - if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
7 ?( {' l4 I7 S7 _7 L* z) C | - {
5 T( r. a4 q+ G' Q - Error_Handler();
, E) S" Y+ a5 B6 N! R o - }
0 C& C2 W& I0 b b! y" D - 9 w1 R) ?# a5 b! j- o; i
- __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
* M% ~; L% m2 t% l - . K5 e" A2 j" e8 }! \9 j; u
- /* USER CODE BEGIN ADC1_MspInit 1 */
, l: P- I( f5 Y' d+ M
4 }8 r* m- \6 j( I( _: k- /* USER CODE END ADC1_MspInit 1 */
1 E* Y; S6 J* [& k8 ~ - }
/ ~' B% `% ]' r+ R& z! W - }
复制代码 / R5 y+ D1 e& k. ^8 E! t
把STM32CubeMX生成的代码下载到芯片中运行,结果ADC1_8的值可以读到,但是ADC1_15的值却一直为0.
- ?& K$ n4 {: m4 d: t) L+ A7 j5 M: i% W
出现上述问题的原因是因为STM32G031的 ADC 序列器配置成完全可配置时,只能使用通
# E: R" a, _$ N! m道 0-14,不能使用通道 15,16,17,18;所以在有使用到通道 15,16,17,18 的情况下,ADC 序列
* j& @' S$ D3 v! q0 c) j M器要配置成不完全可配置。Sequencer 选项选择为:Sequencer not fully configurable
8 s7 o6 c2 z" v9 J$ ~如果是多通道则 Discontinuous Conversion Mode 要使能/ C/ {( N2 g9 C
, r- {9 l J, l6 U+ m8 G* o/ r
# f j) R# u3 [( \! j. h |