STM32U0系列微控制器中的ULP(Ultra Low Power)UART接口设计用于在低功耗应用中实现串行通信。2 p3 I4 `# R3 O6 w" l2 T9 ~
硬件特性:
, P2 ^( y$ z$ o# @ 超低功耗模式支持:ULP UART具备在低功耗模式下保持唤醒源的能力,允许在微控制器处于低功耗状态下依然能够接收数据或触发中断,从而快速唤醒并处理通信事件,有助于降低系统平均功耗。
/ T" d* ^/ V. L' w电源管理:ULP UART可能集成电源管理特性,如低电压检测、自动电源关断等,有助于在闲置时减少电流消耗。+ _* H; L7 n' L5 b5 }8 K
专用低功耗引脚:某些型号的STM32U0可能提供专门针对低功耗优化的UART引脚,这些引脚在待机或睡眠模式下具有更低的漏电流,有助于降低整体系统功耗。
6 |& C+ ?7 d3 k# F7 {) d软件配置:
4 J( E1 r/ c% R5 o6 d$ P1 波特率设置:根据实际通信需求选择合适的波特率。ULP UART可能支持较低的波特率选项,有利于在低功耗模式下降低通信时的瞬态电流。: Y+ V2 S, x' v
2 数据格式:配置数据位(通常是8位)、停止位(1或2位)、奇偶校验(无、奇校验、偶校验)等参数,确保与通信伙伴的设置一致。; Q, a& P) k# ]$ J' k
3 中断与DMA:
7 y8 \2 h" g, d7 W/ O' i 中断:启用接收/发送中断,允许微控制器在数据准备好或传输完成时被唤醒,而非持续轮询,有助于节能。确保在中断服务程序中快速 处理事件并返回低功耗状态。DMA:如果ULP UART支持,可以使用DMA(Direct Memory Access)进行数据传输,无需CPU干预,进一步降低功耗。尤其在批量数据传输时,DMA可以显著减少CPU唤醒次数。3 w: y) m" j2 y6 N# o
4 低功耗模式切换:在进入低功耗模式前,确保正确配置UART的唤醒源(如空闲检测、接收数据可用等),并在唤醒后恢复正常的UART操作。
- B! N) I) X4 h/ E9 c( Y功耗优化技巧:; B& ?9 s; N3 W$ _" a
1 禁用未使用的功能:关闭不需要的UART功能(如硬件流控、校验等)以减少不必要的电流消耗。
u$ j- S$ F, ?- p) _% `" [5 [4 Q% i$ |
2 节电模式:利用ULP UART的节电模式(如果支持),在数据传输间隙降低工作频率或电压,减小功耗。
g& Q+ g( ~) Z. f3 X3 唤醒阈值调整:某些ULP UART允许设置唤醒阈值,调整阈值可以平衡灵敏度与功耗,避免因噪声引起的误唤醒。5 h& E! H+ L1 ?& v2 c3 s& O
4 软件定时器:使用精确的软件定时器代替连续轮询,以定期检查UART状态或处理数据,减少CPU活动时间。
; [, p2 ]: _5 r, u d% M
/ @& w) M4 [! H9 }初始化:调用HAL_UART_Init()函数,设置UART参数(如波特率、数据格式等)。% ~7 q/ U' ]5 {$ J
中断配置:开启相关中断(如接收中断),并编写对应的中断服务程序。& S- o9 I5 U( e! I7 Y
DMA配置(如果使用):配置DMA通道,关联到UART,并设置传输参数。1 B2 p% f: n+ ?: O
发送/接收:使用HAL_UART_Transmit()、HAL_UART_Receive()或DMA相关函数进行数据传输。: S! I/ [1 v1 U3 Z1 x
调试与测试:
0 F& ^/ V0 d" ?* |& N- ]- ]* Q
. A! O* B } C% b
/ u* }; }( Q! `9 K
& t! }' V7 y& C" E8 L MX_LPUART1_UART_Init初始化:
* v3 u8 y) m8 O4 s" V. a* _
a9 C$ }# i, A! Y- static void MX_LPUART1_UART_Init(void). T2 Z7 M: _9 \1 b
- {$ c" f/ R1 i4 g' L
4 ~, V' z+ k2 Z) u! D. Y) u- 6 q& |7 j( y4 ^# E! z7 k
- hlpuart1.Instance = LPUART1;, {# K0 \8 {3 N9 y/ s- j$ b1 f1 U
- hlpuart1.Init.BaudRate = 115200;
3 V) n$ r' d$ ?0 E - hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;+ I; n4 k2 o( o7 k
- hlpuart1.Init.StopBits = UART_STOPBITS_1;/ [& m. }# U" L* E e7 q
- hlpuart1.Init.Parity = UART_PARITY_NONE;; i W9 o% t e* g0 w/ b! `6 @
- hlpuart1.Init.Mode = UART_MODE_TX_RX;
: ]* |" o( H3 s3 G7 \2 [ - hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
( `/ _; {( ]4 L$ A. [ - hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;3 e/ u4 H/ v# n( u: g' P
- hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; R; R$ @: W6 k: u" Q( s! H
- hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;
; o5 @! F C3 z/ H9 M; H- W - if (HAL_UART_Init(&hlpuart1) != HAL_OK). t9 Y9 ]6 b; d* ^
- {
+ Y! u' P/ p5 S' |* a, y - Error_Handler();
! r. L! C3 _+ T# M' a! s# M - }* Z+ K: r% r# c; }2 H# L; e! V/ A9 r
- if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
; ?8 x# M# c( Z% i: H* ` - {
. @3 \* G# d/ L3 Y- [0 T3 X - Error_Handler();
9 ]# y$ H0 ~3 A. T - }+ H) l6 H% S4 s E
- if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
1 b" N9 E) ^9 o$ c - {( {8 X" c5 g, l% Y, F/ e) K% F
- Error_Handler();8 ?" Y; f8 z! k1 U
- }
$ A3 U: ?: `8 f% [$ x7 c9 _% }/ t - if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK), {% @+ Z# f2 [1 ?
- {; [/ i1 G) P m7 e# L1 H
- Error_Handler();
: k9 p+ C, T$ [# v - }
/ Y) R- }7 @: ~/ q - 8 V4 c7 I, t" H g# k* p V
- }
复制代码
% D% _; `+ H) [9 t# B8 u
8 j3 |1 M; s' V! b# i0 ]! Q- static void MX_LPTIM1_Init(void)+ p1 M& J% F- c$ |( `$ d" H
- {* C( H! F) v/ X0 M0 O
8 J8 F6 H4 F3 l9 V9 R1 \# g- /* USER CODE BEGIN LPTIM1_Init 0 */
& G7 R% U; o/ N
4 n% p# y0 K- _) U/ n! O0 W- /* USER CODE END LPTIM1_Init 0 */
1 D( U: `0 X S# Y
4 I6 @% G3 a& {- e3 A$ ]- /* USER CODE BEGIN LPTIM1_Init 1 */" x$ C8 {& X0 Z
- 3 l: z) n7 d. Q
- /* USER CODE END LPTIM1_Init 1 */
6 {! H; D: k9 f4 y) ~5 x7 I8 H - hlptim1.Instance = LPTIM1;
9 y4 T7 d( Q; L. L& \/ D - hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;0 {& D2 v9 w7 C8 m% L
- hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;4 E7 H+ w5 g% A% P5 h
- hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
8 }$ Q9 g$ @: E) N7 L - hlptim1.Init.Period = 65535;) W+ t: }2 }5 t6 ^
- hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
; ^2 G4 s ` p - hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;* n& \0 G6 h6 s: z- b
- hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;! ?4 w( S3 |5 x& c* x
- hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;$ R6 i, \; R7 A6 k* t( a' }: b* }% \
- hlptim1.Init.RepetitionCounter = 0;6 A8 r0 `# g) h& r0 C: x: p
- if (HAL_LPTIM_Init(&hlptim1) != HAL_OK): I T3 _( x* ~/ R$ X
- {" Z+ `1 f' h: g
- Error_Handler();8 b; N$ {- j! D8 U
- }* `! e- q- S c* }! i" `: @
- /* USER CODE BEGIN LPTIM1_Init 2 */
: Y J# ]4 n; ~6 }9 m - $ V% _. `; O( Q |
- /* USER CODE END LPTIM1_Init 2 */2 M& P7 `- S, s8 q
- ) Q- p) p. b" F7 q# r
- }
复制代码
2 B V- Q% j0 V% \; H- ]. J9 S3 X) q3 m, J, t& h2 N/ L% z+ H
* C) s L' n* f4 @$ T这里可以选在HAL库 LL库6 h" f$ r: ~2 x2 g4 a, m8 g% R
, n4 A( b. N5 \' z5 H; w3 ^( a0 ?+ i6 a# b; D
- HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)aTxBuffer, TXBUFFERSIZE);2 t8 F# D- Z6 g% ]! @
- " S) q! r M: E/ O* I) V
- HAL_Delay(1000);
复制代码 * i+ u, K8 _" A
8 g5 ^ g' W+ X' g8 c+ @5 I7 E0 I( H+ J/ K
运行如下:
0 k. O1 F. H: z5 ?
7 R/ i {( w& g- a# g( Y
) m l7 f: [9 M7 C# o2 t2 q* Z- i- d
8 ?0 j0 H1 W7 U Y- q7 L9 [' y3 P1 Q" o, U; W1 T
|