开发平台:KEIL5
& G# j; m' t$ t7 b. g2 x2 y# E# m2 G7 [3 _0 e' l- v- l' `
芯片:STM32G031* k" l( Q9 I" R7 r- V* W! p
$ E/ w/ w( ?( _* \( o
描述:近日使用STM32G031给客户做一款产品,在使用ADC时出现,采集的数值一直为0的情况。分享给大家。$ z, t+ w) k# ~0 O. p1 O1 F
c n) j9 q9 d# R4 J4 s' ]
使用STM32CubeMX生成代码。配置ADC引脚,PB0为ADC1_8,PA11[PA9]为ADC1_15.
. m( U5 J5 m8 P: ?, S7 |2 K6 {: O8 o+ O6 \7 M: j' `
3 Y$ F0 s! ]. N+ U2 L+ v% s% j
" s) M2 I! u) f# I* q
生成代码如下:
7 {- E" t! p# R7 o0 v0 X/ Z# I1 V
8 F q" F& U; a$ M$ ~- int main(void)
$ O& x+ s! C4 b' y0 s9 o! \4 W - {
# s9 c4 i9 C; e% } - HAL_Init();
! N) r9 y. ~' D% _* B - SystemClock_Config();
8 Z' ^, N$ ?8 Y; [. Q/ ^7 w - MX_DMA_Init();
; Y, O" V& x# B3 w/ h r - MX_ADC1_Init();
7 Q$ c; O* ~$ x% J* a - MX_NVIC_Init();
& X* L0 E6 j7 b7 m - HAL_ADCEx_Calibration_Start(&hadc1);
( y4 o& k' H$ r - HAL_ADC_Start_DMA(&hadc1,(uint32_t *)&adcbuf,2);
) l$ g! d( |% n; D* o - while (1)) G- s2 a1 A$ X1 s8 h) `" ]# \* Y$ m* r8 _
- {
" D" @1 j+ O( w& W! }. o; l - if(get_sys_time_us() % 1000 == 0)4 y6 R9 V6 d4 D9 W# a) F- F& O; Z5 C* z* q
- { $ \+ T/ j4 m& h; s. a
- printf("adc1 = %d\r\n", adcbuf[0]);
( d7 q3 { V' p- q$ E. B - printf("adc1 = %d\r\n", adcbuf[1]);
8 b" I1 T. v; R( D" w9 M3 B9 b - }
6 u) D4 N0 f/ w. S/ l6 E- g6 A0 Y
4 H7 @1 J+ X! x# @$ J- }
复制代码- ADC_HandleTypeDef hadc1;2 I2 p% e1 N# g$ V* T
- DMA_HandleTypeDef hdma_adc1;
6 z* X5 G+ n3 z6 U
! |& J& B( k- w* ]- /* ADC1 init function */: P' E" X4 }9 Q2 K
- void MX_ADC1_Init(void) e! ]8 u2 W% m3 }& Q
- {
) ?& P8 ]2 a, e' D - ADC_AnalogWDGConfTypeDef AnalogWDGConfig = {0};
: C9 y, x- b! G/ v6 B - ADC_ChannelConfTypeDef sConfig = {0};! u5 J' p+ c% [) A2 n
- 5 p8 E. r1 Y' Z% \" N8 @
- /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) ' @' Z( q) \1 c u |
- */
4 Q3 X/ s6 n4 {/ i) N0 r; O8 r - hadc1.Instance = ADC1;
& U* x5 M& L3 e! t$ c - hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
9 w1 H% D& {/ ?# S; l% @2 i# e% u - hadc1.Init.Resolution = ADC_RESOLUTION_12B;& T1 Y1 s. ~/ R% k$ Y; ~$ }
- hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;6 B4 S9 ]! w# M& t: r+ T% K
- hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;" O7 |. ^) E, e* u, v* I L" j
- hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
4 A; j9 f6 m+ e1 M) o$ D! X - hadc1.Init.LowPowerAutoWait = DISABLE;8 U* A# U) p# Y( U, `" n: v. p2 I
- hadc1.Init.LowPowerAutoPowerOff = DISABLE;
! H6 T4 ?- M! m$ Q2 x& P - hadc1.Init.ContinuousConvMode = ENABLE;
' x+ u+ e7 Y7 y# j! a - hadc1.Init.NbrOfConversion = 2;
+ V+ z4 O: I# z& W/ p$ | - hadc1.Init.DiscontinuousConvMode = DISABLE;6 q A4 {0 N; U% f, H9 d
- hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;& _+ C/ u0 s- T0 E7 h! g
- hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;( l% S4 |& i( g0 ^$ D3 [4 _# @2 c
- hadc1.Init.DMAContinuousRequests = ENABLE;$ z: c, U& y/ P9 `, q' Q+ ?
- hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
3 Y% V% Y1 H: i' h, s - hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;
: w8 A& s1 p8 @ - hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;6 `5 E( s6 g, I0 g& P5 C5 W
- hadc1.Init.OversamplingMode = DISABLE;
& r) Y* I2 L* U7 M8 i - hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
& w% C! ]% g: {3 P* w4 L: T% g - if (HAL_ADC_Init(&hadc1) != HAL_OK). y# q5 s+ E9 l- Q
- {+ a7 ?& p% N- C p5 V
- Error_Handler();
! }/ _' P2 n- Q4 Y { - }
# f6 }3 o$ o+ G0 U$ ^+ | - /** Configure Analog WatchDog 2 % Q* ~( F' ?, m; P' |
- */1 P- _- K- V# |4 E* v- e' H
- AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_REG;/ ~( }) g/ o7 c3 S
- if (HAL_ADC_AnalogWDGConfig(&hadc1, &AnalogWDGConfig) != HAL_OK)
$ u9 T5 E, P3 M! J0 o - {. A3 F0 x7 S' T
- Error_Handler();8 O0 u, d3 x7 B. L% U" j
- }" T" N4 S$ n, Z6 Y' ?0 T
- /** Configure Regular Channel : t- G J/ v. G f2 u, j
- */
$ d. m; J& K$ m7 h - sConfig.Channel = ADC_CHANNEL_15;
4 q3 J$ Z* Q2 ^! w) K9 S# q - sConfig.Rank = ADC_REGULAR_RANK_1;
) Q; L6 A' T$ e* w - sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
( p; x& E* e1 s - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
! R- ~4 A3 Z0 G - {
7 y' O3 w" B" n - Error_Handler();2 {2 s; @5 Z6 ?9 c* U! R$ h
- } _" H3 g% T+ A+ m0 b! l7 |
- /** Configure Regular Channel & t6 a" Z+ b |$ L. x" T
- */
; d! R3 j) A9 V# `* ?5 _ - sConfig.Channel = ADC_CHANNEL_8;
# ~( m C& y/ J$ r. `' n - sConfig.Rank = ADC_REGULAR_RANK_2;
3 B1 T/ b8 l9 e; Q - sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;1 r3 R- G; d; x9 K e6 I- \" R/ O
- if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)$ \5 G! p+ f: e9 h3 }1 p
- {
2 i' D; P% [# U* h3 N1 ^, o9 @: G - Error_Handler();
0 F) H& B. r! @/ r, L" F4 Y - }
& g+ i( }) a# U' F2 l7 D - : b8 ]/ m6 ]# `" e* i
- }3 w+ o0 w# P: D! f& Z6 a
- / a* | R* h" r4 x
- void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
! K n% W' u. {6 I/ ? - {! l* X' ?5 P6 A7 H
3 i( W* ~) f5 a- GPIO_InitTypeDef GPIO_InitStruct = {0};
y1 i* G- Z: |' e: P - if(adcHandle->Instance==ADC1)
! C1 i2 v M, ~ - {, s6 |' u. ^7 p. b# v5 V
- /* USER CODE BEGIN ADC1_MspInit 0 */- {9 C+ v) A+ j; C7 p
- 4 f+ j- ~# x m1 P
- /* USER CODE END ADC1_MspInit 0 */
. e( n' C* a& `. e! ~2 x! w( b" s* O - /* ADC1 clock enable */7 O# N9 `& F6 t' `9 A1 ~
- __HAL_RCC_ADC_CLK_ENABLE();
( V" C$ h, K+ w - 6 g$ g; s' c: g! q! e! n
- __HAL_RCC_GPIOB_CLK_ENABLE();
9 S' h: n: C, ?* B, d - __HAL_RCC_GPIOA_CLK_ENABLE();
% b( h* d4 X* ] - /**ADC1 GPIO Configuration
1 k- ~. u! h8 B - PB0 ------> ADC1_IN8
9 [- c' Q& Z8 N% Z# j5 J$ d1 h - PA11 [PA9] ------> ADC1_IN15
9 n" P* T& w! u; t/ Z9 U - */
2 ?) l: V- W' V: e2 Y- L; E - GPIO_InitStruct.Pin = GPIO_PIN_0;4 L+ g1 k9 g: T0 p: q' @/ A2 Y, K: ?
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
- ?) w1 [$ G' g0 F7 [5 l6 w - GPIO_InitStruct.Pull = GPIO_NOPULL;
& i) H1 p: c3 |7 ?- R9 k2 I - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);; d8 e, C6 [# o9 R; |5 k6 o! r5 _: F
- 3 d: Q. B; u( I
- GPIO_InitStruct.Pin = GPIO_PIN_11; j4 w# u R& j- W
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;3 X4 w( W; B& J8 {# O) v
- GPIO_InitStruct.Pull = GPIO_NOPULL;
4 J8 `$ `* z9 o8 S - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);. Y( i. _8 m" ?( f; x
- 6 k' Y$ D) D6 U
- /* ADC1 DMA Init */8 l( s* R" h# J5 w, F4 K- j; ?( f
- /* ADC1 Init */
: r- H5 `9 }$ g- P: g2 C" N, i - hdma_adc1.Instance = DMA1_Channel1;: T0 q! [9 t' u, q V
- hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
+ @- @# Y) x3 B! k/ c - hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;' N- z8 f G& U+ ?4 s
- hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
* |8 `- G/ \) o1 I0 e% C7 Q - hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
5 m) S; u- S g. r - hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;( u: |$ @7 V; c( a& x7 l' U
- hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
* L0 W! T7 D7 N7 b* Z" G - hdma_adc1.Init.Mode = DMA_CIRCULAR;
7 d8 q/ d: S! l3 D+ U6 w/ r - hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;% P0 }- @6 H. ~2 t% b* l
- if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
8 B: f+ Z& y) ]: v: D, ]7 i, f - { x( H9 U2 P/ c4 q8 k
- Error_Handler();# f I7 E7 o1 I8 r- ? c) i
- }
" Z' e& A8 N; H/ |: N, i$ e - ; \# E( |2 d6 j: Y" {: `
- __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
E& H4 Y5 ?2 S( Q
! _, ?) o6 P7 l- /* USER CODE BEGIN ADC1_MspInit 1 */8 M5 K1 k* t9 x1 {) n. o' z( H, k
- 7 X: k6 e2 ^. R2 x0 B+ Z$ O; o
- /* USER CODE END ADC1_MspInit 1 */5 C( G4 B# J# x5 o2 v5 k4 n
- }
p! z$ e; N4 `! B8 u; M4 { - }
复制代码 2 C2 B* n# d4 q( ]* C0 _3 A
把STM32CubeMX生成的代码下载到芯片中运行,结果ADC1_8的值可以读到,但是ADC1_15的值却一直为0.
% Y3 Z6 {* |$ `- K4 h- V* ~7 \* O+ c6 i' k+ f! v8 D
出现上述问题的原因是因为STM32G031的 ADC 序列器配置成完全可配置时,只能使用通" ]% o$ _, a8 v! Q, N8 m+ {
道 0-14,不能使用通道 15,16,17,18;所以在有使用到通道 15,16,17,18 的情况下,ADC 序列
) i( m! l# e% N1 z8 ?+ j) _/ o1 O$ G器要配置成不完全可配置。Sequencer 选项选择为:Sequencer not fully configurable! B( V& z$ G) s9 r. `. P0 e
如果是多通道则 Discontinuous Conversion Mode 要使能
+ q4 x/ H, }2 x1 o. Q P6 V; d$ ~5 N: m/ g
3 V7 N" y* K1 H8 C& ` |