STM32U0系列微控制器中的ULP(Ultra Low Power)UART接口设计用于在低功耗应用中实现串行通信。
0 P7 K1 ~2 k. e$ T" l硬件特性:1 o0 S, F; J. T% y
超低功耗模式支持:ULP UART具备在低功耗模式下保持唤醒源的能力,允许在微控制器处于低功耗状态下依然能够接收数据或触发中断,从而快速唤醒并处理通信事件,有助于降低系统平均功耗。2 O. l% T: {: G% R8 S5 x g; I
电源管理:ULP UART可能集成电源管理特性,如低电压检测、自动电源关断等,有助于在闲置时减少电流消耗。
- U& p9 U- Y) t7 G: }专用低功耗引脚:某些型号的STM32U0可能提供专门针对低功耗优化的UART引脚,这些引脚在待机或睡眠模式下具有更低的漏电流,有助于降低整体系统功耗。$ b' {# @% ?0 O3 _0 _" \4 k l) ]; b! \
软件配置:
1 d% l% i$ O) r8 i* R1 y7 E8 i1 波特率设置:根据实际通信需求选择合适的波特率。ULP UART可能支持较低的波特率选项,有利于在低功耗模式下降低通信时的瞬态电流。& o* Z4 T$ X2 Z: \/ y# x7 t
2 数据格式:配置数据位(通常是8位)、停止位(1或2位)、奇偶校验(无、奇校验、偶校验)等参数,确保与通信伙伴的设置一致。/ J6 W6 u. n4 u
3 中断与DMA:
" L$ B. s% m8 J( \5 D; |5 p 中断:启用接收/发送中断,允许微控制器在数据准备好或传输完成时被唤醒,而非持续轮询,有助于节能。确保在中断服务程序中快速 处理事件并返回低功耗状态。DMA:如果ULP UART支持,可以使用DMA(Direct Memory Access)进行数据传输,无需CPU干预,进一步降低功耗。尤其在批量数据传输时,DMA可以显著减少CPU唤醒次数。3 b' [& Z$ X) R* e
4 低功耗模式切换:在进入低功耗模式前,确保正确配置UART的唤醒源(如空闲检测、接收数据可用等),并在唤醒后恢复正常的UART操作。8 a" C3 S8 u t4 y( H7 J/ e
功耗优化技巧:7 Q5 t, p$ n: _. o, F( n7 t
1 禁用未使用的功能:关闭不需要的UART功能(如硬件流控、校验等)以减少不必要的电流消耗。7 {( A d# n: e
3 H3 F" O. u' v5 F- d% L9 f. |9 b2 节电模式:利用ULP UART的节电模式(如果支持),在数据传输间隙降低工作频率或电压,减小功耗。
. K( l& |: l3 G. R. ?2 H: s4 ]3 唤醒阈值调整:某些ULP UART允许设置唤醒阈值,调整阈值可以平衡灵敏度与功耗,避免因噪声引起的误唤醒。
& d( @- e0 h* L* A0 [4 软件定时器:使用精确的软件定时器代替连续轮询,以定期检查UART状态或处理数据,减少CPU活动时间。# \0 |& i* W1 B1 Y
! I, E* Z7 b& c6 Z3 V5 g初始化:调用HAL_UART_Init()函数,设置UART参数(如波特率、数据格式等)。
/ H2 s1 t* L. [8 s中断配置:开启相关中断(如接收中断),并编写对应的中断服务程序。
7 n+ S" L6 L: B# s' b! l: U9 PDMA配置(如果使用):配置DMA通道,关联到UART,并设置传输参数。
% S* F. ^: x' ~% s1 P发送/接收:使用HAL_UART_Transmit()、HAL_UART_Receive()或DMA相关函数进行数据传输。
0 e1 }1 b2 r3 }. @调试与测试:6 S$ |# E4 j/ y5 A, E
+ d- o8 a" V9 j" ?# Q
( n5 V( a" @. }8 E
+ X. I, I1 {) I C% y
MX_LPUART1_UART_Init初始化:' x9 p8 H y$ l% _
3 `% A* u( Z7 h) e6 V- static void MX_LPUART1_UART_Init(void)
6 k# Q% J0 j0 L, |9 I: W. g - {( ~8 e* O3 o1 m" O8 e
! M3 U* E* ?4 c" R- ! T6 s. Q" H+ C- `, h j: T- D4 F
- hlpuart1.Instance = LPUART1;; ]% k/ Y# t( n
- hlpuart1.Init.BaudRate = 115200;
; Q: p7 ]1 Y8 P; a# i - hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
* k6 M9 N2 Y _8 k: \ - hlpuart1.Init.StopBits = UART_STOPBITS_1;% P( F# g$ |7 @6 }0 r
- hlpuart1.Init.Parity = UART_PARITY_NONE;
% }) p ~- L$ d# Q l8 b# x a - hlpuart1.Init.Mode = UART_MODE_TX_RX;9 p3 F3 T" n, X( V9 \" ?- f1 J
- hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;- V7 m8 `$ p1 ?. Q/ o! f# {
- hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;6 Z1 G0 h, @7 n& A
- hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;$ o5 @) t2 P8 @3 ]) j7 K
- hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;
& }5 P( t0 Q+ H O" U- g - if (HAL_UART_Init(&hlpuart1) != HAL_OK)' X4 l0 [9 ~; Q: x; g
- {
6 E" Q+ ?+ I# e3 P - Error_Handler();: l! u2 C* m& H( ~2 b& ]# `! `% N4 |
- }7 X6 }. z1 [. S& q
- if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
% O; `0 x* P# f% d - {
8 l9 S: l! d$ v O5 a- h - Error_Handler();& g3 s Y# h$ l3 ?
- }
. d% B( W7 \2 f4 _% A - if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)6 ~( B/ |* }! h6 o- S6 U5 z
- { v& _! S( J6 n
- Error_Handler();3 v% D0 q# [+ z r+ s
- }
* |" ^% W6 h" {, v9 ^ ^$ I$ T4 b: g - if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK). ?- M5 g0 W S! e, `
- {1 |; M" ~* | E" x" o
- Error_Handler(); s1 N( q4 r3 \1 Z, W/ j8 E8 r
- }! A6 l. ~" f5 D; V9 z0 _
- # ?. |1 k3 D4 U* u/ J# r+ W
- }
复制代码
+ ]( H! i+ j' W& b6 S: O( n" |7 Y. _: ~/ T
- static void MX_LPTIM1_Init(void)
# T2 V5 |4 W9 ?+ g9 x% s# M$ y% w - {+ I5 h4 V+ I* n0 s! {+ Z
- ! G* y! m$ e* m
- /* USER CODE BEGIN LPTIM1_Init 0 */
7 ^; t. g% `( h
' O* ~) }$ \$ P; m' l* [- /* USER CODE END LPTIM1_Init 0 */
) x9 Y; r! S* O3 ~$ a) f - 7 C, g4 }3 R8 v. K& l
- /* USER CODE BEGIN LPTIM1_Init 1 */% l, ~) j1 ?/ B1 X/ H6 ]
, p' T, x L( y2 n- /* USER CODE END LPTIM1_Init 1 */$ g* h5 Y. P) A0 H& [
- hlptim1.Instance = LPTIM1;
: S$ I( p) g c6 q8 K( d - hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
' }5 u/ C" s: ^$ m3 [8 s - hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;! t5 @7 g! o( |' \ E* \
- hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;; p- m/ |: H& ~0 A* O6 V6 o7 H H
- hlptim1.Init.Period = 65535;4 h" X& Y1 ~3 A+ H" l0 L, X
- hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;' n2 S, r' w7 M
- hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;! G( ` S& n& I; r
- hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
4 O' H9 P5 S6 J* T+ V - hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
, O4 B' {# i! H( j G$ K - hlptim1.Init.RepetitionCounter = 0;
' o2 F$ {- j! E* F/ g8 Z - if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)# c) Q" e1 P& _9 j4 d
- {6 l' X0 U8 ?9 Y( E/ ~
- Error_Handler();# X, o! V8 j3 K* |* X, f4 o- ]
- }
7 {" _% d4 b* [5 U( I9 i+ \ - /* USER CODE BEGIN LPTIM1_Init 2 */
* _9 Y) l; Y2 d- \ - # D1 R0 u' s1 G: w+ t1 [$ v
- /* USER CODE END LPTIM1_Init 2 *// G# ]+ M& R O
- + L, `" T$ E; |! d
- }
复制代码
9 I' l% W, @2 x I( W' x& N; Z+ r8 @ g/ K, o* l
" h+ q6 o. ^$ k7 o+ n) H* j E
这里可以选在HAL库 LL库
: ?& B8 ?+ G+ L8 P
- [5 }; M; \6 e, U; l
% S7 f+ ?' @& @4 D$ c' c9 t
- HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE);
( V4 y! C9 W# L) w3 O7 `- Y - 4 P1 G! M% V( M4 [- I9 L
- HAL_Delay(1000);
复制代码 9 P7 Z! b8 @4 a+ f5 }+ C0 K
1 a2 b) \* d# W0 c- m; s2 Z1 L1 Z1 F$ {
运行如下:' S p' G" r3 V9 ~( R1 S
& _4 d' g" ~! O7 U5 M" |- K
" Q" R0 [4 _, y5 H3 ~
3 G2 q9 Y. u2 {% L
1 j8 N1 e% o( O- F6 Y |