STM32U0系列微控制器中的ULP(Ultra Low Power)UART接口设计用于在低功耗应用中实现串行通信。
1 f. ]* n, ~- ?9 |6 _# @硬件特性:
5 n0 R3 m/ Z; X3 w2 O 超低功耗模式支持:ULP UART具备在低功耗模式下保持唤醒源的能力,允许在微控制器处于低功耗状态下依然能够接收数据或触发中断,从而快速唤醒并处理通信事件,有助于降低系统平均功耗。
) e* g6 G6 N4 Y/ U8 t9 K) `& M电源管理:ULP UART可能集成电源管理特性,如低电压检测、自动电源关断等,有助于在闲置时减少电流消耗。
' H+ n9 m0 U( I! I) i% a专用低功耗引脚:某些型号的STM32U0可能提供专门针对低功耗优化的UART引脚,这些引脚在待机或睡眠模式下具有更低的漏电流,有助于降低整体系统功耗。0 r) I$ G! g; [) |3 ^: E, w# z) K% ]
软件配置:
, d C9 u2 j- O1 波特率设置:根据实际通信需求选择合适的波特率。ULP UART可能支持较低的波特率选项,有利于在低功耗模式下降低通信时的瞬态电流。0 X* p, h1 r6 W5 T. H, B( ]4 ~- Y
2 数据格式:配置数据位(通常是8位)、停止位(1或2位)、奇偶校验(无、奇校验、偶校验)等参数,确保与通信伙伴的设置一致。5 Y9 k7 b# j" m: u. L' }! q
3 中断与DMA:
8 E7 v" s9 M3 h8 E Z9 B 中断:启用接收/发送中断,允许微控制器在数据准备好或传输完成时被唤醒,而非持续轮询,有助于节能。确保在中断服务程序中快速 处理事件并返回低功耗状态。DMA:如果ULP UART支持,可以使用DMA(Direct Memory Access)进行数据传输,无需CPU干预,进一步降低功耗。尤其在批量数据传输时,DMA可以显著减少CPU唤醒次数。
8 E, u Y) b, e# E4 低功耗模式切换:在进入低功耗模式前,确保正确配置UART的唤醒源(如空闲检测、接收数据可用等),并在唤醒后恢复正常的UART操作。8 s- d' d) V0 {! b3 t9 v( d
功耗优化技巧:; v" o7 s. U" f( ~$ O
1 禁用未使用的功能:关闭不需要的UART功能(如硬件流控、校验等)以减少不必要的电流消耗。- j# D9 t% _5 Q3 t6 z% D! s7 r
7 v6 \4 p" @" I" `$ E ]2 节电模式:利用ULP UART的节电模式(如果支持),在数据传输间隙降低工作频率或电压,减小功耗。; D8 i$ X) V" |4 c+ |
3 唤醒阈值调整:某些ULP UART允许设置唤醒阈值,调整阈值可以平衡灵敏度与功耗,避免因噪声引起的误唤醒。
& o5 x8 k4 K/ L2 i4 软件定时器:使用精确的软件定时器代替连续轮询,以定期检查UART状态或处理数据,减少CPU活动时间。! d3 i& g4 V" f, b# }
s/ G6 C! D7 [3 n( z$ R/ |4 v
初始化:调用HAL_UART_Init()函数,设置UART参数(如波特率、数据格式等)。
3 k4 B( R4 x0 q2 W9 C* F2 n5 x中断配置:开启相关中断(如接收中断),并编写对应的中断服务程序。# O) Q, ]* V6 n+ m% [! i, u7 @
DMA配置(如果使用):配置DMA通道,关联到UART,并设置传输参数。
4 S. n- o- x2 n* E, n发送/接收:使用HAL_UART_Transmit()、HAL_UART_Receive()或DMA相关函数进行数据传输。
6 F* ^/ }1 ^! H6 b1 d m调试与测试:
# n M* V% B) N, K/ T. Y- e
3 }, T$ t+ \) u, o/ ?3 V6 ]4 G4 |% ^3 A% _4 `# h$ K. [
+ A4 N1 y W$ |3 b# M8 ? Q) u& E MX_LPUART1_UART_Init初始化:
' \$ u7 A& L7 x7 @. O. k
& A, w0 B- K9 O7 W7 Y- static void MX_LPUART1_UART_Init(void)
1 e) w7 `% ]) Y6 a) c& F, `- w: ?5 u - {
) q. r$ w! k$ E; ~" C3 x! O% N! k6 i5 U# X - , `* w9 }7 G& _3 g
- $ r4 R# H6 t9 v! T. L
- hlpuart1.Instance = LPUART1;
+ n3 ?' q8 q5 ?# e/ a. j; O - hlpuart1.Init.BaudRate = 115200;
4 n2 b' b I" r. ]) t - hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
" N9 u% r) p) y) `; @4 } - hlpuart1.Init.StopBits = UART_STOPBITS_1;
6 c n" q# m, o m4 }5 S - hlpuart1.Init.Parity = UART_PARITY_NONE;4 G5 u9 ? O; f3 u$ h3 U% U8 v9 d
- hlpuart1.Init.Mode = UART_MODE_TX_RX;
% v0 B& b' w: B - hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;9 d! v& _: q1 d4 z! q6 c6 M
- hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
5 ], L- F. D5 N+ j/ G! { - hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;/ Y+ {- ?' w- M. T8 ]& h# e- N
- hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;$ {& G2 C) Q# M& }# `9 ~
- if (HAL_UART_Init(&hlpuart1) != HAL_OK)
' s0 \* \! b4 k# @ - {
0 X4 Y2 @( f N- t" A - Error_Handler();
' {7 X8 b. g: _4 y5 [( p0 Q - }
& ?; i2 J6 D1 y - if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)% ` H3 J0 k3 `! J; B9 G% |" H
- {8 w% H* }+ Y5 @$ P" y% j
- Error_Handler();
, a h# g B* D; {+ z4 R - }
- L, Y4 j7 ^" l) K - if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
: W6 v& ^9 ^ |. W1 d2 u - {0 v m2 B K D' N6 M i' I* k
- Error_Handler();3 C7 Z0 @- r/ T* K; ?$ f" ^
- }) V+ r X0 Y6 Q$ n0 [) Z- p/ A
- if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
9 U9 R/ Z0 }( {8 V+ { - {2 A7 ~ c4 y' K' K
- Error_Handler();$ {% M* I8 |: o/ |5 k2 D
- }
& B& C6 E% `) Z% t -
9 P' y( s) X" `2 j+ b8 e - }
复制代码 9 b% H" O2 A. I% ]4 `
0 l% N; J$ m1 Z9 ]2 I/ l3 A1 S0 w- static void MX_LPTIM1_Init(void)& ]" c$ f" R% {5 `' t& w9 O, V& d
- {% R# u# J5 _: i" R. P
; [) ]$ O: o) M8 Y& J' h- /* USER CODE BEGIN LPTIM1_Init 0 */
7 _1 M, ]7 k' S( b A8 ]* N% r7 B - # ?7 M% k% o; o6 t
- /* USER CODE END LPTIM1_Init 0 */
9 _3 \2 m o: N3 w. v- c9 k; a - $ x5 j: S2 a6 I% i" S n
- /* USER CODE BEGIN LPTIM1_Init 1 *// r; T4 P. R+ @3 _' A! x+ a. Y
- # e: i" }% u# P. a# o. e: l$ D
- /* USER CODE END LPTIM1_Init 1 */
& ~5 c0 G- l; J Y; W7 w2 Y) I2 A2 ]3 c - hlptim1.Instance = LPTIM1;. ?% R O0 r7 t, s% b w6 ]
- hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;8 ]+ n& ~6 [0 \! ]# a
- hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
/ E+ w3 D4 a; g* f$ {( u - hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
) x% ?# c* K, Q3 m% O - hlptim1.Init.Period = 65535;4 d, |! A! k. r7 W( t; x( M" W
- hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
3 \1 c4 p1 e a! s4 ~7 N - hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;# Q( @) y( z6 ~$ P. C9 M% R
- hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
0 l9 c- c' L9 I2 x3 J. B* W - hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
8 _& B7 _, E6 F O' a" c& b; g6 M - hlptim1.Init.RepetitionCounter = 0;# W. t$ z$ {/ n' b' b7 x1 l. N
- if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
( H4 ?$ Z+ x3 [# h5 }% P9 s: X4 I - {
' j) E, T& q- S& K - Error_Handler();3 f* s- H/ C: R6 i5 o7 q- O! l; ?3 |
- }
- V3 B I' h, s# r. b! u1 R - /* USER CODE BEGIN LPTIM1_Init 2 */3 n% H; a7 L. P4 r
- 5 l% `7 G( s/ @. ~
- /* USER CODE END LPTIM1_Init 2 */
! ]6 E& R" [' `9 _8 l0 \
2 R7 C+ n/ w8 V$ |- G- }
复制代码
, h6 j- w& F S( _) l! B
$ O# l# W% t+ z( g& w$ M
% ]. t% r' L& g5 K9 V这里可以选在HAL库 LL库
. L3 V4 F* h# Z9 J& j. W" h# h
$ ?9 F8 z4 ` x3 B8 Q
) M% g0 _. X0 F! x a7 f; O- HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE);
* s0 B9 h* C) b, j" g4 A5 `
: X7 c0 Y+ s4 ]& e% U ~ X/ c4 n- HAL_Delay(1000);
复制代码
" v3 d5 P9 K; R4 n- x& s
7 i: P$ R2 F0 D2 \! m
! f. `( e5 L: v9 u( S% y2 b8 R运行如下:% c4 T$ x d% i$ w+ @
8 _) k$ H9 k2 L: S2 o5 h& ?% o
% n; V5 [1 o0 I) o r; v, m- q' e$ M
# d* a( G+ H+ ~# T* L
- b' W( f0 b& \! m# O3 w. h |