开发平台:KEIL51 T5 D4 P9 w- u/ e- _- ]3 P# f
3 s5 g+ z! {! e
芯片:STM32G031
2 ]) J" \7 I/ q. Q+ @$ C$ g @* }2 f
描述:近日使用STM32G031给客户做一款产品,在使用ADC时出现,采集的数值一直为0的情况。分享给大家。
0 I' F7 _, p1 g$ L$ j9 t0 Y" l; m4 b) g" S' _3 c. ^: k& l
使用STM32CubeMX生成代码。配置ADC引脚,PB0为ADC1_8,PA11[PA9]为ADC1_15.- \& L: w, @( f! d" |9 r
! D( h: b/ A9 I) ^( Y5 E2 G$ u$ X( s+ e, j; J
% F9 O- d' M) ?生成代码如下:
/ r7 \1 R( f! [5 |/ F
2 B% \0 k. \. d- int main(void)
0 I2 ~, k! k7 ~; E1 j, v, y, p$ r8 i - {
9 D( K) _( E0 N - HAL_Init();
, u+ @4 e+ c9 S0 j$ T, Q - SystemClock_Config();
# n: g4 b; M6 }/ ^ - MX_DMA_Init();$ [9 ?( X# M" A- O) O6 R( Y) ^) q _$ F
- MX_ADC1_Init();1 x( J( V3 r4 B+ ~9 G
- MX_NVIC_Init();
' f8 L' Y% T" v - HAL_ADCEx_Calibration_Start(&hadc1);4 u, U2 Q1 Y9 k$ u
- HAL_ADC_Start_DMA(&hadc1,(uint32_t *)&adcbuf,2);- V; E1 N# a4 a" G+ r y
- while (1)& [( Y3 i4 r% F w3 f$ u) R% z/ N' @
- {
; y. v, B% V' V" M+ i/ H9 ] - if(get_sys_time_us() % 1000 == 0)+ t9 C" s! b1 p; m
- {
: I0 V* a' C; X8 ~" n - printf("adc1 = %d\r\n", adcbuf[0]);# N; J5 t9 }5 M( l- N; D
- printf("adc1 = %d\r\n", adcbuf[1]);7 |& \' O+ o( l0 [
- }( A2 R3 m ^ U3 f; \
- 6 t5 U7 I3 v% @) W7 L+ B/ B7 G: i, t3 E
- }
复制代码- ADC_HandleTypeDef hadc1;
- r. ]* r0 @6 u$ [, _ Z - DMA_HandleTypeDef hdma_adc1;
w& Z/ c$ i% u, {, [( M: b - 3 i1 ]) ?+ r, N' n
- /* ADC1 init function */1 p% D$ M. o- |$ O% `
- void MX_ADC1_Init(void)! M$ M3 ]- q* G+ N# g9 a/ t
- {, W5 F5 `1 F) Q- I b7 ^
- ADC_AnalogWDGConfTypeDef AnalogWDGConfig = {0};- w" f, C3 n& \( i4 }: R
- ADC_ChannelConfTypeDef sConfig = {0};: h! ?0 e( f. `
- + N9 i) ^( g U7 r
- /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
. b; v" J1 U0 T0 E% j# h9 z - */3 c$ [" l( g# L# o# t8 x+ M. r
- hadc1.Instance = ADC1;
^& `# {% P& u2 w+ ? ~ - hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
! Q+ A6 J; N: T$ K% A - hadc1.Init.Resolution = ADC_RESOLUTION_12B;( {/ X. j- O* E4 T
- hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
" \1 ` U4 g6 A P0 a - hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;' J4 `# O% n" M8 v
- hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
% E( X+ |% G5 [ - hadc1.Init.LowPowerAutoWait = DISABLE;# }- `$ r3 R. m% J- R8 v& w) m1 g
- hadc1.Init.LowPowerAutoPowerOff = DISABLE;; M7 b5 O& _7 }* ?
- hadc1.Init.ContinuousConvMode = ENABLE; v& V8 H+ L. x- p \& l. s# s ~
- hadc1.Init.NbrOfConversion = 2;
/ t+ _. O% F& n2 ? - hadc1.Init.DiscontinuousConvMode = DISABLE;
, _. H! c/ |/ n. f+ | - hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;- w: S5 M3 f5 w+ Q; E6 l7 J
- hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
# Q0 Q7 E6 C# M9 D8 ? - hadc1.Init.DMAContinuousRequests = ENABLE;
; C/ p" i1 d# j. K+ a* N8 R1 {- O - hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;& F2 z( O" \( T. |8 O
- hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;
$ L( g, ?4 S- m' A n' X7 u' S: a, T, N - hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;% u. o4 H' M& y4 U+ u; G$ c8 F% ~
- hadc1.Init.OversamplingMode = DISABLE;
6 p& P- }8 B. h; p - hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
: E8 P. [( l3 K6 x, A( M7 h4 a" q - if (HAL_ADC_Init(&hadc1) != HAL_OK)
5 L2 Y; b" F, a - {
5 C) V- c; ?7 C - Error_Handler();9 W, D7 v0 r. O/ g4 Z! m& }
- }0 C% @. s* d6 Y- \/ E! @
- /** Configure Analog WatchDog 2 ( I7 S" M* z/ X5 U
- */
( H t( ?. U/ a2 M1 m- x* w - AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_REG;
. U$ [( `1 O: r; Y( I9 T+ U - if (HAL_ADC_AnalogWDGConfig(&hadc1, &AnalogWDGConfig) != HAL_OK)
: E: w5 S, e/ {" c8 \) G( E( B - {) Q$ Z! ^/ C6 X v C- p/ C& f
- Error_Handler();
$ v. T# I( m: a - }# O5 n. R; F! q! A: I
- /** Configure Regular Channel # e( t" b% d! S# F1 h, n$ a0 s* G
- */2 F i& t; _: ]6 s' q3 Y
- sConfig.Channel = ADC_CHANNEL_15;0 x% v- |8 ?* r
- sConfig.Rank = ADC_REGULAR_RANK_1;) P( c( @. W+ D4 ]: b
- sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
, ?& H ?' z! v - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)+ |8 H! S( H9 q2 {9 }7 s- D
- {; c( B2 E. }; h. V4 S3 ~: N
- Error_Handler();( g Y" u* J* B& K& i& C/ r
- }8 n/ k& l2 J7 f+ S. V
- /** Configure Regular Channel 5 Z- h% i! m3 G, f4 b$ O
- */5 x0 B* J% [! x2 W( @. V
- sConfig.Channel = ADC_CHANNEL_8;
: t: ]: f' K6 S- H, e+ Y7 _2 u - sConfig.Rank = ADC_REGULAR_RANK_2;, B( S- k* I$ F8 ^
- sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;
6 }* P a" x o T. A5 |/ b c - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
! g. Q, {0 }! j: A1 ^1 J - {" W1 ~! `, f" O0 R) C
- Error_Handler();3 E1 g, t( w5 S( s4 V, z, G
- }) H, }( q3 C7 Y9 w& D3 _
0 ]. {/ d" E4 h; X0 K1 ?/ F- }
! r# h/ u4 X1 `0 j: Z - . K0 G6 F0 P3 k7 c5 G& t" S
- void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)" y" b, ]5 ~ m
- {8 v- t% B0 U, H7 K2 p
7 s' _6 h8 V* P. I( k- GPIO_InitTypeDef GPIO_InitStruct = {0};
: ^6 E: N- V1 \# m8 K% c5 Q0 R - if(adcHandle->Instance==ADC1)$ `8 M. ? r9 e2 ^' `2 h! |9 I
- {
5 Y4 J, _* w, u. E7 { - /* USER CODE BEGIN ADC1_MspInit 0 */& ^. D; S( W7 \4 G; O
- 7 q& Z Z- Z/ |7 x& C
- /* USER CODE END ADC1_MspInit 0 */
* _: ]0 T) g3 | - /* ADC1 clock enable */
0 `1 d5 Q9 e8 _; i# L - __HAL_RCC_ADC_CLK_ENABLE();! M9 p6 O5 `( f+ d* }
- K$ x; n/ i0 M" f9 {& `7 }
- __HAL_RCC_GPIOB_CLK_ENABLE();$ g2 z8 [) k! I: s1 \
- __HAL_RCC_GPIOA_CLK_ENABLE();
7 v/ V8 F( o* o8 A+ r a8 p - /**ADC1 GPIO Configuration
7 f5 B ?5 b, V- M) E7 x1 i5 P4 v - PB0 ------> ADC1_IN8/ g, f9 L" r9 E- {: h4 S
- PA11 [PA9] ------> ADC1_IN15
5 k( S2 T+ }. H+ j i- U - */# {; @; `1 \3 f) w7 H
- GPIO_InitStruct.Pin = GPIO_PIN_0;5 _# u! d% {) g( @ j/ K
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;' C; {1 s+ x, J; b2 N- l7 v$ O' K
- GPIO_InitStruct.Pull = GPIO_NOPULL;
' v) k; o T" k) Y5 e6 d - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
N- G; ^2 m$ L8 f$ ~2 q( ^ - / T9 x- [' K( a, ^6 K0 B8 P
- GPIO_InitStruct.Pin = GPIO_PIN_11;
$ q4 C H* W) ` - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; w0 L# D/ ]5 N/ z
- GPIO_InitStruct.Pull = GPIO_NOPULL;
: ?% K5 q# y7 b* P - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
3 T$ Z3 I$ R+ y1 @" i# } - 2 o4 K( [' V" G+ ^1 N, [
- /* ADC1 DMA Init */% T8 a7 X1 U; t. E
- /* ADC1 Init */- r U; Y, Y% {
- hdma_adc1.Instance = DMA1_Channel1;
3 D! l% L/ d! e - hdma_adc1.Init.Request = DMA_REQUEST_ADC1;$ n' \. z. y6 a
- hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
% l6 Q! Y8 A- h1 i8 k - hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; `. D+ l5 C7 X/ g
- hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
. W) w) ~- X" l5 D6 z& ?8 L% K - hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;5 l0 F2 h7 Q) _: k$ A/ H a
- hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
) g/ v# ^7 M7 D% p k7 c) O2 q+ X - hdma_adc1.Init.Mode = DMA_CIRCULAR;
+ c( ?5 x0 R: e) B! [: x, y - hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;: N; X# |0 ?* n/ L
- if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)+ }" K1 I9 r0 R! S- x8 j Q) ~
- {
2 s$ U+ R$ v9 i/ N/ l - Error_Handler();4 Z& C+ C# N5 d( p$ R/ L
- }+ t# e$ j4 t0 W' u- o# W
- % t) J- q4 |0 T$ v/ J
- __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);" g2 F ]& `6 X5 Z6 H
9 X5 _4 F$ d+ k+ D" j% C- /* USER CODE BEGIN ADC1_MspInit 1 */
E2 W* k" M. }6 `
, w% s, s" N; E* O, u, m. W- /* USER CODE END ADC1_MspInit 1 */
9 E, |5 Z4 O( s8 X [ - } k* s5 S X; i0 _+ @/ B( L5 _
- }
复制代码
4 N8 v- G" O: Q. ^9 W把STM32CubeMX生成的代码下载到芯片中运行,结果ADC1_8的值可以读到,但是ADC1_15的值却一直为0.
8 h0 t- u k) ?) d% u" B
8 p. b4 q/ _: {, W出现上述问题的原因是因为STM32G031的 ADC 序列器配置成完全可配置时,只能使用通. ]; }+ b& {+ I V% t/ u5 g
道 0-14,不能使用通道 15,16,17,18;所以在有使用到通道 15,16,17,18 的情况下,ADC 序列& u+ B% Y7 Z/ V! R) @1 D
器要配置成不完全可配置。Sequencer 选项选择为:Sequencer not fully configurable
( u9 ?5 u8 n, N' F9 L M8 {如果是多通道则 Discontinuous Conversion Mode 要使能( k; z# a& i G. K& |4 n
$ M9 b7 f+ ]& E7 \
. `; _7 z1 j7 F) o |