STM32U0系列微控制器中的ULP(Ultra Low Power)UART接口设计用于在低功耗应用中实现串行通信。
- A7 Q( z: W" P硬件特性:6 v& z- K' l+ |& ~" S
超低功耗模式支持:ULP UART具备在低功耗模式下保持唤醒源的能力,允许在微控制器处于低功耗状态下依然能够接收数据或触发中断,从而快速唤醒并处理通信事件,有助于降低系统平均功耗。: Y3 o/ [( u% Z. h, T. s( O
电源管理:ULP UART可能集成电源管理特性,如低电压检测、自动电源关断等,有助于在闲置时减少电流消耗。# X; h; f* L f( x
专用低功耗引脚:某些型号的STM32U0可能提供专门针对低功耗优化的UART引脚,这些引脚在待机或睡眠模式下具有更低的漏电流,有助于降低整体系统功耗。3 U% m# v" _' [0 F' j- F! B
软件配置:
. W: |3 t, m7 q1 a2 M1 波特率设置:根据实际通信需求选择合适的波特率。ULP UART可能支持较低的波特率选项,有利于在低功耗模式下降低通信时的瞬态电流。8 _8 R- ]* i& K! b9 N( i: B# i
2 数据格式:配置数据位(通常是8位)、停止位(1或2位)、奇偶校验(无、奇校验、偶校验)等参数,确保与通信伙伴的设置一致。( _, Z3 w' a3 w
3 中断与DMA:& | s) F @8 m- |6 d' ~+ I
中断:启用接收/发送中断,允许微控制器在数据准备好或传输完成时被唤醒,而非持续轮询,有助于节能。确保在中断服务程序中快速 处理事件并返回低功耗状态。DMA:如果ULP UART支持,可以使用DMA(Direct Memory Access)进行数据传输,无需CPU干预,进一步降低功耗。尤其在批量数据传输时,DMA可以显著减少CPU唤醒次数。
) q! u# [6 h0 r6 q: P2 K4 低功耗模式切换:在进入低功耗模式前,确保正确配置UART的唤醒源(如空闲检测、接收数据可用等),并在唤醒后恢复正常的UART操作。
/ B5 L" Z5 R$ h功耗优化技巧:: n7 E! \/ a! H- ^- p' I/ _/ L* _
1 禁用未使用的功能:关闭不需要的UART功能(如硬件流控、校验等)以减少不必要的电流消耗。& F! a5 e( t1 j9 v! a
$ P* T5 V; k. P2 Z; E4 _
2 节电模式:利用ULP UART的节电模式(如果支持),在数据传输间隙降低工作频率或电压,减小功耗。
! p- `4 Z. M! ?4 E2 t3 t( B) d3 唤醒阈值调整:某些ULP UART允许设置唤醒阈值,调整阈值可以平衡灵敏度与功耗,避免因噪声引起的误唤醒。
7 A. t! s/ \4 M4 软件定时器:使用精确的软件定时器代替连续轮询,以定期检查UART状态或处理数据,减少CPU活动时间。2 G0 W) V/ H" y6 z' e" \1 `* h f- y
2 a, z2 q1 q0 t! ^
初始化:调用HAL_UART_Init()函数,设置UART参数(如波特率、数据格式等)。# c. q2 e" i& f5 \( L
中断配置:开启相关中断(如接收中断),并编写对应的中断服务程序。5 S& f' [2 I. R
DMA配置(如果使用):配置DMA通道,关联到UART,并设置传输参数。
2 k( v) }1 R8 E! e2 J0 r发送/接收:使用HAL_UART_Transmit()、HAL_UART_Receive()或DMA相关函数进行数据传输。
/ a; C1 h. e8 x调试与测试:
1 U8 m+ w& I! H4 `$ Q5 B% V
+ @3 C1 Q R0 ?4 a
* T0 j; \; p8 ]6 F# `) X# \# a; G6 F2 g; n2 X2 U6 |2 |, A
MX_LPUART1_UART_Init初始化:
# H6 h' _1 V* E) p
) W, D; a0 z4 ? P7 s5 r- static void MX_LPUART1_UART_Init(void), a9 N u( }6 a3 q
- {
2 T( o0 L$ c6 Q0 C
; ?7 z1 q* Z+ ?-
. A* h( i, F# R4 g - hlpuart1.Instance = LPUART1;
& R) s8 C' H3 V+ Y* c* k - hlpuart1.Init.BaudRate = 115200;0 {5 J/ }- C: g* a p8 b- k1 B
- hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;6 Z/ {. g% s z% u7 R/ H6 [; x
- hlpuart1.Init.StopBits = UART_STOPBITS_1;
' {& f3 R! r3 ^8 l! [6 W V - hlpuart1.Init.Parity = UART_PARITY_NONE;
8 b% m( }% H+ r9 G; S - hlpuart1.Init.Mode = UART_MODE_TX_RX;6 Y* n" T" D* Z% O0 V
- hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
2 W1 a# V8 z! Z. p& A3 [! e - hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;/ t0 e8 l" z: O. T( E/ q
- hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;1 [/ `0 ?- w- C) F& H2 k
- hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;% i; o* |0 G, O, C9 g# ?8 I1 t8 z
- if (HAL_UART_Init(&hlpuart1) != HAL_OK)
/ Y o( m: L& s# o7 _ - {
$ x& H2 ^$ z$ J0 Y% I+ p - Error_Handler();
" ?1 s( V% C- Z3 J8 a - }
8 Z, r( r! k. T# g - if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
- f+ n k7 ?3 ]# J0 t3 H4 t - {( ?% }' ^2 ?5 j u5 K; F Y
- Error_Handler();% I/ C7 F0 ]( k* Q' _: i
- }8 ?" l& Q6 X- g3 S# Z; O
- if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
% m- c5 n$ m F3 } - {6 n" |- D5 V* O7 l, T- m% ^# w% Y
- Error_Handler();8 @2 X2 t, }; {( X9 X0 W3 r! E
- }4 g* G0 m4 m& P$ m5 b
- if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
8 i+ g" N; [/ x% ]) M - {! k' o/ I( @4 ]
- Error_Handler();$ g- }& s3 U* ?8 t
- }
( B( X# r: t9 {% O - 9 R$ m; p- }+ N# o8 v
- }
复制代码
& G2 @, f4 l+ m3 F1 e# Y: i: O# }) p. k4 O% X" C
- static void MX_LPTIM1_Init(void)' s r. T) _# @# B. `/ K1 Z+ B
- {$ U8 o* l; c: Z8 {$ C8 l
- ; x5 r m/ N4 |
- /* USER CODE BEGIN LPTIM1_Init 0 */9 L0 A F3 ?' [ O8 _; O
- , B, k2 T$ e1 p
- /* USER CODE END LPTIM1_Init 0 */: I$ Y$ v9 I! M. ^9 a2 u
- 2 t) D6 ~9 S' W1 P" D& K
- /* USER CODE BEGIN LPTIM1_Init 1 */
: y$ ?) Y8 e- b; l% k - : H: i! M2 C, O) N/ K9 G# O
- /* USER CODE END LPTIM1_Init 1 */
) x5 A5 |+ E& c2 [( Z - hlptim1.Instance = LPTIM1;4 B8 \/ g+ \* R2 v3 o3 ^ O9 k
- hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC; S; e7 p ~, d' N! y# {7 N4 p- q% u
- hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
1 ^' `3 _1 }( Y W - hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;+ ~: X& t& l( k( n; N8 M0 \& y
- hlptim1.Init.Period = 65535;
l: [. o. v! f& I: w2 U - hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
$ A1 Z- W: z+ E+ C - hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;. P9 h$ z I' |! Z* n8 d
- hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
0 f, a s; I: A - hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
\6 L. F4 {5 c# C7 [; m - hlptim1.Init.RepetitionCounter = 0;
2 Z* F( f, T$ w - if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
! j B# K1 T3 ]( |9 k5 n$ p" R' n - {: Y- `) e# Q' a" P
- Error_Handler();+ l8 a* X- P' g7 }
- }
0 v) B0 U# I! | - /* USER CODE BEGIN LPTIM1_Init 2 */
8 c3 J, Z- A- v5 g* ?5 ~3 j/ \ - 4 g4 t- ?3 a2 C6 E, k
- /* USER CODE END LPTIM1_Init 2 */
1 _: H5 Y4 J' j7 {+ @4 w' ^+ y
& M- | }- @7 F- }
复制代码 . b: [+ ^7 p3 a* n# @; t. s; T
' M8 O h; ^2 F5 k. x& R$ I4 O
, s4 B0 S( g% Z1 h1 z8 {这里可以选在HAL库 LL库/ |. ]; G4 u2 }' _& i
! R% P4 w" `2 l/ l. P+ R
; [" v9 z- G& o( z- HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE);
; g1 l. C _& x5 Y" ] - ) c9 O8 o, n1 {$ F) V, U2 E. ~/ V
- HAL_Delay(1000);
复制代码
1 _/ k7 x7 D9 ?9 i3 G8 X7 B/ u/ Z- |
& `& U6 B% x. A" z0 I' e
运行如下:
8 I+ W& i! R8 s8 E" s: Z3 R3 z0 _
$ u/ \& j( P, j6 m
1 Q0 v! H' q# m/ p: v5 q
; Z. I* f7 \# e1 @! f L# r* c' K) F: E6 g1 f- v5 [# {2 W
|