STM32U0系列微控制器中的ULP(Ultra Low Power)UART接口设计用于在低功耗应用中实现串行通信。# P1 N7 @& ~' I) N8 d7 _
硬件特性:
4 j" l; k% v" v* ?. X9 o 超低功耗模式支持:ULP UART具备在低功耗模式下保持唤醒源的能力,允许在微控制器处于低功耗状态下依然能够接收数据或触发中断,从而快速唤醒并处理通信事件,有助于降低系统平均功耗。
7 L# Z0 ~6 G, W9 N& o' f9 g电源管理:ULP UART可能集成电源管理特性,如低电压检测、自动电源关断等,有助于在闲置时减少电流消耗。
/ i- K; A: l( Z. ` h5 l* I, k% E! q$ A专用低功耗引脚:某些型号的STM32U0可能提供专门针对低功耗优化的UART引脚,这些引脚在待机或睡眠模式下具有更低的漏电流,有助于降低整体系统功耗。
6 m G* [7 r' m& N' w1 E0 u软件配置:, ` c% y4 l1 B4 j$ `+ i
1 波特率设置:根据实际通信需求选择合适的波特率。ULP UART可能支持较低的波特率选项,有利于在低功耗模式下降低通信时的瞬态电流。
* f0 n; q3 R+ d* L2 数据格式:配置数据位(通常是8位)、停止位(1或2位)、奇偶校验(无、奇校验、偶校验)等参数,确保与通信伙伴的设置一致。/ Q: j' l8 D7 M$ F/ p4 _# t3 |
3 中断与DMA:& s4 ?$ Z/ p( ~
中断:启用接收/发送中断,允许微控制器在数据准备好或传输完成时被唤醒,而非持续轮询,有助于节能。确保在中断服务程序中快速 处理事件并返回低功耗状态。DMA:如果ULP UART支持,可以使用DMA(Direct Memory Access)进行数据传输,无需CPU干预,进一步降低功耗。尤其在批量数据传输时,DMA可以显著减少CPU唤醒次数。
# I1 X+ d! M l4 低功耗模式切换:在进入低功耗模式前,确保正确配置UART的唤醒源(如空闲检测、接收数据可用等),并在唤醒后恢复正常的UART操作。- L! p; U( X K! x, c7 J
功耗优化技巧:. D, ^6 `0 T8 Y+ d9 z
1 禁用未使用的功能:关闭不需要的UART功能(如硬件流控、校验等)以减少不必要的电流消耗。
. W3 H! F3 w4 P3 ]
4 z& R( t/ J' f2 节电模式:利用ULP UART的节电模式(如果支持),在数据传输间隙降低工作频率或电压,减小功耗。9 i- c* c# @3 ~$ w
3 唤醒阈值调整:某些ULP UART允许设置唤醒阈值,调整阈值可以平衡灵敏度与功耗,避免因噪声引起的误唤醒。& B1 Q8 h# @ A0 [/ v9 F
4 软件定时器:使用精确的软件定时器代替连续轮询,以定期检查UART状态或处理数据,减少CPU活动时间。
- n% B% J/ Q4 i- u& Z! V6 C/ `; b# u
初始化:调用HAL_UART_Init()函数,设置UART参数(如波特率、数据格式等)。2 r% C% Z) Y! \4 I; C3 [4 r$ ?5 |
中断配置:开启相关中断(如接收中断),并编写对应的中断服务程序。
. W) ?3 ?- W* p7 B4 ~. M5 FDMA配置(如果使用):配置DMA通道,关联到UART,并设置传输参数。
* P1 X- U9 u2 R7 t) o* |& g发送/接收:使用HAL_UART_Transmit()、HAL_UART_Receive()或DMA相关函数进行数据传输。
9 J1 o, w) { e0 @8 N调试与测试:
4 ^# C" f5 F; H3 O& G2 a: P
9 x! n3 y; | }
6 p; V+ }( N; T0 ~9 K8 K- a8 k: r# [8 Z; E$ v- X
MX_LPUART1_UART_Init初始化:$ u. G) @- b* V7 n' E& o
+ C* I7 M7 @/ c& P0 J8 r' R- static void MX_LPUART1_UART_Init(void)% V' y7 @/ }* f! U2 g
- {4 y1 ?% j- s: w5 i1 R; o0 o8 W
- ( `. N& F4 A4 V1 N9 B) _
-
% e4 e/ L5 A8 {. a8 y$ s* N/ q - hlpuart1.Instance = LPUART1;/ ]9 b9 }3 c5 p9 {# r
- hlpuart1.Init.BaudRate = 115200;5 c( U( W8 G# L) e2 c
- hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
, x5 X. E6 e1 v& ]" P - hlpuart1.Init.StopBits = UART_STOPBITS_1;5 N. S: ]" n0 ]9 e5 T: R# p
- hlpuart1.Init.Parity = UART_PARITY_NONE;
]0 k; R: u5 M8 N8 W - hlpuart1.Init.Mode = UART_MODE_TX_RX;
# ~0 X; d1 u, O3 B - hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
* c0 j: z' b; J+ J& l$ j - hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
u; G: u. c9 ^* E: z - hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
$ z! Z4 w7 j% N/ E2 g8 H - hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;6 k4 S0 b) M4 z' o: y$ N, v# w
- if (HAL_UART_Init(&hlpuart1) != HAL_OK)
' P& @' i$ w0 P2 Y; R1 _* } - {
% y1 ~/ Q6 H% \7 H$ R4 J - Error_Handler();
8 _9 I% s: r; D8 v - }* c6 O. \0 o8 {2 e0 Q
- if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)3 _0 j# T# u7 o) K$ |6 G& J0 ]
- {
. n; b7 d! ?' [7 v |, q0 ^ - Error_Handler();
D# `0 l& L) \( t! T1 J* q0 [ - }9 {2 J5 I: T2 V$ U9 |" y/ M9 ?
- if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
( y) e: g1 h2 W* @) y - {% Q5 J* w8 |# F
- Error_Handler();7 k @: {7 J' S# H
- }( g9 ?% v/ o3 S. @
- if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
, M3 V, `) C, M3 @0 _ - {+ \; a) q" W; E7 d$ a9 Y9 M
- Error_Handler();% j' L9 N! F9 t: r' b
- }
& f# | O7 m" A9 L$ e! m - 4 h8 `* d0 g" p% I& j Z! F
- }
复制代码
* R7 q r0 R$ D j+ a: H) O3 X7 e3 i k7 J0 G: F
- static void MX_LPTIM1_Init(void)
+ r) u- N; j& q& R' T4 b" V - {! u# j6 M( o) s) r9 p
, e2 D; V3 |( i1 t- /* USER CODE BEGIN LPTIM1_Init 0 *// y0 Q, H9 N* o% H
5 n5 M- r; O+ r9 ~3 y- /* USER CODE END LPTIM1_Init 0 */2 B& H' k" C$ c5 z
; f6 P! P9 u2 U) z- /* USER CODE BEGIN LPTIM1_Init 1 */0 P% Y9 I7 @6 Z! j+ G
" w2 \, \2 N( `; |/ P- /* USER CODE END LPTIM1_Init 1 */
* n! p$ R6 q8 X( S3 o. O! L - hlptim1.Instance = LPTIM1;
& @7 F- `. I4 f9 \3 E* h - hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
$ \9 |. O1 a& X& S- j" i( M - hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;" @6 D, _, r6 T7 b, }" G* b
- hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
5 A& O1 w1 r) d+ a - hlptim1.Init.Period = 65535;: g) e; Q! q% q
- hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
, G+ K. e/ `+ n3 U* M. K/ l - hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
6 W8 Z' B: n: f' \ - hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;0 W% t3 j e# C3 U; G: c6 }
- hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
1 J( [8 h/ @; F/ U. N' s; v - hlptim1.Init.RepetitionCounter = 0;
1 e7 G; L- m2 Q o+ w+ O9 Z/ ^ - if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
. ^) C/ Y7 Z5 L8 Q6 u, u - {
; p* `7 i0 i( b A - Error_Handler();
! S5 K6 K3 R0 ?1 R8 \# B+ j - }6 k; H. U1 ?( T0 v( E
- /* USER CODE BEGIN LPTIM1_Init 2 */
$ n' X. Z# H( X3 W - 5 t6 I1 M! z% J2 W# H' ?# m. c* ^
- /* USER CODE END LPTIM1_Init 2 */
9 |4 P* L; g- j2 u W! W: X2 Q
. ~: ^4 p8 i" J0 g- }
复制代码 , {& ^) V4 H/ Q, K ]1 @
& Z0 ?! A2 I5 S
: \8 w I7 s* a这里可以选在HAL库 LL库
8 c" Z3 Y2 _- d# p8 I* z
. h' b3 P3 Q6 r9 {* z/ B0 _1 a
1 ?5 q2 l* N- p; F- HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE);0 g* |- P8 U. f& Z8 N
/ i+ }6 `4 j% _6 w- HAL_Delay(1000);
复制代码
( z1 K8 f, p: Q+ ^: `3 A/ `2 C4 f* b" \* [. m8 Q7 g4 G6 X3 L
# e5 E/ L* `5 i
运行如下:0 d e' e& {% h, V+ J6 E& Z" \( b
% S7 ^$ s+ ]' f# b+ F) f& ^' v3 J# y$ Z; w' \0 _0 E- [
4 }' E( l& D, @/ {) E7 C+ y r
- x- @- A, _6 K+ [" C |