开发平台:KEIL5: G. g6 f* N+ s* P6 X' B5 T% c
4 J5 J, [6 B5 j1 J. j
芯片:STM32G031- c. c+ @+ L1 m( `2 }8 |0 w% F
) `1 B6 e& ~# s6 K2 {( j描述:近日使用STM32G031给客户做一款产品,在使用ADC时出现,采集的数值一直为0的情况。分享给大家。& b9 _4 H$ I- d3 I" m0 H( Z o
2 S4 h9 Z) e, I" I) O% t使用STM32CubeMX生成代码。配置ADC引脚,PB0为ADC1_8,PA11[PA9]为ADC1_15.
1 t3 P9 f+ o) L) ^) d5 h+ q
& [- w3 f! T& R$ L# V5 m, g- |3 E/ w! Q6 @& ^/ T/ n
; u9 q6 R/ W; D4 _. z Q* d生成代码如下:
3 B' q4 _! A8 W) r5 E
% R6 j0 A3 K) q. H1 i4 ^- int main(void)
* ?: g: [* H4 V- m' L - {
4 z) S! q8 e' e7 v9 i- c" a - HAL_Init();
6 g2 u; o5 g- W S - SystemClock_Config();
8 ~8 ?+ A% j6 n/ d3 B4 T5 c - MX_DMA_Init();
# N5 S4 V. r* v8 K4 o - MX_ADC1_Init();! b; ]) @0 `% C% ~( X" b ~
- MX_NVIC_Init();
, d3 l- h+ q1 x; D1 J# Y - HAL_ADCEx_Calibration_Start(&hadc1);
3 c# x: w' U" u6 {* w4 V: w - HAL_ADC_Start_DMA(&hadc1,(uint32_t *)&adcbuf,2);9 t+ ]' P3 H2 \! `6 V
- while (1)6 k2 v% h% D" x1 [( b, N& H
- {
0 }0 q2 x) ~' U0 z - if(get_sys_time_us() % 1000 == 0)- Q* h( m( J$ z6 I% A% s9 D
- { . O, b# v3 A( h/ a4 Q; F# |
- printf("adc1 = %d\r\n", adcbuf[0]);
6 F3 E# E$ N$ i9 y4 t: e - printf("adc1 = %d\r\n", adcbuf[1]);
" k7 | K3 l" p, G - }/ K5 |9 }- E5 T8 u$ D& t2 @' q
- + s& o; ^6 P4 Y {( a: p
- }
复制代码- ADC_HandleTypeDef hadc1; e6 c" r/ U8 H: [$ F$ K7 i+ ?
- DMA_HandleTypeDef hdma_adc1;
7 i; y2 ^# R% ^) k
" | }1 A5 S% U$ i) s" r3 y- /* ADC1 init function */
) I8 I8 P. a& t$ T. g - void MX_ADC1_Init(void)
* y8 \6 T5 }0 m( f- z+ n! B - {, S) a, u- I( n9 ]' @" E y
- ADC_AnalogWDGConfTypeDef AnalogWDGConfig = {0};3 C8 ^- R( c* S/ v5 H# u
- ADC_ChannelConfTypeDef sConfig = {0};
$ k* G7 S( v; T
( `- M5 ?% M. I% q+ a- /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
. o4 T# ^- r7 M& C E - */4 ?7 i' o; k5 ]- G6 G. d6 l( s
- hadc1.Instance = ADC1;
* S( c3 v6 w6 x% l& W - hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
" ~& z0 G2 K8 S4 ?0 G* c" Y. Z - hadc1.Init.Resolution = ADC_RESOLUTION_12B;
1 R( \, }8 E. Y+ W5 @ - hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
4 e4 K! I8 \6 `. D% W3 C! y - hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
& g0 U, s/ g+ g: X2 V+ n5 Q/ T" g - hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
6 g; K1 H6 D5 O, A - hadc1.Init.LowPowerAutoWait = DISABLE;1 g6 |( G- z7 z
- hadc1.Init.LowPowerAutoPowerOff = DISABLE;
$ R' F1 {9 t' w* L8 I - hadc1.Init.ContinuousConvMode = ENABLE;1 R3 `- w: I1 B5 y5 P+ }
- hadc1.Init.NbrOfConversion = 2;
4 k* H: E- j# K( J; N3 l/ D* B - hadc1.Init.DiscontinuousConvMode = DISABLE;' N6 p8 x9 }! z/ K4 E. b2 F
- hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;/ L( c/ B5 q4 Y6 \: f, w; w
- hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
! w3 Y1 `( P0 a/ s - hadc1.Init.DMAContinuousRequests = ENABLE;0 S) M, }: K1 q3 b. d; `# [/ ~
- hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;1 a. c _) |' W- ~0 n
- hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;6 E% S! T m+ t
- hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
. f1 H% j7 I9 D$ S - hadc1.Init.OversamplingMode = DISABLE;9 o! S2 I9 s( i, m6 w
- hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
' q+ _) G" E3 P v - if (HAL_ADC_Init(&hadc1) != HAL_OK)
$ @, v/ U0 j8 N# b0 C6 z - {
% \+ |. z+ x" y A9 u0 d - Error_Handler();
6 o$ H( P% Y4 V - }
# ~" U6 w7 m& i; Y - /** Configure Analog WatchDog 2
$ e; H0 F& U0 Q) x2 o& |' U" n% t - */
, \9 Y. ~. W( L/ [' s/ Y ` - AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_REG;! c% j3 y3 P9 t7 ]
- if (HAL_ADC_AnalogWDGConfig(&hadc1, &AnalogWDGConfig) != HAL_OK) F, J g6 T, X" y- G# D0 q3 G
- {
6 S/ a! X, P. R9 I/ Z+ l - Error_Handler();. H. d4 i0 u% W5 _
- }& Q/ m Y1 F3 L
- /** Configure Regular Channel
, W8 M0 K7 o L8 d- x6 X9 z - */
1 E$ Z% A1 M4 p/ ^7 x2 j$ _2 k, D - sConfig.Channel = ADC_CHANNEL_15;
! [" L0 t, f- x8 w& O& `7 a - sConfig.Rank = ADC_REGULAR_RANK_1;) Z w" e+ g( q$ f
- sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
. I6 Y5 p" z* [9 A! q - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK); W* `/ P, M$ @3 A: X
- {! X3 s m6 D+ |+ }0 g
- Error_Handler();
* t: P) Z: e, L' i' g# c - }
* ]# v i0 r q0 H - /** Configure Regular Channel
5 U/ b0 }6 ~- D - */
/ S+ U( P, G3 Q3 G, b* w - sConfig.Channel = ADC_CHANNEL_8;7 K6 R1 Z- {2 n* z
- sConfig.Rank = ADC_REGULAR_RANK_2;- b$ Y1 B. B3 O9 f: g/ }
- sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;7 X1 X. ~. v% i/ b4 e+ P
- if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)' P$ _' z4 d# n4 a y
- {
0 L3 u" U e9 A& t: T- i - Error_Handler();, O/ S' I: u ~0 I! ~* v
- }5 g1 \3 a w% y& f8 k, M" d
- 4 Q" @6 A% u; B7 k e/ Z" ~. o
- }8 Z. f* R& T8 W+ H) E0 f; b
' T& s! `0 D8 |& K) J# ~- void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
; Q4 E! P0 S0 k- _! u - {
4 Q8 Y, Z8 X8 o/ H& a# l: C
8 e8 d0 z% G- j' i- GPIO_InitTypeDef GPIO_InitStruct = {0};
% R* k: H9 ?0 i+ S) F9 [, D - if(adcHandle->Instance==ADC1)
7 C, h1 P' w7 M! |8 h4 ~ - {/ H( _" n' t4 T' j+ X* w- ^
- /* USER CODE BEGIN ADC1_MspInit 0 */) ` g' i8 v. A" E; w" P3 H8 p4 w
8 o( j4 ^, x! J8 `; L( N# [9 B- /* USER CODE END ADC1_MspInit 0 */' Y4 i+ h: Q& ^+ U# ~& y
- /* ADC1 clock enable */
' K2 K, K1 r! `: E* e6 I/ N( j - __HAL_RCC_ADC_CLK_ENABLE();+ ^0 m% m. }. F
- : F0 [9 i0 y- t3 q
- __HAL_RCC_GPIOB_CLK_ENABLE();# i2 L2 R; u8 H& G' ]' g- G
- __HAL_RCC_GPIOA_CLK_ENABLE();
8 K K7 ?3 e' }5 |% P ?$ \ - /**ADC1 GPIO Configuration Y0 j2 ]1 \6 E1 A- a2 Z, l
- PB0 ------> ADC1_IN8
; A9 Z: ~# L+ }7 W% r - PA11 [PA9] ------> ADC1_IN15
2 g% E1 V1 L7 n8 W( ^' r/ Y - */9 k1 d$ v0 P- K& ?8 ^( M$ ~) }
- GPIO_InitStruct.Pin = GPIO_PIN_0;: P5 ^* c0 C4 _. V+ V
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
+ m7 s+ {( {$ B* F" ]! p3 g w6 N - GPIO_InitStruct.Pull = GPIO_NOPULL;- o! [2 i. m0 X8 R6 Z4 A& k
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
' P [+ s, t) {& w - , E$ h/ k& R w$ x0 Q# O
- GPIO_InitStruct.Pin = GPIO_PIN_11;% ^" d" A( B5 J1 U; q
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;9 c" B( i6 }7 D! C q
- GPIO_InitStruct.Pull = GPIO_NOPULL;
" M9 X& a5 `1 s' H7 ` - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);9 N) T, R# \) w3 U8 Z/ t! d
- 2 E5 v: T& C) T# x8 Y+ W9 k
- /* ADC1 DMA Init */5 t5 M* h" H: F, Z
- /* ADC1 Init */- a5 e; b2 P, i
- hdma_adc1.Instance = DMA1_Channel1;
* X; e) _. F7 r2 Y' K0 V7 B - hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
5 v" `, {" O5 p$ o6 b/ V: { - hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;$ ~+ H* T$ {# w. C" d0 \2 u' l
- hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;- [1 j0 M# b6 x8 K: v; A% `' m+ d
- hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; y- N: m& A$ R( O" @: L
- hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;* ?1 i0 x2 q6 F8 y# P! m
- hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
0 f* ^. h# k6 e8 w - hdma_adc1.Init.Mode = DMA_CIRCULAR;+ Y8 r' K0 x: x* T' P
- hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
% j8 J0 g9 G1 y - if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)) ? R" J8 I% h: d
- {! {. g: P E% w1 V/ i
- Error_Handler();
1 L' T% H8 U* X$ t0 z+ i - }
3 F2 L# W: \7 O" V5 u - 9 ^7 F: ~# ]. e4 Q/ v) p
- __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
7 k7 d: o& W5 Y
( Q1 V- M9 }+ C* J# K- /* USER CODE BEGIN ADC1_MspInit 1 */# q; C$ W" L5 J2 l: R, p: u
7 z1 Z) A) C0 T9 z s- /* USER CODE END ADC1_MspInit 1 */! M1 L3 k. B5 [
- }! _6 e# \1 b) @ S
- }
复制代码
2 c! w7 y2 e( Z" U5 M7 _把STM32CubeMX生成的代码下载到芯片中运行,结果ADC1_8的值可以读到,但是ADC1_15的值却一直为0.
* l( A1 R: l/ p5 e0 l7 M0 r" ] c
( A$ `9 v) ^3 p9 Q! u出现上述问题的原因是因为STM32G031的 ADC 序列器配置成完全可配置时,只能使用通
+ \- X0 n/ l6 q6 ?3 T5 t, U) H道 0-14,不能使用通道 15,16,17,18;所以在有使用到通道 15,16,17,18 的情况下,ADC 序列, f& o" @, C& L
器要配置成不完全可配置。Sequencer 选项选择为:Sequencer not fully configurable
& I! g# A2 M) k( m( k1 j6 O如果是多通道则 Discontinuous Conversion Mode 要使能6 r3 H# P/ M7 o# ^. X
* Z0 {) k9 O. a# h$ c' C
$ f0 n1 l' r" O0 N: J" F |