说明:驱动基于STm32G031K6测试,其他型号需自行做改动。$ ?2 F% j4 A- ~0 z1 [
- c1 u) z/ l5 n( i7 B* B
串口1的初始化:- Z7 L) l$ r# A0 a
0 V2 ]4 m+ ] [! i2 G
- //使用串口1,通过中断和DMA进行数据收发。DMA的初始化另作说明( N+ l# }4 ?2 c& B2 Y! ]9 o
- void STM32LLUart1Init(void). C5 S' g7 h$ A6 E" J" h
- {
8 `, p5 G3 b* J - LL_USART_InitTypeDef UART_InitStruct = {0};
4 Q; h7 ^: o. e3 j% x - LL_GPIO_InitTypeDef GPIO_InitStruct = {0};4 V' j( m: D( W& v6 Z* N
- ' k6 j8 W% i9 v) R& r9 \) S
- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); //使能GPIO时钟
& f& j" ~4 }& x% v3 c - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); //使能串口1时钟: O2 O4 y: i2 \# w8 N) L. q, T
- : e& s# Q0 W7 x3 ~9 P
- GPIO_InitStruct.Pin = bspUART1_TX_PIN; //TXPin指定2 K( b7 `; K- x/ s) j
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; //io模式配置为复用模式7 M3 ^! |0 s$ c E9 `5 S6 b
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; //设置为高速率
* J9 `( k6 j# \ - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; //设置为推挽输出: C7 `) x( {0 ?8 G1 c
- GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; //不带上拉/ i: x" Y4 F( L
- GPIO_InitStruct.Alternate = LL_GPIO_AF_1; //选择复用IO功能
' O. T0 D3 g5 a - LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
! |4 t" m$ f8 C7 `; R/ l% \! H1 G# K - 7 K$ F, \$ Q8 n. {) R- p3 s9 ~
- GPIO_InitStruct.Pin = bspUART1_RX_PIN; //TXPin指定' H8 |" P# F. A \7 f: e
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
$ x8 a7 y- I" A! o7 r( | - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
1 S0 _6 Q0 b" g8 T5 R p0 V* ?6 s - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;9 ]0 ^; [, ? S, v3 L
- GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
6 x5 I* z* G( j2 b/ _ - GPIO_InitStruct.Alternate = LL_GPIO_AF_1; //选择复用IO功能
. E' M2 |1 Q J5 g' N. H% M - LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Y7 C* N d. r: l
# d/ j) p7 i E, f" Z4 F- NVIC_SetPriority(USART1_IRQn, 0); //开启串口中断
0 @$ @' _% q" V3 M - NVIC_EnableIRQ(USART1_IRQn);
4 l& T% x0 H; s' C& ]" ]
5 H8 a! u7 T% D7 G" I- UART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; //设置时钟预分频
. b/ n( K% J- V; ^# g) b- n6 ` - UART_InitStruct.BaudRate = 115200; //设置串口通信波特率
# Z2 `/ p0 D; { s" q* \5 n5 s - UART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; //8位数据位% v9 A* e7 d# ~, j9 U
- UART_InitStruct.StopBits = LL_USART_STOPBITS_1; //1位停止位
$ N; g4 F$ N8 C6 K# O1 Z - UART_InitStruct.Parity = LL_USART_PARITY_NONE; //奇偶校验关闭
. Y8 \% T& B1 p - UART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; //数据收发功能都开
) [0 \. [2 H2 Z' J1 ? - UART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;//硬件流控关闭
5 f0 |; ~/ U; ]% l* j - UART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; //数据采样频率倍数设置
" S( m3 h: Z; s+ n, Z - LL_USART_Init(USART1, &UART_InitStruct);
. ]( G7 w3 ^7 w' q/ n* O - # Z& W$ t; y6 J0 n+ W* U/ ^
- LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);//设置TX缓存阈值为深度的1/8,暂时不理解这个,可能是串口中断产生时的fifo阈值吧
7 x* q" j: F9 m% A6 H& r( ]+ t( E6 s - LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);//设置RX缓存阈值为深度的1/89 J/ k- s+ j7 X$ A: u6 d2 t8 W0 P- J
- LL_USART_DisableFIFO(USART1); //因为使用dma接收,关闭FIFO
1 S& G& w: i! r& d9 t* Q) @" v - LL_USART_ConfigAsyncMode(USART1); //其他基本配置
9 u( X ^4 }- c7 y; p, ~/ ? - . @8 Z! X8 P/ ~! l% T9 U3 h
- LL_USART_Enable(USART1); //使能串口
4 Y* W; x9 X: k. P6 A% z9 g! R% c* P
8 p" s& _0 w8 `) y0 Z# ~- while((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1)))); //检查相关标志位
3 }" Z j- I y3 p' G+ h# X) h1 ^
0 p1 A4 p9 k' H2 E2 q. i, Y1 h- LL_USART_EnableIT_IDLE(USART1); //使能空闲中断' @$ d* Z! m/ z% L5 Q
- LL_USART_EnableIT_ERROR(USART1); //使能错误中断1 l5 ^, } c! M- K
- 2 D+ l* U0 ]5 P4 X* b; e6 d$ ^2 N
- }
复制代码 6 w$ l3 Y6 \7 Z9 t
串口中断处理函数:: u2 ~0 G- s |& \) N1 W
4 ]" i+ d6 m; J3 Q; x- void USART1_IRQHandler(void)
, L( P5 z+ Z8 t! a l - {/ K) ]3 z3 N+ C9 R0 X. `5 _
- uint32_t isr_reg = 0; 3 b" n0 o, d$ L) V- {
- isr_reg = LL_USART_ReadReg(USART1, ISR); 1 E" h, |+ X1 }% z( P
- if (LL_USART_IsActiveFlag_IDLE(USART1))
( l+ s: S# i% _0 O8 R1 z- H - {& w6 i% X0 c' I3 ~2 t$ K% M
- LL_USART_ClearFlag_IDLE(USART1);* P% c2 [8 g- k" n+ u. ?8 D
- //设置串口接收使用DMA,串口接收的数据会自动保存到DMA初始化时配置的缓存内,
: A; O& M; h% Q" \8 r9 a& R. z - //这里可能需要对收取到缓存的数据做一些操作。
- `) K s; n. x+ i4 w. T8 c - }" L/ P! D6 E& @
- LL_USART_WriteReg(USART1,ICR,isr_reg)$ d/ G+ C( X3 p
- }
复制代码 * i# b, A6 L$ |* o) c9 i: v
串口发送函数:
c& v. [' ?; ^' r1 R3 p
! r& P. C$ S3 c- void STM32LLUart1SendBuffer(uint8_t *buffer,uint16_t length)$ ^- |* w( X5 _: O' s) P$ l
- {
2 \/ U5 a, o+ G, j& @* d+ q& | - uint16_t i = 0;; J7 A, f% C: s4 K0 }9 B0 x+ V G
- for(i=0;i<length;i++); q4 t, X. u7 K/ C4 W
- {! } `9 A$ @4 P, N# b
- while(!LL_USART_IsActiveFlag_TXE(USART1));
: N- s' h3 j3 J$ r - LL_USART_TransmitData8(USART1,buffer<i>);
. ?! \! z7 Z; S/ t6 T$ k: F - </i>}
: n* @9 j, ^( B% B! B0 `/ O - }
复制代码 . W: |# }) t& r. R( v0 D1 l
串口数据接收通过DMA进行,不需要串口接收函数,DMA具体配置另作说明。' V$ Y5 O5 k X
& x0 w# m6 @1 N, C, |2 n6 ?! e, b) s/ G
|