说明:驱动基于STm32G031K6测试,其他型号需自行做改动。
7 t/ {8 K- s& M* B' Z" e, f" Q0 d: a2 S
串口1的初始化:- W" j. ~' X8 g7 s7 u
% @' B: c* j6 Y; E' x- //使用串口1,通过中断和DMA进行数据收发。DMA的初始化另作说明- g2 r( k) j' W+ {
- void STM32LLUart1Init(void)6 `; F3 ]- p7 v/ V) w8 |
- {# d" M9 I8 b/ U) x' G
- LL_USART_InitTypeDef UART_InitStruct = {0};" s- J' u6 P' \, ~8 |" F
- LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
1 [" x5 Z, [* `' A" l( w - ) v' d+ v: _ W9 X
- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); //使能GPIO时钟
; ?5 D) K# |, t4 K- g - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); //使能串口1时钟' j( a' K h* _ D
- 5 H. C: u/ A+ Q2 [! a5 m; A
- GPIO_InitStruct.Pin = bspUART1_TX_PIN; //TXPin指定
' y& ~9 M5 Z. J; H - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; //io模式配置为复用模式8 h* Y$ R8 x' Y }7 W
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; //设置为高速率* n# f6 V8 ?; m7 c) L$ p! t/ J
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; //设置为推挽输出
, B7 s! C0 m- L0 C - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; //不带上拉; ]7 R; \* Q0 _$ T7 j0 o/ s4 Y
- GPIO_InitStruct.Alternate = LL_GPIO_AF_1; //选择复用IO功能) w- ]3 M" S$ C3 O) E2 X
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+ A- }9 K' e. z6 e+ i# [ - 4 K( U7 f3 d4 _3 Z/ o4 A
- GPIO_InitStruct.Pin = bspUART1_RX_PIN; //TXPin指定% P- X7 J) I2 D) f {& [7 u% I
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;. O) `% m+ A% s( M O2 A
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
9 J2 W( O& y: j$ {4 v6 r - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;% S5 }. ]4 l5 ]
- GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
* ?4 s+ O M% X" r. l - GPIO_InitStruct.Alternate = LL_GPIO_AF_1; //选择复用IO功能
- N; E$ k! o- h. u1 ] - LL_GPIO_Init(GPIOA, &GPIO_InitStruct);7 J* C7 L$ ~: P& ?" y7 Y8 W6 I
% Q) q i9 E: ?- NVIC_SetPriority(USART1_IRQn, 0); //开启串口中断: Q) B# g" ~ k8 i" g
- NVIC_EnableIRQ(USART1_IRQn);
0 H- k% t z! q" R* n& g
6 I' D& F0 M; Y- s0 V& A0 a: e- UART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; //设置时钟预分频
; J! V* q% k& P* d: c' c' _6 s8 g - UART_InitStruct.BaudRate = 115200; //设置串口通信波特率
- O9 e! ~6 J; s2 {3 m/ Y$ | - UART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; //8位数据位/ W& P/ m/ H7 A" Z( _% T: {8 i
- UART_InitStruct.StopBits = LL_USART_STOPBITS_1; //1位停止位
1 ] X: C9 I5 g, ` - UART_InitStruct.Parity = LL_USART_PARITY_NONE; //奇偶校验关闭; k4 r0 R( R. X0 L# E: q, Q3 J
- UART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; //数据收发功能都开$ n% e g: G, o2 n; f& f9 }- E2 t8 f
- UART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;//硬件流控关闭
8 _6 W1 h/ E4 T - UART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; //数据采样频率倍数设置$ {2 d' C) ~9 q* [
- LL_USART_Init(USART1, &UART_InitStruct);
) N, N. j! O% m) t& b
# K5 s$ B9 l" W- LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);//设置TX缓存阈值为深度的1/8,暂时不理解这个,可能是串口中断产生时的fifo阈值吧
: @! ^% Q, G- W% g0 B e. r! c/ ]+ ~ - LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);//设置RX缓存阈值为深度的1/8$ l9 ], N6 L. Q
- LL_USART_DisableFIFO(USART1); //因为使用dma接收,关闭FIFO5 N# u( d _# w1 o; F; v9 S
- LL_USART_ConfigAsyncMode(USART1); //其他基本配置
! @9 h; k$ z; C7 r# f/ |8 j
7 D& s7 _0 d; M- LL_USART_Enable(USART1); //使能串口0 }9 g; \- U; f6 O; O; K" | x" v' Q* B
z- L$ p: K" y& h- while((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1)))); //检查相关标志位
2 V8 i7 Q1 S% _, P
( s+ ~3 n6 H& D) l- LL_USART_EnableIT_IDLE(USART1); //使能空闲中断
' A- M# D) G$ w9 A9 I5 x W - LL_USART_EnableIT_ERROR(USART1); //使能错误中断
" W3 C- s6 u9 V* T' j& q4 e
# U' [$ u" l7 P3 |# B6 E- }
复制代码 ( J _" X2 Y- i' n# `2 p
串口中断处理函数:) j, }6 { u F; ?+ c4 T9 x q, ?, t
2 \+ M# |- n& F$ Y: C8 q& v
- void USART1_IRQHandler(void)
) I& U& a* L0 r# p g& c - {7 K7 v2 h, B& \( H" ~% {4 |
- uint32_t isr_reg = 0;
3 O/ V& e# n! S3 G2 p - isr_reg = LL_USART_ReadReg(USART1, ISR);
4 k/ ?! K; O- ] - if (LL_USART_IsActiveFlag_IDLE(USART1))
: i) q K. \: p, M - {
7 p9 r1 h6 E5 T% \/ C$ u - LL_USART_ClearFlag_IDLE(USART1);9 G) Y) \$ `$ x, i5 ^4 V$ X
- //设置串口接收使用DMA,串口接收的数据会自动保存到DMA初始化时配置的缓存内,6 H$ B0 m# I8 V9 ^
- //这里可能需要对收取到缓存的数据做一些操作。
9 _$ ^' h/ i/ g' e& Q5 W m - }* C0 _$ f) O0 `
- LL_USART_WriteReg(USART1,ICR,isr_reg)+ J) u" {8 ^1 L% C: o7 G
- }
复制代码
( E$ l" f2 L; T串口发送函数:% f g- D6 F" h
a8 e& e! k$ }! N
- void STM32LLUart1SendBuffer(uint8_t *buffer,uint16_t length)0 a+ w) z8 b% _. l2 K- R3 P
- {: t9 i$ P0 u7 L0 g0 z+ U6 b1 c9 z, X3 K' `
- uint16_t i = 0;+ n8 Z" |; I7 i: V
- for(i=0;i<length;i++)
. e( K2 G9 P9 t6 \4 R - {4 |, v) f" o- z+ [% c& F
- while(!LL_USART_IsActiveFlag_TXE(USART1));, a% j' D: k+ V( F4 V
- LL_USART_TransmitData8(USART1,buffer<i>);2 ~) }! r2 _8 o8 W2 M0 U
- </i>}4 t! e, i4 C# a' i* q: R: k
- }
复制代码
+ B" @$ C9 }, s: h串口数据接收通过DMA进行,不需要串口接收函数,DMA具体配置另作说明。
6 `9 {8 p3 L* P" _% I- O
6 f# R# n1 V6 D' Z" I/ d% y* O5 c) e
|