说明:驱动基于STm32G031K6测试,其他型号需自行做改动。
3 o1 n, W0 P, H3 x. M9 X9 r" J" N$ V$ U9 C* W& }5 l7 h
串口1的初始化:
& b8 U3 v1 i8 ^! e/ o" c4 J% J0 T9 Z" J1 O A! y- k" O
- //使用串口1,通过中断和DMA进行数据收发。DMA的初始化另作说明
/ w; C1 [+ A2 W6 P3 X' e: E - void STM32LLUart1Init(void)
+ R) T4 O1 t+ @% V+ d - {, V X/ @. c0 H3 F6 U9 L4 n' C
- LL_USART_InitTypeDef UART_InitStruct = {0};
; {4 e( c* l# u+ n$ w4 g j - LL_GPIO_InitTypeDef GPIO_InitStruct = {0};' n' b* _' _) i* Y- k I
- : s0 K' j+ K0 j& o1 j
- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); //使能GPIO时钟
8 r& I& K+ v7 E' M# V1 {% ~% m% [ - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); //使能串口1时钟
/ Z9 J4 V6 a$ z9 U# |. C/ b
, Q3 d2 ^5 G- x$ V5 o- GPIO_InitStruct.Pin = bspUART1_TX_PIN; //TXPin指定" p* q2 z3 {" p* T& o: H0 b+ w
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; //io模式配置为复用模式
3 r/ O. E1 z) x) X - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; //设置为高速率& O x) l$ ? h5 [( E. ^
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; //设置为推挽输出
- C* w$ w. |7 a3 y2 n. ~ - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; //不带上拉' L* u/ E$ m- J5 O* W9 u
- GPIO_InitStruct.Alternate = LL_GPIO_AF_1; //选择复用IO功能
2 S; i) @" Z# E( N+ Z6 }8 G. J - LL_GPIO_Init(GPIOA, &GPIO_InitStruct);+ N: O4 R6 f3 L- G- N7 }5 s" `
+ J: z' y/ `2 }/ F- GPIO_InitStruct.Pin = bspUART1_RX_PIN; //TXPin指定2 u6 K5 R0 e+ @, W7 y: S5 Q- A
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; \% i/ k5 U9 r4 Z6 G; x
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
3 l q* j7 V5 ]: Y0 Q7 z& k1 g - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;/ i( X, s. [5 o( X' v
- GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
- B8 K/ i" @8 ~' D5 X - GPIO_InitStruct.Alternate = LL_GPIO_AF_1; //选择复用IO功能. A4 \" k, q& i+ z. u6 v
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);8 c2 u) K) p- \
- ! x3 }* U2 F; e* i# v
- NVIC_SetPriority(USART1_IRQn, 0); //开启串口中断
( I6 X! |9 Z% I) h- S- i. S - NVIC_EnableIRQ(USART1_IRQn);
/ S' t* R4 E3 X7 Q; m5 L+ ~
F: {, X4 p3 n, V8 t6 F- Z- UART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; //设置时钟预分频8 f4 o5 x+ p/ Z2 T1 h
- UART_InitStruct.BaudRate = 115200; //设置串口通信波特率
6 z1 q6 Q8 X0 l' X& J - UART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; //8位数据位. Q$ L* P+ f5 m7 V
- UART_InitStruct.StopBits = LL_USART_STOPBITS_1; //1位停止位
9 w7 Y! Y2 P7 }2 p5 F - UART_InitStruct.Parity = LL_USART_PARITY_NONE; //奇偶校验关闭
n9 L j5 P6 A# [$ O6 b - UART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; //数据收发功能都开
! J6 W5 A- ?# I( x( V5 p - UART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;//硬件流控关闭
0 X a, ]7 H6 r( ~& H9 R: c3 O% u - UART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; //数据采样频率倍数设置
& |) ^5 @ {" e; v& }. T, P& d - LL_USART_Init(USART1, &UART_InitStruct);
4 M' d% x+ w. L- d0 u
- i$ `4 Z. r* n: V+ \/ ?- LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);//设置TX缓存阈值为深度的1/8,暂时不理解这个,可能是串口中断产生时的fifo阈值吧
/ W- q- w4 Z* r- `/ J' L7 I - LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);//设置RX缓存阈值为深度的1/8/ d! g& t$ ]( o7 T4 @0 j. s
- LL_USART_DisableFIFO(USART1); //因为使用dma接收,关闭FIFO+ z3 o2 z6 Y, o( f" n
- LL_USART_ConfigAsyncMode(USART1); //其他基本配置
: ]/ Q1 U7 ^! g& \7 h8 c3 z9 j - 5 U4 d7 E3 Q5 `% o: A" p. {
- LL_USART_Enable(USART1); //使能串口4 v" D/ d4 B: g7 `; u( L( b
/ H4 P7 u; G1 g/ h- while((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1)))); //检查相关标志位( j; J, t) Z5 P' P) J p" `
: I: Z; L: m/ o/ ^- LL_USART_EnableIT_IDLE(USART1); //使能空闲中断
, e% O! @9 d0 D; S& | - LL_USART_EnableIT_ERROR(USART1); //使能错误中断+ b1 r6 w& g2 x# N0 ~
- 5 s* h( j! r9 m ^
- }
复制代码 7 g) T$ W2 K! V& L
串口中断处理函数:
6 d% V9 v/ t) f) |+ u0 D/ h+ d3 Z7 B+ h# X- V/ t5 |
- void USART1_IRQHandler(void)) p, ~ T+ n; I' O6 l/ e
- {2 J; a3 j+ D- t6 n2 ]
- uint32_t isr_reg = 0; 9 L5 }" C& R/ k
- isr_reg = LL_USART_ReadReg(USART1, ISR); ! |5 A; a2 R; L" q5 N
- if (LL_USART_IsActiveFlag_IDLE(USART1))
& c* ?, q3 q( s - {
- P6 M k2 Z: t. X6 n - LL_USART_ClearFlag_IDLE(USART1);9 P+ t) [( _. w
- //设置串口接收使用DMA,串口接收的数据会自动保存到DMA初始化时配置的缓存内,
" x7 y% B: z. ^7 W# n3 |$ E4 a! A4 O - //这里可能需要对收取到缓存的数据做一些操作。( ]5 p5 \6 S4 y' a' X4 |$ {1 N
- }
4 J) {/ K9 F. T! E1 s! F - LL_USART_WriteReg(USART1,ICR,isr_reg)& Z" a F8 C: O$ {( y6 E
- }
复制代码
3 ~4 U' C8 J* Y3 W串口发送函数:1 _1 t3 h0 Y5 y( h$ Y' L+ B7 ~4 r
1 v6 s- P1 i2 m1 e3 Q
- void STM32LLUart1SendBuffer(uint8_t *buffer,uint16_t length)
3 x8 x1 R+ G% i( k/ Q1 U - {. O! H/ R, w' t# G
- uint16_t i = 0;* N' C0 g* |$ T y3 S6 P' a
- for(i=0;i<length;i++)
6 v( ^( G: K; j! c - {: ] t/ i+ U5 h
- while(!LL_USART_IsActiveFlag_TXE(USART1));# N1 @3 G; U1 a" w
- LL_USART_TransmitData8(USART1,buffer<i>);6 _5 b' i1 e( f1 }
- </i>}
7 B! c* v/ d( c% Y+ M( u8 o' i - }
复制代码
! _' N) T6 Y! P2 l9 j* c串口数据接收通过DMA进行,不需要串口接收函数,DMA具体配置另作说明。2 B" l @& i( I" z0 L
0 w, |2 {& l, c2 X. t5 L l+ t7 X- K5 `, t0 h. W
|