开发平台:KEIL5
& x5 A0 g* Y; W% |: A! ^1 g4 X' G9 A) h8 Q4 K
芯片:STM32G031
5 w( _0 d+ A6 P$ a: E: I
- g5 N; I, v& ^$ q- r% K& u描述:近日使用STM32G031给客户做一款产品,在使用ADC时出现,采集的数值一直为0的情况。分享给大家。
( r6 f3 c% C& e2 A) Y) t1 [( D* w4 l: K& _
使用STM32CubeMX生成代码。配置ADC引脚,PB0为ADC1_8,PA11[PA9]为ADC1_15.
9 a- {6 `/ @$ R- H
% Y% q. j3 M5 I: u" G7 W; p- c+ e( z1 H1 V5 F9 N6 l; L
) R, l) A! R- V8 [生成代码如下:
{, ]; M. Q0 ^% z, ] Q3 D5 f5 D4 s& X+ H7 r$ B- z2 Y' q
- int main(void)1 N3 M$ O J7 a' E% l
- {( x7 t/ V; m- d! J3 F5 O
- HAL_Init();* m& P" l% l2 x# |
- SystemClock_Config();# Y0 S9 \# A) v
- MX_DMA_Init();/ q9 h6 _$ L" L3 L' [
- MX_ADC1_Init();
M, f: u! Y- G; C% y: r: A! K, ^& B - MX_NVIC_Init();
! r$ }3 V! g0 {1 F7 h - HAL_ADCEx_Calibration_Start(&hadc1);
1 e' ?1 O2 }- ]% K - HAL_ADC_Start_DMA(&hadc1,(uint32_t *)&adcbuf,2);* h" Z& t6 N( ^' b4 v x
- while (1)& M+ c W9 F" o; s! p* W# `% F9 k
- {
! E- C5 Z' G: o- U8 \4 w - if(get_sys_time_us() % 1000 == 0)
7 ~& V( Z9 P2 Z% x+ A9 I - {
) g$ Q& N. j# D - printf("adc1 = %d\r\n", adcbuf[0]);
s3 q, M9 ~# {; |/ n; c - printf("adc1 = %d\r\n", adcbuf[1]);
( v9 c/ A8 Z! h - }& v2 ~# C& ?" C* g7 w
% m; b& }$ E# v. A/ B- }
复制代码- ADC_HandleTypeDef hadc1;
2 ]# K4 s+ k7 Y- V7 y4 N - DMA_HandleTypeDef hdma_adc1;
4 U) o( k( e. o5 p' [. r - ( C2 I4 f) Z' ^5 v8 `5 F
- /* ADC1 init function */8 s7 n7 S/ m% \( R' D- h
- void MX_ADC1_Init(void)
- W/ Y6 u1 `4 w8 K5 R' H l0 ^5 } - {/ j# S( g8 A1 \2 I% c; Q: D+ X- K
- ADC_AnalogWDGConfTypeDef AnalogWDGConfig = {0};+ `& p' l6 |9 @# w ~
- ADC_ChannelConfTypeDef sConfig = {0};1 N9 m. C4 ^- O
- 0 ]: i8 M- f' }
- /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
0 z0 F$ v9 l; M) i - */+ y- @$ y7 `$ x1 o/ S: m
- hadc1.Instance = ADC1;
$ }( y' l3 t# @ p - hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
' H; k* I& [& H2 \ - hadc1.Init.Resolution = ADC_RESOLUTION_12B;
5 X3 ]; n* j7 g) c ]! ?; N - hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
, s2 B# \# q/ C7 ^) K( a, k4 b - hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
2 x& c) M+ q0 e( E/ c - hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
" Y5 ~7 i/ d. K# D: X+ @ - hadc1.Init.LowPowerAutoWait = DISABLE;
; g f& k* C2 N& e% d. m - hadc1.Init.LowPowerAutoPowerOff = DISABLE;/ U4 ]8 h. F0 I3 \$ A
- hadc1.Init.ContinuousConvMode = ENABLE; f. ]. |: G% k. W/ V0 e
- hadc1.Init.NbrOfConversion = 2;
* q( O4 b' z, c5 | - hadc1.Init.DiscontinuousConvMode = DISABLE;# s8 }, ^9 }# \' V# ?
- hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
6 i2 S% m1 [4 o) z) e* V& s - hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;0 t7 x' ?! h/ C: |: M# T
- hadc1.Init.DMAContinuousRequests = ENABLE;
3 W, G2 r R0 ~$ X+ s- _ - hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;1 y' i/ f& `1 X0 J0 S& J
- hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;- E: f0 @* s7 v9 \( C- }$ R
- hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
* \, `+ }* o% l - hadc1.Init.OversamplingMode = DISABLE;: ^3 i8 A; o. I* t; ~" }* L% |% L
- hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;5 j R) ~8 [# E d/ P$ {4 |, u
- if (HAL_ADC_Init(&hadc1) != HAL_OK)
& W- x+ A; V# Y4 H- I! O: Y: K - {
2 u- M& W* J- K! j" P2 \ - Error_Handler();
: e" m0 A. m: k7 D - }
2 D1 t8 Z) G `, W - /** Configure Analog WatchDog 2
8 W% Q' {/ m D/ A1 Y7 z# d, @ - */6 M( s# m$ {* H, h' y& J
- AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_REG;
. ?( k4 x5 J, R2 @" U - if (HAL_ADC_AnalogWDGConfig(&hadc1, &AnalogWDGConfig) != HAL_OK)
: I, I( W& N( h& J0 f - {
' u# f, E4 \* v/ ?6 z - Error_Handler();( ~0 D) B. ]* {9 S* m* s1 U2 Z
- }) c8 M+ M3 W9 n8 A# Y/ P: }4 j4 ?
- /** Configure Regular Channel
$ n9 @. }! j- X. E8 J* k5 l - */6 x$ U1 |1 K2 k1 c2 x1 q
- sConfig.Channel = ADC_CHANNEL_15;, s5 K- ^: H3 l8 C
- sConfig.Rank = ADC_REGULAR_RANK_1;
3 a( o p I" W' }: a - sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;, ~5 e$ v: }9 W: W e6 g3 W
- if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
4 @2 n. B, u: ~7 Z- Q9 d% d( M: I( n - {
6 M, \- C3 ^1 B+ R - Error_Handler();- J( O+ z* Z9 @# _$ ]
- }
' K( _# V' }6 V; R - /** Configure Regular Channel
+ y, W" E! g3 U, H4 B2 A9 H8 t - */
; O# p3 s6 U; j3 m5 l3 [8 L3 W& ` - sConfig.Channel = ADC_CHANNEL_8;
& w/ ]# S# f H( S% k# f$ {: s9 L - sConfig.Rank = ADC_REGULAR_RANK_2;0 f: M8 d" f, B: s
- sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;) V+ o& _$ j5 ]( Z/ R+ a
- if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK). g, j2 I& k& N- y3 L
- {
# Q( j/ L! I8 k4 V" U" ] - Error_Handler();* p) v" a/ c6 m* h4 @
- }+ ]" |3 O' U: D# @ e9 S
- " A- S: e$ j# ~2 z8 s6 I( j
- }
7 F" ]: u% i+ B& R - 1 g5 m/ E8 J. S/ A d. R
- void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle). _2 u. U" l' K# q& V; M: v! u
- {
5 D" d+ k m$ c, t+ r - y. d. ~2 b; N! {; f: V
- GPIO_InitTypeDef GPIO_InitStruct = {0};2 `( C5 P/ |7 Z3 m& z' I# U
- if(adcHandle->Instance==ADC1)1 \9 `/ d% s9 W% S* E9 P V
- {# \; ]( m3 @6 e( x! z7 n: H$ y
- /* USER CODE BEGIN ADC1_MspInit 0 */
9 N4 b1 B" c- t! K( n - % F4 n4 m/ c4 O" j
- /* USER CODE END ADC1_MspInit 0 */
1 J' N. \) z! \% Z+ J - /* ADC1 clock enable */! `% d! J5 R( a" I
- __HAL_RCC_ADC_CLK_ENABLE(); x# R8 a/ E2 n9 a* w3 U& }
- 6 K* H6 f9 f/ v, V& d4 w
- __HAL_RCC_GPIOB_CLK_ENABLE();9 X7 a5 A5 P8 b/ x5 T
- __HAL_RCC_GPIOA_CLK_ENABLE();3 }, C6 ` w) |
- /**ADC1 GPIO Configuration
# i. U5 z- ^2 A% D - PB0 ------> ADC1_IN8
# L1 Z' _- I% z4 I9 `3 X - PA11 [PA9] ------> ADC1_IN15 , [! Z8 [2 T9 A
- */
- @8 k9 s$ n$ y6 a- L9 \: X( S0 y - GPIO_InitStruct.Pin = GPIO_PIN_0;9 Q8 v" H8 k9 N$ O( V
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
0 f P ^( r" \6 j5 M$ d - GPIO_InitStruct.Pull = GPIO_NOPULL;9 o( V, I0 _. q( F8 z
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);# x3 |/ R. e8 B; G1 n0 y/ V3 Q. q2 E
- {8 z- U* F( w6 M8 p7 D; K- GPIO_InitStruct.Pin = GPIO_PIN_11;
; K( a8 P# H o' w! q8 {0 i - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;4 x1 ^$ h# Z; T
- GPIO_InitStruct.Pull = GPIO_NOPULL;& d& J/ L& R% o
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
( X3 |( Q+ `( z: x4 D
. S% W0 T U% `, {+ v1 v- {8 `- /* ADC1 DMA Init */
& d1 B' H8 c$ M4 X! V( f% ^& l; H! r - /* ADC1 Init *// s; ]: G4 [, p" b
- hdma_adc1.Instance = DMA1_Channel1;
5 w( a2 Q1 W& ~/ ?& F" E7 I - hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
( s9 _ y: s; e$ M8 T; p - hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
. v- i- x$ _! \: U2 p - hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
7 `& M! Y- `, |6 k - hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
q3 x! N/ k9 F7 L( G4 |& J& }- _ - hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
1 C' E: m1 L3 [' I! r, R - hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;' g- }% ?8 h- |3 y9 k: }
- hdma_adc1.Init.Mode = DMA_CIRCULAR;
3 C8 H1 v4 y+ d* ~+ z - hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;! T( |7 c% j: P- p( |/ H, O3 P1 s
- if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)3 n! X, a) n2 T4 k k
- {) x. ?5 O& S" P
- Error_Handler();, X" y2 s9 E- G, P
- }5 q3 j6 r* A; n2 X& v" p i
# o7 `2 E9 }9 b( z8 [- __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
8 G: P& e5 F1 H/ k
6 m& \9 n( b4 ]! \3 k; d& M- /* USER CODE BEGIN ADC1_MspInit 1 */& ?, U; m$ @/ e
- , z. ]( j) R( `) d G
- /* USER CODE END ADC1_MspInit 1 */
. U6 o1 A$ u: M8 w, ^! I - }7 G1 C X+ M M# p4 }0 Z, }+ y
- }
复制代码 , `. C; X6 o6 z+ C' i- Z4 D
把STM32CubeMX生成的代码下载到芯片中运行,结果ADC1_8的值可以读到,但是ADC1_15的值却一直为0.
& S5 n8 c; t: Z/ G' T0 z
1 T; N( ]5 u) E0 r6 T出现上述问题的原因是因为STM32G031的 ADC 序列器配置成完全可配置时,只能使用通4 P1 d1 k. f* s! O* e# M8 {; c
道 0-14,不能使用通道 15,16,17,18;所以在有使用到通道 15,16,17,18 的情况下,ADC 序列2 A3 K6 d3 i: O- v
器要配置成不完全可配置。Sequencer 选项选择为:Sequencer not fully configurable
+ X0 s/ t! I8 A如果是多通道则 Discontinuous Conversion Mode 要使能
6 s" w6 q5 l9 Z; e
# s( d6 r1 T& T1 c$ U/ d, o" U [) O- o2 X
|