ADC+LPUART串口通讯
% g4 }" J6 ?6 m3 P3 H. Q& h程序介绍:给ADC的第四通道一个电压,通过AD转换,输出到串口打印信息“The current AD value = ****** V”
: k/ A" i5 a& X3 O
/ G2 v" Q8 ^# v调试过程中出现的问题
$ n- ~9 k+ ]6 x6 _/ g8 j因为用的内置AD,调试过程不复杂,基本一次就通了,但是串口调试的问题主要是会出现乱码情况,还有16进制显示全都是00 00 00,关于这些问题大多数都是由于波特率不匹配或者是波特率和晶振频率不匹配等。
) z/ o& f2 g! ], F$ w$ P: `+ |7 b D8 C( B& W s. h- ?4 a
1.STM32CubeMX) f# Q) Z9 M: s$ X2 }
$ c* d. q' m+ C" I0 G, P
1 B% p. c2 q+ W9 I, H0 @/ ^+ h* ?' @) M4 M: j( b% @. i7 X' E, J
4 l5 E; p5 E- {% v' N% j% H$ x8 i# X2 H1 Q# P
STM32CubeMX里面时钟图还是比较清晰直观的,比较容易上手,从图中可以看出这款芯片的LPUART是低功耗的,并且用的内部时钟(选择LPUART也是因为项目需求,UART类似),而ADC是内部有专用时钟,用HSI16M时钟工作; A$ ]! q* ]" u: R- v
: H$ g9 W# [0 L% n4 X: q! {: V2.代码部分
0 ~1 E- m# I7 _! z6 O" D: T5 G4 _/ V9 Q. \: b( r5 U% _
- #include "main.h"
5 E: n1 q% B! J4 E8 v& ~9 w - #include <stdio.h>& V" R6 u u! |# T% D
! \5 g; F4 @/ W; s- |- ADC_HandleTypeDef hadc;& g% U8 j9 g1 ~( X3 r# @- |
; j2 X' Z: `: r5 {0 x" ] F/ i/ n" B6 R- UART_HandleTypeDef hlpuart1;/ E z# S5 s" [* o6 w9 w
* |7 K% F+ o# n: c6 \4 }2 M9 o6 C; d- ADC_ChannelConfTypeDef sConfig;
7 r2 p! {" b- C: _# x" X
5 ~/ j2 z' k9 O& ?- static uint32_t adc_conv_var;/ b3 a. W" t8 q5 p
- float temp;
7 t& O `, G, g c7 n# M+ M9 ~
( ~& T4 N5 p6 s" C- void SystemClock_Config(void);
. w8 d! |1 n/ O8 l. V: A$ ^ - static void MX_GPIO_Init(void);# u/ w! _9 O: n* C
- static void MX_LPUART1_UART_Init(void);1 z! f9 F4 p2 W0 q' u; |
- static void MX_ADC_Init(void);$ V# s/ x% c! H( T2 U2 X0 d, _/ M
- static void GET_ADC_(void);
9 a ?; D y9 k& ?: O3 E1 U
& Q% d6 v. @# ^
8 X; e* F6 X9 M7 D% w8 Q9 Q- int main(void)5 H1 e: n# Q: V) \6 ?: ]4 C
- {
3 p2 c( v9 }) w
$ U( C. m9 P$ W, [5 @" x$ L- HAL_Init();
& ]6 ~ F$ S% o* c6 P1 O - # `+ }7 r- v) {& `& t) x
- SystemClock_Config();
( X: S( E' d- R' m! u. a% X$ s! g
% y; h1 m4 @' W/ R& r/ E( p- MX_GPIO_Init();( M b0 K3 L* [
- - w$ N* W5 t) r" |5 ]
- MX_ADC_Init();
7 |0 @. Z& M) s# Q - 3 L" P, q: B# F2 v M) j0 h# X0 l0 c
- GET_ADC_();
& L3 _* B- _6 z* M7 X: L4 Y - 9 Y& b5 ?' H8 Y8 N1 R, S/ t* x' d5 |
- if((HAL_ADC_GetState(&hadc) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
$ a& H, m6 Y2 ^8 B( L - {
4 K+ o0 V: g0 w$ ` - adc_conv_var =HAL_ADC_GetValue(&hadc);
2 l# q& I9 M* Y( w, M - temp=(float)adc_conv_var*(3.3/4096); ( y4 [9 a5 @' G/ x% S
- }
! o; c! m n" I% X3 W+ p - 9 b; |" r/ w9 c' n# I
- MX_LPUART1_UART_Init();4 X# {: l/ a; k9 k8 ^3 @
- printf("\r\n The current AD value = %f V \r\n",temp);
' }/ ^( B9 N8 a2 S
! h2 s% T6 f) e: k: v9 w h0 Z- while (1)- Y( F' g# l' Z9 N0 r
- {
! L7 w$ U8 V6 b* s( `& `
. B! B4 y0 s8 a8 z/ i+ y$ a+ o' }- }8 m8 N2 t( H, A: N S3 l* w
- }5 g/ I l) V- p" [6 @# ?
- //printf函数重定向" R1 c% H& Q g4 t) Q5 q
- int fputc(int ch, FILE *f)& Q+ e" I- K" ^' p
- {
3 Z% U% g( S; G4 C! b - uint8_t temp1[1]={ch};
# w0 b5 T. |; Y - HAL_UART_Transmit(&hlpuart1, temp1, 1,0xFFFF);: N5 d& v4 y' a$ w# v' p; S/ u* a% V
- return ch;7 R3 {# ~* r3 W
- }
3 O6 z8 z3 {- s L3 a - /**& E+ o9 h6 \2 K$ @1 d4 g
- * @brief System Clock Configuration m3 y: a% s2 z# ~6 V
- * @retval None# M; g/ K) W( V. T$ c" s. w
- */
+ S1 y& V- Q5 S. G - void SystemClock_Config(void)
/ _ o% v# P5 [3 E* }. G - {8 [) R3 A! K5 R( t1 w3 S
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
2 o+ h, Q1 U9 B [! v4 g5 K - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
% X4 j2 s6 X! _5 X7 c% Y- N# i( c - RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
3 W/ t! h. y0 U$ l4 I* \: Q* {
3 T, \, T" Z# _- ]- /** Configure the main internal regulator output voltage ; \2 V3 w" X) C2 q! `* m
- */
: I2 w- g- S- @+ s0 b0 y+ e0 [, { - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
2 D7 P( x( C2 N - /** Initializes the CPU, AHB and APB busses clocks 1 _* Y# q( t) g' |5 r8 T: x& m
- */
, i0 J$ ]: P) H9 l* v; y: u/ n - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;; g' ?6 H& K# Y/ v r& e
- RCC_OscInitStruct.MSIState = RCC_MSI_ON;# g; V' a. f* I3 d% B1 h: z
- RCC_OscInitStruct.MSICalibrationValue = 0;
. _5 j) L- p& i f' S4 n# G - RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
. e, Q3 [" J( l. Q - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
$ f- E% Q( H% A T' S - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
/ Z) G1 l% S, i& t- z - { w+ K6 _$ z0 [% B p
- Error_Handler();
+ P8 h3 n! S$ g8 k - }
0 F% Y, }+ ` l. m - /** Initializes the CPU, AHB and APB busses clocks ' _8 A; l: D: T1 }) O6 |9 |& j
- */: ]7 L9 u q$ ?6 s; p. K9 g; n$ ^
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
9 u/ W, `5 K) W9 I1 S - |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
1 _% e& y W! j2 [' C# p2 b4 W: [ - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
, s6 v4 h; d5 ~) K: s - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ A* W% f$ G- B; \ - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;2 Q( ^0 i' m: e, {, X) J
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+ ~9 ^) y( V! S8 v X0 O* ` - ) K3 w6 u7 @7 T6 J" g6 O
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
& j9 I3 F6 C9 D7 ^ - {
3 u d6 f$ `' w - Error_Handler();
, c* T4 O; y7 P3 e f- i7 d2 n - }
1 n9 V$ `# ~& F3 t% \) I. p - PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPUART1;5 h/ K$ D- E1 c: y/ B
- PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
7 J) S' u0 ?- ~) ?: |2 ?3 T - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)/ n+ _& t! U+ G+ ~( ~8 y
- {
+ i- f2 A6 \* R5 j& Z - Error_Handler();! v( D# E# `% w `& y, ~
- }
1 y5 Q) E* u6 W: H - HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);! F5 r& u" c/ M! e" f8 B
- }
1 S, s3 v1 g2 O' W - % B. U2 H' U8 B5 q/ I" M4 l2 |
- /**
3 c* [2 h2 m1 c2 f% i+ I/ |( K - * @brief ADC Initialization Function
5 K1 K6 _+ G4 x- u - * @param None5 N# f) ]" t5 @# @5 a6 Z I
- * @retval None
6 T9 ~8 m o. r) b: c, O - */
9 @ u, Y% o7 c \7 o - static void MX_ADC_Init(void)
2 F& n% s. d' b0 H# m - {
; g; g' H8 a4 Z! N2 M3 O. R, {7 B, g - ADC_ChannelConfTypeDef sConfig = {0};/ J- w- ?& e& |
- 6 L5 Z$ H9 {8 {3 H$ S
- hadc.Instance = ADC1;
, x' h: q* l' M, X - hadc.Init.OversamplingMode = DISABLE;6 c. U* w0 f' t1 m1 x: _# T; x
- hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
/ y( ]3 m: }/ c" ^8 P# d - hadc.Init.Resolution = ADC_RESOLUTION_12B;0 }( R, w) B- _ G4 [. M G: V
- hadc.Init.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;- H8 \; L7 a- I* v
- hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
7 z6 Q3 s9 k4 f. p( E7 q/ ?; y - hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;+ G& I2 b$ k1 a) D
- hadc.Init.ContinuousConvMode = ENABLE;
" `6 Q; z( E0 }3 \ - hadc.Init.DiscontinuousConvMode = DISABLE;
% X$ e) F$ T7 t0 K; q4 G - hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
, Y2 } J4 c' A/ {# L5 {; c - hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;5 v0 y1 O7 P5 E8 C1 E* E
- hadc.Init.DMAContinuousRequests = DISABLE;
$ r4 {) v6 j7 o+ F2 D, t) z - hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
1 Y/ ~5 B4 k* z, y7 O0 @ - hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
6 j: o7 y' N& ]0 ] - hadc.Init.LowPowerAutoWait = DISABLE;
8 ? V9 k- n( F- O - hadc.Init.LowPowerFrequencyMode = DISABLE;: M, x* n% s2 |- ^; L
- hadc.Init.LowPowerAutoPowerOff = DISABLE;- r# r1 D9 a4 u
- if (HAL_ADC_Init(&hadc) != HAL_OK)
$ T* U7 @, F% B$ N. c - {9 _# D1 P& U( Z% B8 c
- Error_Handler();
3 c b# l" m7 E( z - }, M, Q2 n7 b/ W2 u
0 s2 _" V! g+ ]( d* |- if (HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED) != HAL_OK) //启动校验功能
! z* I* U+ {; T. g8 M$ o0 [ - {6 ^8 o2 F# L2 Z* i
- Error_Handler();* x7 l" T1 [$ Y8 ` Z4 p
- }
2 y+ n- o' y2 |: f7 Y; K7 \# | - }& K1 V$ c, C; N3 f" a' z( }6 n
- static void GET_ADC_(void)& ?; O8 `$ g$ ^1 Z5 P8 A) ~4 W$ E
- {
$ p' _2 h$ K8 K) x: u2 m5 u - sConfig.Channel = ADC_CHANNEL_4; /* Channel to be converted */
5 z8 H1 }9 p/ }. }# J L4 \" A1 _ - sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; // 设置通道
: h( X3 K* n1 H# |# t. X3 j. A! v" B X - if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
9 Z; r3 Z" l7 B8 [* i! i2 t - {( l- w( h3 [) A7 F4 r g/ K
- Error_Handler();
2 p: @9 t5 d `8 B* ^& p, Y! n - }
6 s6 E! u/ P, P( ^: s" c9 x" Y3 D
6 N' m, Q# W" t+ p6 @- if (HAL_ADC_Start(&hadc) != HAL_OK)
+ h6 E3 v4 `' [% k/ z/ U! I - {
5 H% g% d1 d* M5 y- h - Error_Handler();1 g' m# I9 S; a9 t# O7 }
- }' Y k" l# \2 P+ }
- HAL_ADC_PollForConversion(&hadc, 10);! S( R- r, R" T7 B3 Q
- }, }8 X0 Q) I t; Q% u
- /**1 p3 C4 ^; R# W1 p
- * @brief LPUART1 Initialization Function# D+ C5 A3 J+ h7 w$ {$ Z
- * @param None, e( d. m6 A+ ]6 q. ^; f
- * @retval None& G' @6 z7 l. d: i& @$ K
- */# i4 C3 j$ N _& x% C
- static void MX_LPUART1_UART_Init(void)7 T2 h& U% T' ~+ U: T( ]; _
- {
3 t+ [2 n! ?3 q - hlpuart1.Instance = LPUART1;
C" Y+ `. X& G1 ~ - hlpuart1.Init.BaudRate = 128000;
, m0 Y9 V3 U C: H - hlpuart1.Init.WordLength = UART_WORDLENGTH_7B;
3 r" R# t- }( F* Y - hlpuart1.Init.StopBits = UART_STOPBITS_1;' S, o4 q4 q& |' ?$ m, B
- hlpuart1.Init.Parity = UART_PARITY_NONE;' ]9 t3 B6 B p" e1 q$ I6 W7 c2 F7 E
- hlpuart1.Init.Mode = UART_MODE_TX_RX;5 l+ L, c* M6 U
- hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;: u. D6 @" F0 S8 \9 D7 G1 w
- hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;+ k$ e" v& y+ L. z0 {8 C! y; u
- hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
9 G/ ~. S# C' T$ X2 M# x - if (HAL_UART_Init(&hlpuart1) != HAL_OK)8 {6 o3 ~7 L% f7 o
- {( C) H: w U8 r |/ Y
- Error_Handler();
& n4 L! K3 b6 P$ ~4 ` - }+ {. h$ B- q1 H. j6 M+ ?
- }' b0 S6 L# a) x9 [& O7 q" z
- " c' t9 ~$ l% e- U2 J& x
- /**( N. v' e( T- V* Y8 c8 d
- * @brief GPIO Initialization Function
- h( v' R6 _2 p& i - * @param None4 _( E- X4 l& ~ H4 k
- * @retval None; I& f8 r% V& C' A# l
- */
; t/ q4 A+ Z/ O0 n8 Q - static void MX_GPIO_Init(void)
9 I) X3 t/ ^7 w! R7 l7 o. K4 d% | - {* F5 U0 ]7 A N( d3 j
- GPIO_InitTypeDef GPIO_InitStruct = {0};) W3 }) t5 K7 Z) A
- * n9 H9 l" l# z: m7 L3 f- Q2 Z
- /* GPIO Ports Clock Enable */3 Q6 t# N, ` Z# r( }: \
- __HAL_RCC_GPIOH_CLK_ENABLE();" P' |5 E7 C4 G$ z: ^1 ?
- __HAL_RCC_GPIOA_CLK_ENABLE();
1 h& Y7 z% T' e* _9 [$ p- j - __HAL_RCC_GPIOC_CLK_ENABLE(); m. A! x, j2 q* E- U' ^
- __HAL_RCC_GPIOB_CLK_ENABLE();
) K ~) |% C5 w3 R - 1 ^: r' D. G' e
- /*Configure GPIO pin : PB13 */
3 _$ P% w2 G O p6 Y - GPIO_InitStruct.Pin = GPIO_PIN_13;( N: t7 ~% P* K
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
2 w- V6 G1 Z' M8 }/ k6 V8 S - GPIO_InitStruct.Pull = GPIO_NOPULL;
9 G4 N$ j6 F, D5 i1 m/ t0 `6 f - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
4 [$ P3 V1 b9 D) f9 H7 Q, v% f - GPIO_InitStruct.Alternate = GPIO_AF2_MCO;
4 G" s( \& Q g% Y0 q - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
8 P% z( C5 O0 A9 V9 | - }
复制代码
* e' D7 Z+ V$ P) J! r3 j: z( ~6 W/ r' J% @, P
9 r. f( X: |+ U) d# i: j: k" G _) p1 n. Z) h( N ?7 O, Z+ Y( i, w
- R: d8 c$ A6 n. X6 k, S |