STM32U0系列微控制器中的ULP(Ultra Low Power)UART接口设计用于在低功耗应用中实现串行通信。
) k, A( E" z* |2 B2 c2 Z- x" N硬件特性:
. J, n; @% `& _" l 超低功耗模式支持:ULP UART具备在低功耗模式下保持唤醒源的能力,允许在微控制器处于低功耗状态下依然能够接收数据或触发中断,从而快速唤醒并处理通信事件,有助于降低系统平均功耗。
) Z) f/ ?9 q1 L% d3 D0 T9 t电源管理:ULP UART可能集成电源管理特性,如低电压检测、自动电源关断等,有助于在闲置时减少电流消耗。, R- A# F0 w% g m# Q
专用低功耗引脚:某些型号的STM32U0可能提供专门针对低功耗优化的UART引脚,这些引脚在待机或睡眠模式下具有更低的漏电流,有助于降低整体系统功耗。
3 O4 ]4 _/ _2 v软件配置:7 ?" o+ f9 o) s+ ?0 J/ `2 [
1 波特率设置:根据实际通信需求选择合适的波特率。ULP UART可能支持较低的波特率选项,有利于在低功耗模式下降低通信时的瞬态电流。
0 i9 `4 X6 Y. m, V% g% i0 c2 数据格式:配置数据位(通常是8位)、停止位(1或2位)、奇偶校验(无、奇校验、偶校验)等参数,确保与通信伙伴的设置一致。
0 J: C) v0 V& S* _3 S [& @3 中断与DMA:
+ W: Q" B/ |2 f1 j; T8 v 中断:启用接收/发送中断,允许微控制器在数据准备好或传输完成时被唤醒,而非持续轮询,有助于节能。确保在中断服务程序中快速 处理事件并返回低功耗状态。DMA:如果ULP UART支持,可以使用DMA(Direct Memory Access)进行数据传输,无需CPU干预,进一步降低功耗。尤其在批量数据传输时,DMA可以显著减少CPU唤醒次数。
/ E5 {/ b$ J* `6 M3 e4 低功耗模式切换:在进入低功耗模式前,确保正确配置UART的唤醒源(如空闲检测、接收数据可用等),并在唤醒后恢复正常的UART操作。: W+ ~' n+ r: P4 M1 U" S
功耗优化技巧:
+ ?) Q, N3 e% k2 k3 c! r- z& j) I0 M1 禁用未使用的功能:关闭不需要的UART功能(如硬件流控、校验等)以减少不必要的电流消耗。- x- Y7 z* C# c
7 ^; ~! B8 f; `* g2 节电模式:利用ULP UART的节电模式(如果支持),在数据传输间隙降低工作频率或电压,减小功耗。0 u* B% C4 V0 I: n( M7 p
3 唤醒阈值调整:某些ULP UART允许设置唤醒阈值,调整阈值可以平衡灵敏度与功耗,避免因噪声引起的误唤醒。8 B: E0 @7 ^5 S5 E
4 软件定时器:使用精确的软件定时器代替连续轮询,以定期检查UART状态或处理数据,减少CPU活动时间。
( J& X4 U3 V" U% q3 x/ K: }5 N9 p
1 d2 N5 k* b; a/ ~/ Y初始化:调用HAL_UART_Init()函数,设置UART参数(如波特率、数据格式等)。( X) t1 v2 [+ d9 ^. N: P( Q* W" Z
中断配置:开启相关中断(如接收中断),并编写对应的中断服务程序。
8 S0 O- Z8 U. s+ o+ m0 S# kDMA配置(如果使用):配置DMA通道,关联到UART,并设置传输参数。
) _1 }) S; [: B4 S/ T发送/接收:使用HAL_UART_Transmit()、HAL_UART_Receive()或DMA相关函数进行数据传输。
/ G. e8 U% u: f: }调试与测试:/ W3 u& ]! r1 Y/ C) z7 C6 {% P
9 M I$ o6 w$ k5 _/ i
; {+ F% c) a/ g* t2 n5 @
( Z- }( c5 t& `6 Q" L" I% G
MX_LPUART1_UART_Init初始化:
/ b) K9 a$ `4 P5 N/ Z
; q, n& P7 ?" W" c5 E* q& A- static void MX_LPUART1_UART_Init(void)8 D' N/ }" L# w5 d
- {' N7 N& v, X$ K: w. e
- % w( k0 o# ^/ L, ?
-
' k) R! N0 m0 H; V( K1 p; D - hlpuart1.Instance = LPUART1;
1 @7 H% P$ ^3 X F! T - hlpuart1.Init.BaudRate = 115200;
4 s( M5 R6 q+ q& _2 [$ F - hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;0 @, @& ^2 I0 z" r
- hlpuart1.Init.StopBits = UART_STOPBITS_1;
# W' y1 u) l7 T6 [; V - hlpuart1.Init.Parity = UART_PARITY_NONE;4 ]$ h+ t2 I$ @# I& {; x7 n+ _
- hlpuart1.Init.Mode = UART_MODE_TX_RX;
, X/ Q: I+ e9 a- b& V( q - hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
# ~8 X6 N/ t+ u% s: [+ h: m6 w - hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;- B$ a* S7 H% t
- hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
% k$ _4 n: f' q/ T2 b0 R. W' d - hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;
, ~* T. D3 f P( p; \7 T6 k - if (HAL_UART_Init(&hlpuart1) != HAL_OK)
1 \. j" u# P" U: o2 S - {
3 g7 e1 `1 e. A4 m% C - Error_Handler();4 g, x. [/ T" U+ D
- }
: {% p1 W) U, b5 U: }; B# @ - if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
& Z1 C$ P' R" P( W: v) B5 [ - {
0 h0 J+ x) J3 w3 f - Error_Handler();8 A4 N: Z* d/ m' s
- }
" ]/ D- j. F! v0 v - if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
- p- i& l! h9 `% w - {* l, R, m# G, ?' m3 ~- y' U% r- `
- Error_Handler();, z$ g# | i0 ^+ u) v+ _
- }
: N5 t/ Z9 Z0 j5 l9 C - if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK): w5 F: U0 ?4 F4 H
- {' V9 G, p% w( x9 @2 f% }& {% R2 v
- Error_Handler();* B$ e9 j7 D* W: o0 {: j9 X
- }
6 X, l. i5 R& R g1 ]; O - 8 N( x( |5 Y/ A; u: `( a
- }
复制代码 ; c) b8 p: S# d
! V# l4 G- L# Y! A* F) ]
- static void MX_LPTIM1_Init(void)
* i% i ]5 g9 ^; G' f! n - {
& X8 }5 M5 t1 v$ v5 f
, p( S/ Z/ _6 B5 \1 t- /* USER CODE BEGIN LPTIM1_Init 0 */# B* u3 P7 f9 Y
- " g, v2 ? m2 t, f5 T
- /* USER CODE END LPTIM1_Init 0 */+ S* g) D* d' k7 |8 Q
1 Q0 E) H6 \# W& J6 n1 w- /* USER CODE BEGIN LPTIM1_Init 1 */
! {+ t' Q9 u8 c - 9 j' R7 i4 j: T" w5 n) l8 j; ^+ d
- /* USER CODE END LPTIM1_Init 1 */
- @* s( |8 N' j" l1 x5 y - hlptim1.Instance = LPTIM1;& C6 h" l8 P( n/ B
- hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
/ G8 V$ C i) w" A- ? - hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;; l# n1 `% w, M( A' a, ~1 @8 i
- hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
9 X( E2 h/ n0 F& ^% G - hlptim1.Init.Period = 65535;% G0 S8 a% ~9 ?4 b6 O. `
- hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
/ i& Y0 k2 f, a3 ~ Q% V - hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
. j+ L# }, p4 u* ]9 n2 Q) U( }4 D* y" t - hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;6 \; z' H1 R% e* _" b) ?' r: Z
- hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
' b+ \% s- V, G" O/ o - hlptim1.Init.RepetitionCounter = 0;
. n: {7 L8 j0 T - if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
$ a) s0 x& p Y1 @+ w - {4 n- a. p& e5 q& M. |$ X8 b% U
- Error_Handler();
& K1 Z- ?1 i1 L$ i8 k - }
0 l9 D2 J; t% Z, u# ^1 x; W& e0 W+ N" ? - /* USER CODE BEGIN LPTIM1_Init 2 */
+ n7 K- z9 y1 s6 o - ) y0 J* Y1 S: @
- /* USER CODE END LPTIM1_Init 2 */% g( c! Q/ P5 Z5 x% G
" d+ V) C* \9 {3 R- }
复制代码
/ c3 m& q7 u: e* E8 _; ]3 X3 `7 Z, ~0 F5 j+ j9 w
9 [( p* k) Y+ P& D! U0 O0 @6 y+ S
这里可以选在HAL库 LL库. X6 a. U7 m! M8 U* e
; ]) n! W$ M* O9 E4 G) Z
6 l5 l6 _" T' P% P+ b- HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE);
$ q+ T: D/ y! j6 ]9 ?( S1 _, P5 y - # S5 x1 c# R) f( Y1 ^ v( j
- HAL_Delay(1000);
复制代码 ) ^2 o2 c; x! _+ K
! W g) q/ f( ?/ }7 O! {' k$ W+ ~
' a8 q2 v+ S4 g" D$ ?+ g( H
运行如下:. L7 n; Y$ d1 x3 M/ u
0 P, T8 m. P* W8 q0 T% X& @8 g* n Q. G! Z. \- _, T
( ]- R6 A0 j5 T$ v5 M" E
$ m I+ g" {! k& {# B& l" J |