说明:驱动基于STm32G031K6测试,其他型号需自行做改动。
' w* g' p/ k$ s! Z9 b( E6 |; w( c+ B1 w" m2 L1 O6 I& {" q
串口1的初始化:
& r# s* v3 }$ F& E: V/ }/ [' ^2 {/ V: n2 ]# B- z# l
- //使用串口1,通过中断和DMA进行数据收发。DMA的初始化另作说明
0 L6 K/ f, ?: Q0 E. @ - void STM32LLUart1Init(void)
7 d/ M8 }. n4 C1 F9 O. @ - {2 O0 K, I+ T: d9 w9 C" D: C0 h
- LL_USART_InitTypeDef UART_InitStruct = {0};
7 N& e1 k0 y$ q* S0 `* l - LL_GPIO_InitTypeDef GPIO_InitStruct = {0};! Z0 n' r/ i; u( ?3 F
; k9 Q0 O7 Q, h/ _- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); //使能GPIO时钟1 u* V% l7 D" ]* D, A$ E. @
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); //使能串口1时钟
6 W- {/ t, p, h6 O' D. C
3 I% H. A- F8 _3 Z2 Y- GPIO_InitStruct.Pin = bspUART1_TX_PIN; //TXPin指定
w" V3 u9 m/ r3 W0 i - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; //io模式配置为复用模式0 ]2 y+ u! \- q, F9 u0 Z8 |
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; //设置为高速率8 I+ w" B$ k% K( @8 H
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; //设置为推挽输出" b" Q7 o! |# N3 b. i) Q% U& X3 N
- GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; //不带上拉+ x' d' B4 [5 ^ V. l
- GPIO_InitStruct.Alternate = LL_GPIO_AF_1; //选择复用IO功能# F: w: e5 ~) u9 @6 k& g2 |
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
9 f. C O' \ g$ W6 q, @5 T( N" B - # ~( W, \9 m+ u1 ] }8 a# a% v8 Z
- GPIO_InitStruct.Pin = bspUART1_RX_PIN; //TXPin指定2 A& ]: ?+ L' G. r4 y% w& `6 X- r
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
2 Q+ i2 v/ v0 I' B; t% u$ t - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;( T. E3 x6 ^$ U: W0 j2 \+ U
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
. }/ u: Q. }' L9 X* R1 O - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;; }3 M- n( E: I) l
- GPIO_InitStruct.Alternate = LL_GPIO_AF_1; //选择复用IO功能7 [ H( c+ P5 |4 u; d. Z
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);! P2 r: r* ?1 U$ u0 u: {
- r; C4 ~# p% z2 Y$ ~- NVIC_SetPriority(USART1_IRQn, 0); //开启串口中断( O: y: B& U$ Q4 e5 Z- p8 L$ I2 n2 A
- NVIC_EnableIRQ(USART1_IRQn);
+ r# Z; O/ [0 Q/ S7 Y- y7 B - - w- D: `7 g4 q; J5 O
- UART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; //设置时钟预分频1 E* W; M& z l N: V P
- UART_InitStruct.BaudRate = 115200; //设置串口通信波特率9 s7 s! f, o. w! h% O
- UART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; //8位数据位
l- [ n9 Z2 j% W# K+ D+ u: r6 Q# [ - UART_InitStruct.StopBits = LL_USART_STOPBITS_1; //1位停止位4 o H- V D" K+ a' b0 l$ r0 `
- UART_InitStruct.Parity = LL_USART_PARITY_NONE; //奇偶校验关闭
, F" e& G0 D) q4 Q4 Y( J - UART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; //数据收发功能都开, F- V5 |7 I# |1 d' D9 D! L
- UART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;//硬件流控关闭
% v* I% U, R$ v: p - UART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; //数据采样频率倍数设置
; T- ?5 \; v4 Y8 y u& i/ v - LL_USART_Init(USART1, &UART_InitStruct);
# s |0 R* Z$ Z R; y: Z
% m. D) O) i+ U* n- LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);//设置TX缓存阈值为深度的1/8,暂时不理解这个,可能是串口中断产生时的fifo阈值吧& b" b$ |2 x2 [- J/ }/ {9 M/ f9 Y8 b
- LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);//设置RX缓存阈值为深度的1/8$ ~: X7 q X$ {0 L! h6 ]
- LL_USART_DisableFIFO(USART1); //因为使用dma接收,关闭FIFO
0 u! e& m' d- z3 S& d - LL_USART_ConfigAsyncMode(USART1); //其他基本配置
# s: O9 B) r6 _! x1 f( r1 W
/ f+ V6 b9 V \- LL_USART_Enable(USART1); //使能串口; A8 h; S! j5 N) j
- O! x( P8 ` Y
- while((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1)))); //检查相关标志位) U; i: M5 v( }
- 1 E( c" r3 P+ c% x6 [7 f9 d
- LL_USART_EnableIT_IDLE(USART1); //使能空闲中断2 R0 m" o: @/ {" u
- LL_USART_EnableIT_ERROR(USART1); //使能错误中断
% Z% V/ w9 O0 `/ Z) \3 |9 }
% v' S' K9 m9 n5 _* g8 Q( w e- }
复制代码 6 p' ]( I, n* q u: g0 a3 d3 ^
串口中断处理函数:2 H; i% j7 E$ _8 K; ^4 V% h
, E: V* h- a- K) M+ Q: {- void USART1_IRQHandler(void)* `- U; T) [/ G9 a! f
- {
, ~. }% _- c H5 L1 x# G' I5 ] - uint32_t isr_reg = 0;
: X1 J. ^" `: u- Y4 I. ~ - isr_reg = LL_USART_ReadReg(USART1, ISR); ; [& ]2 V) a- N0 k/ l$ d( r
- if (LL_USART_IsActiveFlag_IDLE(USART1))7 p# U7 J6 ?5 M0 y
- {
% s$ p- @# V! J4 [# p - LL_USART_ClearFlag_IDLE(USART1);4 b4 o% I; ~4 R0 `& ?, O
- //设置串口接收使用DMA,串口接收的数据会自动保存到DMA初始化时配置的缓存内,+ |. K: S0 i6 A
- //这里可能需要对收取到缓存的数据做一些操作。
" s% E: U( o* @8 Q6 _: E# {" b - }
, M0 {2 v* z, \# v8 e3 s - LL_USART_WriteReg(USART1,ICR,isr_reg)/ { l. o/ M9 V1 S3 a
- }
复制代码
+ A& Y8 _ J, ~$ ^2 ~ P串口发送函数:3 G1 Y/ V: J9 p8 F# V$ O- v
% p& w' w9 r1 g# Q7 q5 g- void STM32LLUart1SendBuffer(uint8_t *buffer,uint16_t length). X- b' {" a: s( {9 W" C
- {2 m! h0 \! m# w- m
- uint16_t i = 0;( c6 j( _) L4 Y# m- B. u# j
- for(i=0;i<length;i++)
! {2 v$ S) y* H+ L2 |! K - {
+ |+ v5 T- _' K - while(!LL_USART_IsActiveFlag_TXE(USART1));0 x" Z8 b7 ]- n& `) F5 O
- LL_USART_TransmitData8(USART1,buffer<i>);7 G6 [7 a0 @: N% S: t
- </i>}: L5 ]! O) x- F2 y- N; r5 U
- }
复制代码
, Z7 Y/ D. a U4 h& Z- ]串口数据接收通过DMA进行,不需要串口接收函数,DMA具体配置另作说明。
4 j, q' M+ D7 F1 V
: t, o& T, S" o( z/ g
6 z2 C& d9 h* ]# d- K |