STM32U0系列微控制器中的ULP(Ultra Low Power)UART接口设计用于在低功耗应用中实现串行通信。$ h. K7 k! V* I/ \& F3 P* O
硬件特性:. I0 Q6 x. [0 e" u9 w
超低功耗模式支持:ULP UART具备在低功耗模式下保持唤醒源的能力,允许在微控制器处于低功耗状态下依然能够接收数据或触发中断,从而快速唤醒并处理通信事件,有助于降低系统平均功耗。/ ^& {4 D* z7 A9 l0 c; ~
电源管理:ULP UART可能集成电源管理特性,如低电压检测、自动电源关断等,有助于在闲置时减少电流消耗。
% e) n% @3 S( T' a专用低功耗引脚:某些型号的STM32U0可能提供专门针对低功耗优化的UART引脚,这些引脚在待机或睡眠模式下具有更低的漏电流,有助于降低整体系统功耗。
; \1 O3 u$ R; t5 ]1 ]软件配置:% }9 _/ `/ k' t0 }" E' A( R" @
1 波特率设置:根据实际通信需求选择合适的波特率。ULP UART可能支持较低的波特率选项,有利于在低功耗模式下降低通信时的瞬态电流。: f9 I9 h2 {$ {: U
2 数据格式:配置数据位(通常是8位)、停止位(1或2位)、奇偶校验(无、奇校验、偶校验)等参数,确保与通信伙伴的设置一致。
) s9 b* y7 w. `$ |2 S3 中断与DMA:0 K$ }/ k, H* } d9 H
中断:启用接收/发送中断,允许微控制器在数据准备好或传输完成时被唤醒,而非持续轮询,有助于节能。确保在中断服务程序中快速 处理事件并返回低功耗状态。DMA:如果ULP UART支持,可以使用DMA(Direct Memory Access)进行数据传输,无需CPU干预,进一步降低功耗。尤其在批量数据传输时,DMA可以显著减少CPU唤醒次数。
. r& T2 \6 E/ N; Y" Y a4 低功耗模式切换:在进入低功耗模式前,确保正确配置UART的唤醒源(如空闲检测、接收数据可用等),并在唤醒后恢复正常的UART操作。: b( f( K5 ^6 \5 ]& n# ?
功耗优化技巧:
7 [; n9 ? j: Z0 X( T. `1 禁用未使用的功能:关闭不需要的UART功能(如硬件流控、校验等)以减少不必要的电流消耗。. T# `* I! r1 r9 x
& V& A& f3 p( l4 Z' W
2 节电模式:利用ULP UART的节电模式(如果支持),在数据传输间隙降低工作频率或电压,减小功耗。! y# l# _: p9 w! d
3 唤醒阈值调整:某些ULP UART允许设置唤醒阈值,调整阈值可以平衡灵敏度与功耗,避免因噪声引起的误唤醒。- {* `- u# P7 ]
4 软件定时器:使用精确的软件定时器代替连续轮询,以定期检查UART状态或处理数据,减少CPU活动时间。
" F$ L6 t; L- H6 t! z# O7 H
8 `6 O$ N4 ?: X/ d初始化:调用HAL_UART_Init()函数,设置UART参数(如波特率、数据格式等)。; ?9 E4 K/ L2 s5 K/ \7 k
中断配置:开启相关中断(如接收中断),并编写对应的中断服务程序。
5 h1 j6 C. E/ h- k0 NDMA配置(如果使用):配置DMA通道,关联到UART,并设置传输参数。
6 j5 d& D V( @1 o0 O/ M发送/接收:使用HAL_UART_Transmit()、HAL_UART_Receive()或DMA相关函数进行数据传输。) V) C' e* `" _
调试与测试:
9 I7 z2 ^$ H# ?3 t# R/ C
$ t6 {- N7 v+ b& ^
2 ^, o, {- t& ^/ y' M7 O$ _5 i. H; I
MX_LPUART1_UART_Init初始化:% L, C/ l$ X7 l1 p- a% j6 B; V
0 T2 `* W/ A/ G8 s* ?/ H
- static void MX_LPUART1_UART_Init(void)# K- j; ?1 s! k0 u9 _( c
- {
w5 O e; k& v& ?) O1 g$ N! N/ t, Z - * t3 `7 v. l0 B8 q: G
-
/ K# W7 M: H* d1 O1 r! W+ Y5 Q - hlpuart1.Instance = LPUART1;
% F* ^9 z- ~ \& z" h1 A/ `+ w; a4 a' G - hlpuart1.Init.BaudRate = 115200;% D' {& @! D( W* E5 \! l
- hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;* a4 w+ r( O0 Y' }
- hlpuart1.Init.StopBits = UART_STOPBITS_1;$ }7 Y' G0 S( s4 z+ J8 C+ \. H: m
- hlpuart1.Init.Parity = UART_PARITY_NONE;0 b* `, N) C6 L
- hlpuart1.Init.Mode = UART_MODE_TX_RX;" t$ b! m/ H$ C" x% [
- hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
! i' p. Q/ R) s. g4 a% [1 M: i - hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;" p( X, [2 I L4 j% q# v1 j
- hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
$ o' k. F9 ~- l( W: s5 F: P, i1 j3 ^ - hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;
; Y n; C: ^$ T) B# }& R6 q, T - if (HAL_UART_Init(&hlpuart1) != HAL_OK)
( p4 ? I$ h$ R8 r( `1 b* x6 H8 b - {
9 z. J- l, b/ y% Q4 h - Error_Handler();
, ]* ^" H. U& y: ^' `# n! ? F - }8 o; a, [( b+ C6 w$ Y& h0 b
- if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
% u' l- ` s& [ - {# ]- H. i, o5 p! f. M! g
- Error_Handler();# a( ^* {; Z! f! y7 T: b* Z
- }
2 ]0 } D8 H& R' |9 z9 h" G - if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
0 R% T% H5 E i9 {5 [ - {7 ^7 s3 P2 t3 C- L9 q" b
- Error_Handler();2 L% F8 G3 I5 W) t U/ Y$ L
- }; z$ ^! B: G9 J; O) Y
- if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
$ j7 ]$ J0 s7 H$ V) O$ y: R# D1 l3 c+ } - {
6 K2 @& x- |% q& w; O* I - Error_Handler();
* p) a" W0 Z6 }' u; p) U* J. k - }
7 J( ^7 }6 [6 k* v$ D -
! b0 Y; r8 M+ R9 L( g4 i8 E - }
复制代码
# P( {' M4 t2 s3 ?% G8 e' C/ i4 Q, d9 f
- static void MX_LPTIM1_Init(void)1 _9 d5 c+ W# M: [* Y6 c( c
- {
3 Y: \3 ~0 T% B% z# O, T - . L+ {/ c* \% b* r. z
- /* USER CODE BEGIN LPTIM1_Init 0 */
, X7 r: K, y9 V/ _1 i$ _ - 9 b2 A1 Y5 K o( j$ c
- /* USER CODE END LPTIM1_Init 0 */5 Z# c f' d- X; t! B1 k+ |
" t* G3 ]$ I# o# z# a- /* USER CODE BEGIN LPTIM1_Init 1 */: F5 W7 ^/ W* c+ B$ F) ]
- : s' L& _: `* h
- /* USER CODE END LPTIM1_Init 1 */
/ |: j8 }' X6 }% y - hlptim1.Instance = LPTIM1;
1 z5 d8 T: H; F, n d - hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;) ~5 j' d2 f' p
- hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
) U" _ w& C3 E* N8 m. a - hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
3 L% G, B( g6 ~ - hlptim1.Init.Period = 65535;
% {1 g! l# H# b - hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;# P0 K" e! R, M- O3 M9 ^$ T
- hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
' {: F2 c9 f: b# S: t& ` - hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;+ U( R. S ?7 {9 p8 m9 e
- hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
. {% ^4 @" {5 b' O- C2 s - hlptim1.Init.RepetitionCounter = 0;
& _& d/ q+ p9 I7 `2 s" C - if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
- d% f/ H) z# \. A0 q - {3 U4 G( g9 ~8 X" l% v' o/ y
- Error_Handler();
; g7 w& e1 P' v) |& G - }7 H4 j1 K6 m) A4 J4 ?' x( R/ W
- /* USER CODE BEGIN LPTIM1_Init 2 */
- b! j2 \1 a; [2 ] - . `# m0 y5 d2 q8 y- F
- /* USER CODE END LPTIM1_Init 2 */
+ ?) g) A; N0 i - . E" R! G4 x. I5 |: \
- }
复制代码 ! P% K: I( u/ S n
/ Z$ W* y2 m& e$ {7 l/ j
( l! b9 b3 u8 e6 ~2 |这里可以选在HAL库 LL库0 U. q0 J1 Y I2 G6 X0 V
# U/ K( x9 f# u! x$ k; C: Z
) }2 |0 z9 P8 X1 _- HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE);2 S1 f8 d6 o% T* D# f
6 k- E9 w4 Q' k2 |- HAL_Delay(1000);
复制代码 3 J2 [' b5 v1 t ^0 U5 k
1 R' {* u# N/ f8 \- @0 o* n9 J- y6 O% l, h
运行如下:
7 j ?& K! ~! l2 X
( E" ^( D/ @/ ?+ ]: g' {
$ E9 _" U: c" D) b
" S' o! _7 d4 E* v8 ]- W9 v
: P H9 N7 M4 U7 v% {
|