STM32U0系列微控制器中的ULP(Ultra Low Power)UART接口设计用于在低功耗应用中实现串行通信。
: G/ X5 l% C6 V" {+ c& v硬件特性:! t6 A% w7 P9 N9 x8 _7 y' @1 x# |
超低功耗模式支持:ULP UART具备在低功耗模式下保持唤醒源的能力,允许在微控制器处于低功耗状态下依然能够接收数据或触发中断,从而快速唤醒并处理通信事件,有助于降低系统平均功耗。
& N7 y# L2 Q! U t E: D e& w电源管理:ULP UART可能集成电源管理特性,如低电压检测、自动电源关断等,有助于在闲置时减少电流消耗。 t' ^8 R1 J" }3 D) q
专用低功耗引脚:某些型号的STM32U0可能提供专门针对低功耗优化的UART引脚,这些引脚在待机或睡眠模式下具有更低的漏电流,有助于降低整体系统功耗。
4 L& ]% e$ H2 m* P% q软件配置:
/ n! T: q# Z& M6 [+ x" U$ P' _1 V1 波特率设置:根据实际通信需求选择合适的波特率。ULP UART可能支持较低的波特率选项,有利于在低功耗模式下降低通信时的瞬态电流。
8 e% q( p2 g \; l8 u' o" W2 数据格式:配置数据位(通常是8位)、停止位(1或2位)、奇偶校验(无、奇校验、偶校验)等参数,确保与通信伙伴的设置一致。! i( W% B% N- U( ?1 o
3 中断与DMA:2 \1 O* }/ h" ?# Q
中断:启用接收/发送中断,允许微控制器在数据准备好或传输完成时被唤醒,而非持续轮询,有助于节能。确保在中断服务程序中快速 处理事件并返回低功耗状态。DMA:如果ULP UART支持,可以使用DMA(Direct Memory Access)进行数据传输,无需CPU干预,进一步降低功耗。尤其在批量数据传输时,DMA可以显著减少CPU唤醒次数。! ]7 M! A$ Z& ~9 n2 W6 w
4 低功耗模式切换:在进入低功耗模式前,确保正确配置UART的唤醒源(如空闲检测、接收数据可用等),并在唤醒后恢复正常的UART操作。
6 _* N \+ V" M8 ~$ D功耗优化技巧:! [! `2 z6 x3 ?7 e0 y" p
1 禁用未使用的功能:关闭不需要的UART功能(如硬件流控、校验等)以减少不必要的电流消耗。
: o) ?) f3 e% X% }( E( C- m( f8 r1 o
" `+ L* ^+ [! Q3 G5 t9 ]2 节电模式:利用ULP UART的节电模式(如果支持),在数据传输间隙降低工作频率或电压,减小功耗。
$ Y6 T6 O7 z8 G( o. _+ _3 唤醒阈值调整:某些ULP UART允许设置唤醒阈值,调整阈值可以平衡灵敏度与功耗,避免因噪声引起的误唤醒。
! Y7 }6 l# U- E5 d/ d9 A" u4 软件定时器:使用精确的软件定时器代替连续轮询,以定期检查UART状态或处理数据,减少CPU活动时间。, @1 V3 L$ P* v8 E. P
1 \3 N( T; s" O; r+ r/ c初始化:调用HAL_UART_Init()函数,设置UART参数(如波特率、数据格式等)。/ q$ X/ g- y' U @9 y
中断配置:开启相关中断(如接收中断),并编写对应的中断服务程序。
/ y: }5 g. S; d4 q- DDMA配置(如果使用):配置DMA通道,关联到UART,并设置传输参数。
( j! _/ o6 u! Q9 w$ }# Y3 K发送/接收:使用HAL_UART_Transmit()、HAL_UART_Receive()或DMA相关函数进行数据传输。; U/ d: T& {; J, s& ^
调试与测试:
8 x( d/ h+ L% p
a2 L: y+ L% _4 I9 i1 F( j2 j, m
. s$ b" H0 P$ v
/ \/ g/ l& @) f
MX_LPUART1_UART_Init初始化:5 X- s0 J% _% A. x% ]9 i3 h
4 ~$ [0 {7 `% F: T: _
- static void MX_LPUART1_UART_Init(void)5 s. p+ {- z- B& k( O: b4 L
- {- ~+ U' t3 W3 {/ v. y
0 M! X! l. S9 B: o-
% Z/ Y7 P2 X( E6 ` - hlpuart1.Instance = LPUART1;2 S. k$ h8 G2 L" l# Q( J' Y4 u1 b
- hlpuart1.Init.BaudRate = 115200;& A5 B, [/ m* Q
- hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
7 Q( S) n( M Y/ | L( ^8 u' Y - hlpuart1.Init.StopBits = UART_STOPBITS_1;; T( d$ a5 S' E Y
- hlpuart1.Init.Parity = UART_PARITY_NONE;3 U# u3 S) g, K0 ~! T
- hlpuart1.Init.Mode = UART_MODE_TX_RX;; x0 v1 {( h1 u4 L3 n) |6 K& _1 s
- hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;, w8 Z! B: g& y( B7 C
- hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;$ W" y3 k: D" g/ V- L
- hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;1 t6 {. ~0 W& r/ G- A( ]
- hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;" J: O, X2 V: J/ r" Y. R
- if (HAL_UART_Init(&hlpuart1) != HAL_OK). a8 i7 P4 N- I' x0 l* B7 }
- {& v0 J/ f. `7 q1 W7 A5 O7 F: d
- Error_Handler();% x3 x; U7 G' @$ h# }
- }& X. _+ C$ _" x: c
- if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)5 @( B7 J. Z1 |
- {9 h9 @& m# m/ M& Q4 z! r
- Error_Handler();
* D/ V0 w& \4 G/ J$ T8 ~; W - }! |7 j/ o$ f/ H' f0 a8 N. ^( m
- if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
$ }3 g! K, ~3 U4 Z. H- ^3 `! F - {
( b1 I- z" M3 M - Error_Handler();
/ h( Y$ F# c# `+ k. E' B - }( _, O$ T7 i/ O; S8 E4 H
- if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
/ L+ h) M7 [% R. X* s4 { h2 M - {
f, V* `9 k8 e! l0 m - Error_Handler();
1 U0 k. @8 G% I9 g - }$ b' h4 [' ]6 o! Y4 Y
- 6 }( T) ~% p* ]" ?0 j
- }
复制代码 w( Q+ y' ?! l B8 I
( H& `$ m( j! Y* R8 V, D) s
- static void MX_LPTIM1_Init(void)( p5 q# H3 U: D$ k
- {
, W" \4 d; r# |% q" {. A/ i
' I/ p7 @& g7 a$ E" A+ w" {9 D- /* USER CODE BEGIN LPTIM1_Init 0 */. r4 _' I: o/ D: N" T. c1 P' D
+ c0 R% c6 n/ k) B) [8 m) E- /* USER CODE END LPTIM1_Init 0 */
" G) W) D8 L$ n$ X3 i - . X) Q2 \( k5 i2 x& @
- /* USER CODE BEGIN LPTIM1_Init 1 */9 ~# o+ X3 @& E: U h
3 L3 e( x8 N4 I! a- /* USER CODE END LPTIM1_Init 1 */
" J& Z3 g; S. [ - hlptim1.Instance = LPTIM1;! A- n7 V1 n7 z4 w. e1 k/ }: K
- hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
7 x& m; E2 T& z+ I& P5 z - hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;8 j7 m# q( ^. V7 U
- hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
' j9 J/ i3 K( X2 ]. g' R" |! F# E - hlptim1.Init.Period = 65535;
: s/ F" U7 s& y- p - hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;/ E! b8 b2 R: g0 Q5 _
- hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;* \0 G9 ~- Q) h
- hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;, B9 E0 B% o( s9 i6 }6 h3 ^
- hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;3 {9 U( m) p$ H. T6 ]% f
- hlptim1.Init.RepetitionCounter = 0;; W6 A+ m% T/ f6 l
- if (HAL_LPTIM_Init(&hlptim1) != HAL_OK) K+ \( i6 `* a8 d9 O
- {% Z4 _8 u2 X% o
- Error_Handler();
% e1 B, N) N$ s, @/ j8 F9 @( K1 q/ a A - }, ~' q6 d, q. B5 h1 r
- /* USER CODE BEGIN LPTIM1_Init 2 */% i4 ]4 G" A# B2 g
- 2 e9 O9 ^. x7 k$ B
- /* USER CODE END LPTIM1_Init 2 */
, t$ [! G2 h9 i6 K- t
; E' f6 ~4 y; U# B" v# F4 j2 i- }
复制代码
8 A2 |7 |" d$ z6 d* v' I
' p4 e5 _3 d8 m r0 q5 h+ U' B' N( t" W$ l, u& H
这里可以选在HAL库 LL库0 L9 i; }8 D6 b5 @! n7 }: u
* I( K' \0 D( A) ~1 u9 t2 ?. X
2 H# j# C9 d. w) X& V- HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE);: {; J6 `+ K( [/ x; ?3 W
- 8 J5 U0 t6 _8 I( M* ]( f( X
- HAL_Delay(1000);
复制代码
3 D' ~) A9 K" l" l) Z! h% ^2 d* y
/ i e) ]8 w C0 `: F, |) ]* L \, r# g8 a9 p. A7 T
运行如下:
3 K! b) I2 t' e6 Z" N( ?
5 {# h9 u6 E3 l/ K% f& f1 `# z; N
1 c: P# W6 y) `4 b, q# X2 Z2 K' r7 I$ `# ? d0 O* I
9 z6 m- g0 I0 U |