说明:驱动基于STm32G031K6测试,其他型号需自行做改动。
8 Y [( {2 R% k5 Z( E! V( m @$ o+ I. ~2 E
串口1的初始化: H5 M: d! y( G( j* \- J0 k1 r! \
v$ V' }+ B3 |! i1 R! v
- //使用串口1,通过中断和DMA进行数据收发。DMA的初始化另作说明6 S( N8 b# Z4 r! X8 z" y+ d
- void STM32LLUart1Init(void)' H( x A6 z2 R" i j C
- {
o+ l: x% W7 \3 X# w - LL_USART_InitTypeDef UART_InitStruct = {0};. ?8 G9 u0 C' _3 O
- LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
9 E# g, r1 L: h0 Q9 X; t7 W" ^
/ L# }) j/ }+ K% O6 B- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); //使能GPIO时钟2 _$ s9 O3 x* |5 H8 U
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); //使能串口1时钟
8 p) I1 N s6 F- j
0 M+ I) ~' G! W) P- GPIO_InitStruct.Pin = bspUART1_TX_PIN; //TXPin指定
% ]- S3 K/ \7 D7 y* V - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; //io模式配置为复用模式
1 d& _' l% }; B) C - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; //设置为高速率: t. w7 } ?4 X1 l5 z) l
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; //设置为推挽输出
0 V. G; O1 F1 z4 V, ^/ K - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; //不带上拉6 n7 G- _& N, {$ H+ \7 V: Q( |- n
- GPIO_InitStruct.Alternate = LL_GPIO_AF_1; //选择复用IO功能9 I K- ^6 ~+ l1 F( B: Q
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
3 i4 X i. W) l3 D3 R - 0 {; L+ }0 H1 }6 P- F
- GPIO_InitStruct.Pin = bspUART1_RX_PIN; //TXPin指定
8 `3 z+ ]8 d' l - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;8 Q+ |# ~/ o; P3 i: \& G
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;/ m `& r8 [" T. u& N
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+ o T, x' a/ h2 q - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;" x; |! ?/ H* s/ n* q5 m& f2 o$ P/ N; K
- GPIO_InitStruct.Alternate = LL_GPIO_AF_1; //选择复用IO功能& x: G: Z2 @- U4 b
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);0 Z5 l0 k4 ^& m
- ; j1 ^+ d+ N& w1 _! x
- NVIC_SetPriority(USART1_IRQn, 0); //开启串口中断% U* V2 `. k* b) V7 }2 t4 k
- NVIC_EnableIRQ(USART1_IRQn);1 ^/ v x- }3 ^
3 r' b% t/ Y8 {- UART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; //设置时钟预分频
3 V4 u8 A7 P2 M% v! Y6 P - UART_InitStruct.BaudRate = 115200; //设置串口通信波特率+ D. |0 W2 E& [' q
- UART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; //8位数据位 v# G: J! B2 g3 I: p
- UART_InitStruct.StopBits = LL_USART_STOPBITS_1; //1位停止位1 [; L) G/ U# P# O, ?0 a
- UART_InitStruct.Parity = LL_USART_PARITY_NONE; //奇偶校验关闭6 l" \* p& z& ] y2 W( L) I; q
- UART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; //数据收发功能都开
w. J; \; l& [, b- Z' i, a3 ~& Y - UART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;//硬件流控关闭
" M3 ^8 s. ^ c) H2 I - UART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; //数据采样频率倍数设置
* h$ d: `2 V; D) D8 N: X5 s3 b3 R% v1 z - LL_USART_Init(USART1, &UART_InitStruct);
4 N; X) f1 s9 g: n0 t
; t" \* X& Z) w( `- x; R! s; ~- LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);//设置TX缓存阈值为深度的1/8,暂时不理解这个,可能是串口中断产生时的fifo阈值吧
+ K$ k4 c0 ]. H: C0 i" a - LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);//设置RX缓存阈值为深度的1/8- Y, Y( c* z+ U
- LL_USART_DisableFIFO(USART1); //因为使用dma接收,关闭FIFO
3 d' h7 E, F7 h- L8 M+ } - LL_USART_ConfigAsyncMode(USART1); //其他基本配置
3 @9 W5 D& G- u, V4 m - 4 s p' P( v& l" }* k9 C6 G: {
- LL_USART_Enable(USART1); //使能串口
|. X, ]8 u* P2 c' Q. h - 6 |4 [% e. D8 U4 x4 s3 I( K
- while((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1)))); //检查相关标志位2 O9 T l% G+ D, h" U5 }" B
- ! Z; b. N A9 _" N
- LL_USART_EnableIT_IDLE(USART1); //使能空闲中断. j2 R- R# v, {2 {9 j: F
- LL_USART_EnableIT_ERROR(USART1); //使能错误中断& O6 Z3 T! L& n/ f+ b- _! Z% z
! K: Q. X( W) g8 U# P/ W; f- }
复制代码 $ v' T, d* b6 m5 p0 F
串口中断处理函数:
" s+ w2 o$ d1 `+ L* s/ Q; ~- u, w& `* \8 S- L, R
- void USART1_IRQHandler(void)# Z6 ~; p& B2 Z" ^* d
- {$ D& X) C4 \7 A+ B# _, y- c6 d
- uint32_t isr_reg = 0; " }* J/ y, L, q5 K: o( G, |
- isr_reg = LL_USART_ReadReg(USART1, ISR); , a7 K& v" g% R0 ?: _, e( I
- if (LL_USART_IsActiveFlag_IDLE(USART1))! l& L1 F, o4 u$ C+ M! z
- { e4 B& }6 {6 B, f3 O
- LL_USART_ClearFlag_IDLE(USART1);2 L* n3 T9 F% u* r8 k: E, e! ]% t, ?
- //设置串口接收使用DMA,串口接收的数据会自动保存到DMA初始化时配置的缓存内,7 \6 d- Q7 S) h
- //这里可能需要对收取到缓存的数据做一些操作。& H5 M) m) X+ C u) ]
- }5 K, G# T5 Z/ V4 Z, q5 H: } A
- LL_USART_WriteReg(USART1,ICR,isr_reg)
O5 {$ d# x8 _% r6 ~4 J2 ~ - }
复制代码 + V5 U& S/ Q2 g4 z" E! [% D
串口发送函数:
, E* @ F) p% X' U6 a+ |: m7 B+ ~( L% i7 }# _2 z) p B! C! ]# [
- void STM32LLUart1SendBuffer(uint8_t *buffer,uint16_t length)
2 Q" |: \; Q8 G3 y - {
/ F9 N. p. A+ T" D - uint16_t i = 0;
( R1 Y" n4 }+ @ - for(i=0;i<length;i++)
: ?+ p3 ~' b, \1 j+ Q - {
& j _' S. b. ^% f; _6 l - while(!LL_USART_IsActiveFlag_TXE(USART1));% v2 q" C2 ?" s8 u& A8 q
- LL_USART_TransmitData8(USART1,buffer<i>);
7 p H7 w) z0 s8 h2 m& K - </i>}0 A1 n1 Z$ L7 D% g1 Y
- }
复制代码 0 `$ g/ \; O$ E8 N+ h, y0 E
串口数据接收通过DMA进行,不需要串口接收函数,DMA具体配置另作说明。* r% l! P) O2 G: i/ c L
7 x2 ]% s* ~0 O
# e# u! T6 f7 a% Y+ ]9 C- G
|