STM32U0系列微控制器中的ULP(Ultra Low Power)UART接口设计用于在低功耗应用中实现串行通信。
+ ]" q. B/ w3 \- y4 R5 ^9 [6 |硬件特性:1 [& x- @( X' s1 w, z' c: r
超低功耗模式支持:ULP UART具备在低功耗模式下保持唤醒源的能力,允许在微控制器处于低功耗状态下依然能够接收数据或触发中断,从而快速唤醒并处理通信事件,有助于降低系统平均功耗。
5 J' c/ N* q: y1 A l; q2 h( J电源管理:ULP UART可能集成电源管理特性,如低电压检测、自动电源关断等,有助于在闲置时减少电流消耗。: [0 J, z& {" f6 u. |1 t1 M
专用低功耗引脚:某些型号的STM32U0可能提供专门针对低功耗优化的UART引脚,这些引脚在待机或睡眠模式下具有更低的漏电流,有助于降低整体系统功耗。; a$ B9 V7 L) y, X5 t0 b. c
软件配置:
/ r- K1 ?8 |7 x+ T/ O6 j1 波特率设置:根据实际通信需求选择合适的波特率。ULP UART可能支持较低的波特率选项,有利于在低功耗模式下降低通信时的瞬态电流。5 d8 E6 [' |" b- l
2 数据格式:配置数据位(通常是8位)、停止位(1或2位)、奇偶校验(无、奇校验、偶校验)等参数,确保与通信伙伴的设置一致。& q0 {* D. U: e9 a1 U/ T
3 中断与DMA:9 Z* _- n0 {; F/ H
中断:启用接收/发送中断,允许微控制器在数据准备好或传输完成时被唤醒,而非持续轮询,有助于节能。确保在中断服务程序中快速 处理事件并返回低功耗状态。DMA:如果ULP UART支持,可以使用DMA(Direct Memory Access)进行数据传输,无需CPU干预,进一步降低功耗。尤其在批量数据传输时,DMA可以显著减少CPU唤醒次数。
/ r2 L9 H S, y: }) M4 x9 d# C+ R- R4 低功耗模式切换:在进入低功耗模式前,确保正确配置UART的唤醒源(如空闲检测、接收数据可用等),并在唤醒后恢复正常的UART操作。
! ? S* A+ G$ v" v. Z* x4 e% `/ w' J功耗优化技巧:7 i% ^% d. P. V5 d% Y# i; x. D
1 禁用未使用的功能:关闭不需要的UART功能(如硬件流控、校验等)以减少不必要的电流消耗。
; A: S0 _ D4 E& U/ S' v1 ]4 A9 k2 O9 n
2 节电模式:利用ULP UART的节电模式(如果支持),在数据传输间隙降低工作频率或电压,减小功耗。
/ g: m5 M6 h3 f+ |8 {1 q8 N; `, i3 唤醒阈值调整:某些ULP UART允许设置唤醒阈值,调整阈值可以平衡灵敏度与功耗,避免因噪声引起的误唤醒。
3 H. m1 m5 S4 j$ h4 软件定时器:使用精确的软件定时器代替连续轮询,以定期检查UART状态或处理数据,减少CPU活动时间。) j3 H& ~+ `0 H) ^$ m5 C
" x" {% t' o: @- b+ T1 k初始化:调用HAL_UART_Init()函数,设置UART参数(如波特率、数据格式等)。
5 i! D+ @, c b) X7 [中断配置:开启相关中断(如接收中断),并编写对应的中断服务程序。
" E4 B1 T3 K7 A! W" d" Y" z5 c1 ]5 yDMA配置(如果使用):配置DMA通道,关联到UART,并设置传输参数。
* o$ e$ p6 m( d2 e" X/ f" s发送/接收:使用HAL_UART_Transmit()、HAL_UART_Receive()或DMA相关函数进行数据传输。
; `- M9 f0 m2 W4 @: s调试与测试:
& M. e. b; m0 v1 I" x8 O
+ w) s$ x/ f# ?. {3 c, k1 u A/ Y( G0 A' q
7 F/ a9 a) O Y6 J* `& p MX_LPUART1_UART_Init初始化:
; ?9 j0 }) r6 Y- V! Q' Z' x# D
2 f0 E' t- U4 U$ P5 M2 F- static void MX_LPUART1_UART_Init(void)) P/ q3 G8 B* W$ o& b
- {8 D# C0 A |2 h3 y" M) W
- + u/ @6 U* r! _8 M
- ' f" Z1 q7 q: p4 \& \1 U
- hlpuart1.Instance = LPUART1;
& v: S+ @& \, A5 X) O0 L( Q - hlpuart1.Init.BaudRate = 115200;
$ h8 ~4 ~5 |4 t3 I - hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;4 ^5 ], q2 j% n3 c
- hlpuart1.Init.StopBits = UART_STOPBITS_1;
) J' W4 B: P! _ - hlpuart1.Init.Parity = UART_PARITY_NONE;& V! `! p( X& r: L1 w5 M& L- a6 F: [, _
- hlpuart1.Init.Mode = UART_MODE_TX_RX;
: \$ ]1 C2 [# F - hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
6 n# d" c7 }8 _* u6 q9 i+ M5 d8 n - hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;$ T g2 W# u7 V% a& k9 i
- hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
% r+ ~( T. M t* b. e" N1 p1 T - hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;6 V) ~* s, J- j# \" a+ h
- if (HAL_UART_Init(&hlpuart1) != HAL_OK)
" I* W' @8 D7 t( M X - {: ]+ z, j2 D& z4 _ m
- Error_Handler();
3 T' P# E* C( ~! c# o6 x - }
4 w( r9 y' Z, f/ [; v: k& b - if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
) o; v; d6 o8 A9 n, V7 g - {
+ R R r& W! I {/ ~& `* {5 S5 E - Error_Handler();# g/ C$ D+ d: L4 c" I% K
- }) Z7 e v* R& d0 E5 i
- if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
# |( N- _2 }6 A+ J- P) U - {& i6 X' M. b# l0 A+ d+ ~* I
- Error_Handler();
/ D8 ]- h) d! f W. ? - }4 D* o6 ^* A8 j2 B# }! P8 X
- if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)8 ]" E* D) R5 D: D
- {
5 d) G' j5 H9 b- K - Error_Handler();
6 n) F l% C5 }! I" h4 J+ l* Z' y& Q - }
& Z, W( g+ u# I, s3 @; `+ H -
% S' L# o9 ~. r4 S. N# k$ } - }
复制代码
3 w. n' L$ k; U l) H
* x# b1 p& Y5 u6 c3 w; j# j* h- o- static void MX_LPTIM1_Init(void)) r. |5 f; o8 I& j, l8 I
- {
" F' v2 g p- a# |
* O# V; D( q5 k8 x5 F4 N- /* USER CODE BEGIN LPTIM1_Init 0 */3 i( N; X- Z3 t+ f- w3 W
- 0 P4 a8 n3 y+ w5 z* ] F
- /* USER CODE END LPTIM1_Init 0 */( I; }3 {" u4 s
$ O# \& H& i/ T) L( H: }- /* USER CODE BEGIN LPTIM1_Init 1 */% d9 {+ O8 A! H* A) Q+ p
- 6 Z5 X F8 t' r/ E
- /* USER CODE END LPTIM1_Init 1 */5 d2 A" \6 e4 g1 s2 h* J7 y7 d3 ~- Y
- hlptim1.Instance = LPTIM1;8 _, V# \3 K1 b M6 }: I
- hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
. e* s0 @* g0 X% g u) o - hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
8 m$ F$ o) v* s5 |. \ - hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
1 H5 O. c: K' s" ? - hlptim1.Init.Period = 65535;& j5 Z5 D& h! e7 M3 F- E3 b% a
- hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;3 Z8 C' r" \* M1 M
- hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
- Z- [! ?* G/ @5 T; N. G - hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;2 n+ H2 z6 j9 x, G8 ?1 L$ d
- hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
4 g& Q0 z4 H& q6 J9 L - hlptim1.Init.RepetitionCounter = 0;0 v B' h( y* ]8 U+ g# w
- if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)- A0 H( z _6 z3 c4 Y0 \$ v2 t3 p4 w
- {
) y& `* h2 w9 g# r - Error_Handler();
B& w7 P8 m' `1 [- k3 f) i: A - }6 A; z, z9 N* l
- /* USER CODE BEGIN LPTIM1_Init 2 */
0 z1 b7 Z( G# a# C1 X5 q
- V4 d! }, a8 A* B# |6 L5 n- /* USER CODE END LPTIM1_Init 2 */% D0 ~& k0 y' d# p
$ d5 g) m' f5 Q: M' v/ e- }
复制代码 $ s1 S. R! G( l! B. @$ C4 q: |
$ p* |. L; A( e" D1 j! ^4 T% L( _ O0 p( [3 Z5 k5 d# j; X* t( ]
这里可以选在HAL库 LL库
& W- T$ n/ u- J& r# v3 x
- i/ f$ o! t) l5 w! Z
% A. ^$ Z2 Z4 T- HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE);
, F4 z/ _0 T4 v, t" | G0 z' ^2 O - ! O' r4 D; \- P; j
- HAL_Delay(1000);
复制代码
* K$ l1 u% E9 I: L, ?7 m. ?( B
; a+ N6 D [, g4 d( X5 ], i+ \4 f# `; S& c, S% N% Q5 c- B, j
运行如下:
- Y/ I# L: w% z" H: M& z1 M
6 \0 n$ c9 N' w
( s# C: ^4 `; B9 w8 N, J w' f
( c" |) ^% B9 S' Z' u( F( b
. b% x7 N9 }: T/ H |