STM32U0系列微控制器中的ULP(Ultra Low Power)UART接口设计用于在低功耗应用中实现串行通信。
1 v: `0 K' \9 q" ?4 X5 j3 C8 v9 V硬件特性:
# B. X& Q0 ]9 G( \ 超低功耗模式支持:ULP UART具备在低功耗模式下保持唤醒源的能力,允许在微控制器处于低功耗状态下依然能够接收数据或触发中断,从而快速唤醒并处理通信事件,有助于降低系统平均功耗。
1 h6 C8 V) R6 a/ m: p电源管理:ULP UART可能集成电源管理特性,如低电压检测、自动电源关断等,有助于在闲置时减少电流消耗。0 m( Y$ B# C0 b. S4 G
专用低功耗引脚:某些型号的STM32U0可能提供专门针对低功耗优化的UART引脚,这些引脚在待机或睡眠模式下具有更低的漏电流,有助于降低整体系统功耗。
8 n* d- I, v1 ]; j8 D6 n, e软件配置:
8 N. b# X% P4 w1 波特率设置:根据实际通信需求选择合适的波特率。ULP UART可能支持较低的波特率选项,有利于在低功耗模式下降低通信时的瞬态电流。
. O9 n4 y$ p! n+ j- P2 数据格式:配置数据位(通常是8位)、停止位(1或2位)、奇偶校验(无、奇校验、偶校验)等参数,确保与通信伙伴的设置一致。
& @2 r, G3 k. H1 k9 i" E3 中断与DMA:
& ^, ^/ Q; w: k2 g2 z3 d 中断:启用接收/发送中断,允许微控制器在数据准备好或传输完成时被唤醒,而非持续轮询,有助于节能。确保在中断服务程序中快速 处理事件并返回低功耗状态。DMA:如果ULP UART支持,可以使用DMA(Direct Memory Access)进行数据传输,无需CPU干预,进一步降低功耗。尤其在批量数据传输时,DMA可以显著减少CPU唤醒次数。' g( r5 v0 p: J* L9 l
4 低功耗模式切换:在进入低功耗模式前,确保正确配置UART的唤醒源(如空闲检测、接收数据可用等),并在唤醒后恢复正常的UART操作。7 d' m4 Z( @( x" }4 m Q. J
功耗优化技巧:
% ~2 d5 f% r4 m1 禁用未使用的功能:关闭不需要的UART功能(如硬件流控、校验等)以减少不必要的电流消耗。
0 E5 t3 g% j# h; K6 \4 ?6 ]" i8 {5 \" V- s
2 节电模式:利用ULP UART的节电模式(如果支持),在数据传输间隙降低工作频率或电压,减小功耗。. }9 q: d$ e4 J4 N
3 唤醒阈值调整:某些ULP UART允许设置唤醒阈值,调整阈值可以平衡灵敏度与功耗,避免因噪声引起的误唤醒。3 I9 f; l2 S u1 i) f& ~# `/ D
4 软件定时器:使用精确的软件定时器代替连续轮询,以定期检查UART状态或处理数据,减少CPU活动时间。8 w8 H* \$ S8 f% G: ~
, ^3 y" @; a! H5 o初始化:调用HAL_UART_Init()函数,设置UART参数(如波特率、数据格式等)。 N, X: g$ V# R, N5 J# \9 s
中断配置:开启相关中断(如接收中断),并编写对应的中断服务程序。
x' V3 z( i3 d0 O; x' w* gDMA配置(如果使用):配置DMA通道,关联到UART,并设置传输参数。% u9 }# S% q# ~0 _# i+ b! [
发送/接收:使用HAL_UART_Transmit()、HAL_UART_Receive()或DMA相关函数进行数据传输。
: _0 D' b6 i2 c1 G调试与测试:( ^' Y |! B7 n1 W
& V4 S4 h" D1 ~
# J2 k* i, \$ u+ d
% j5 G5 L$ W' h6 z' q9 L MX_LPUART1_UART_Init初始化:
0 s; h) G/ r! a& o; z$ ?9 {# x& I$ q) H( @
- static void MX_LPUART1_UART_Init(void)6 O* R. W, U2 t1 L4 D, w. x
- {
- F7 _2 }0 E% {" i
: N! o$ _4 H) {# T. v2 F-
( E1 B: d6 K F- k; P6 X9 g% y: Z8 k - hlpuart1.Instance = LPUART1;" u% M- y$ C" E8 a, c
- hlpuart1.Init.BaudRate = 115200;
) Q& [% m& y% I2 t' g - hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
1 F2 m6 z0 J% C+ t0 z - hlpuart1.Init.StopBits = UART_STOPBITS_1;; q7 p9 R% d! n, R
- hlpuart1.Init.Parity = UART_PARITY_NONE;
7 u% `; C% \0 p* h/ s8 X* A% m& X8 g - hlpuart1.Init.Mode = UART_MODE_TX_RX;; g- u: p: y5 Q5 h
- hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
: R- G `' p! z% B6 l% l1 R - hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;. l) W" ?4 T8 m1 {
- hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
& d2 Y7 L* y {$ w. I. h - hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;5 ?5 K' c8 U1 Q, K( \4 n
- if (HAL_UART_Init(&hlpuart1) != HAL_OK)
9 B- s+ m% K. b. l - {
2 U# S$ D$ D) R - Error_Handler();3 k$ W5 E2 @. b6 f
- }
8 x6 g" x5 ]! _! P6 i# f) Z( ^5 m6 ~- [ - if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
# p4 [: ]6 l- ^8 ~& Y' Z - {+ @+ C, Z5 ?/ l
- Error_Handler();
' J, P" I: E6 h$ X& ~9 G - }$ X0 M. O- d* Q3 q3 N7 ~
- if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
, }, V [: L' R - {% o! `0 u3 [% b$ v
- Error_Handler();
& n: t% T$ w( I1 x( J - }/ k2 l9 G ], y; W. k
- if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
; F6 ?8 P7 T7 `4 M2 E - {0 u2 M+ T7 k4 A' Z4 n5 B2 l
- Error_Handler(); E) o* m. x# H- q1 Q
- }. ^/ ~: e+ ~: c* q$ Z9 f( k
-
6 N# m/ V" U- t0 {/ w - }
复制代码
2 b/ O& R( |" ~
8 C& ?/ h+ A2 F0 \6 h- static void MX_LPTIM1_Init(void)
$ _- a4 S5 z$ H l+ Y! f: I6 B - {
9 l/ P2 Z+ D. Z' y( O6 y
5 D' h6 ~0 h/ U% E; I- /* USER CODE BEGIN LPTIM1_Init 0 */" R" Y% h# \; s+ ]
# M8 m% r$ d% m2 J+ S9 Q- /* USER CODE END LPTIM1_Init 0 */
" ^8 ?! W- S& g% Z5 L" j/ G - - C( i. n$ M1 O/ K
- /* USER CODE BEGIN LPTIM1_Init 1 */
2 ^- | o( K6 C" T R
! D- H( s, ^( y8 K# `3 ]8 B% k5 A- /* USER CODE END LPTIM1_Init 1 */
' n* I1 S8 ~7 ~/ s; M! d7 h4 C+ d - hlptim1.Instance = LPTIM1;
) U: {! h8 H) B; R: m+ p) ` - hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
/ m$ b' G0 `" W - hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;% g; K2 ^$ [$ F/ v, y' e6 h7 t
- hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;4 a9 R3 K4 D' V Z4 o
- hlptim1.Init.Period = 65535;
" w" j C W' V' c6 X - hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
& @# { D3 Q- K0 s; q9 _0 C - hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
2 V `1 Y# o+ y - hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;% |2 M( C0 O' z2 X- l) K
- hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
8 c4 E, X- p$ i" c6 g! k( S0 _% b - hlptim1.Init.RepetitionCounter = 0;; i+ [; N# @- ~
- if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
- K8 b& j7 M5 Z7 C2 x* q - {
( H% B1 P6 x8 K4 U* ~5 J" _; S - Error_Handler();
# B" g1 C! \% d# j" ~# J) B - }* Y4 |" K: O1 s. ]
- /* USER CODE BEGIN LPTIM1_Init 2 */
6 G2 _/ g/ w7 W - 9 U% g/ L% x. l. Q9 c
- /* USER CODE END LPTIM1_Init 2 */
) v8 r: S' q0 w. _1 {
- k- w& y/ m6 P3 r. Z7 _" j- }
复制代码 2 L5 c. [7 S" D" T k! @0 v1 P5 ^
: s. ~5 f7 w8 m2 D) s5 _
8 R w, u2 Q' P7 X这里可以选在HAL库 LL库: N6 O+ }1 |" v0 ]( R0 Y
$ M- A2 d" F" r. `& D& }; c) S
/ A# j9 J- w- P- HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE);
, Z0 ?! C8 s8 Y* i9 N, u/ e7 W - " c2 E5 O$ i( J9 ` o% ], G
- HAL_Delay(1000);
复制代码 " n7 l- C, h b! z
, P1 }7 K3 x e Z8 u9 z( ~
5 C/ @0 e! [ G+ w运行如下:- Q3 P8 c7 g( _! Y, k( h/ p
5 ~0 \: h" P# |/ Q
! v1 m- z- v: u( l3 D; i0 U# g) A3 E& _8 k
+ C6 W- S/ o+ \9 w1 B- E& Y
|