说明:驱动基于STm32G031K6测试,其他型号需自行做改动。
5 G5 P7 T b# p# {' }# T1 N* ^5 B, R, ]1 `9 S
串口1的初始化:& T& x$ d* h; g3 J) @( \; I
7 I M/ O7 k3 N/ R! S
- //使用串口1,通过中断和DMA进行数据收发。DMA的初始化另作说明
, U4 C. Y$ e# {! D) K - void STM32LLUart1Init(void)& w( q6 K6 N1 m0 N. n
- {
+ \2 {- R! K4 r' ]' o: ^. j3 o7 t - LL_USART_InitTypeDef UART_InitStruct = {0};( `! S9 E6 q% h" Z) l7 Q% }! {
- LL_GPIO_InitTypeDef GPIO_InitStruct = {0};/ J8 ^) b: }! M" p/ J& t& K8 c
5 l$ `% {/ J) m- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA); //使能GPIO时钟( Q7 M! z0 I. P) F5 n6 m7 u
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); //使能串口1时钟; ~" l$ x8 B% y: t0 x6 U& Q. U
- 6 ]" C7 @2 j( ?' Z. z$ f6 S# \
- GPIO_InitStruct.Pin = bspUART1_TX_PIN; //TXPin指定$ A5 a9 j. w% \: B h! @8 i. N
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; //io模式配置为复用模式1 U; x$ |/ ^& _; w
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; //设置为高速率3 `2 ~6 U+ w9 J/ C. q' l
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; //设置为推挽输出
, i5 P# C) z" D2 i; |& e/ P7 R - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; //不带上拉
0 }/ F4 [' O1 y: ?1 S, u9 O3 W i& c - GPIO_InitStruct.Alternate = LL_GPIO_AF_1; //选择复用IO功能9 r4 g- a& N" E) @7 g
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
: H4 s2 d1 e. z' h4 s - 8 V u4 ?/ U$ C- y C
- GPIO_InitStruct.Pin = bspUART1_RX_PIN; //TXPin指定$ b; Y- R e6 h* X+ s* C6 b! a7 A
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;; M e- \0 b# w2 j t2 _. x
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;6 E. z( w( y$ I
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
: @: z- i. ~* g - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; Z' @" g2 V8 a* T* M
- GPIO_InitStruct.Alternate = LL_GPIO_AF_1; //选择复用IO功能
) y& V% V1 Z u" i D - LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
! T, M' k4 N. t7 P! M* F' X
' j/ { ]( G4 z( _. h- NVIC_SetPriority(USART1_IRQn, 0); //开启串口中断
4 ?; o+ V6 {* h T% ^4 p. W, C - NVIC_EnableIRQ(USART1_IRQn);
* A$ |0 ?4 i% r/ V7 ^4 N% ]# k - : r0 W% u* W" j( z/ o
- UART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; //设置时钟预分频
3 \: N7 O. _3 Q( Q: M - UART_InitStruct.BaudRate = 115200; //设置串口通信波特率
; A7 l6 A4 b& @% z5 O' C - UART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; //8位数据位
5 D0 T; u9 ?) M5 o, ^ - UART_InitStruct.StopBits = LL_USART_STOPBITS_1; //1位停止位
8 L2 q" W' n) k/ X1 K - UART_InitStruct.Parity = LL_USART_PARITY_NONE; //奇偶校验关闭
* {+ }1 U6 y$ \- A, w2 i$ q - UART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; //数据收发功能都开
( U% M) U2 O# d$ e. k8 Q. V9 O - UART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;//硬件流控关闭
7 z& x7 i3 ^0 e7 ]9 C - UART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; //数据采样频率倍数设置
' q4 \ c* ]& |. a. Y2 _% E - LL_USART_Init(USART1, &UART_InitStruct);* f# G+ |& H0 G# t- |' n" _
+ L; f/ W7 X8 f8 {% @- LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);//设置TX缓存阈值为深度的1/8,暂时不理解这个,可能是串口中断产生时的fifo阈值吧/ j* f" A: v: M' b
- LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);//设置RX缓存阈值为深度的1/88 D# L+ T; o9 }6 k+ T
- LL_USART_DisableFIFO(USART1); //因为使用dma接收,关闭FIFO
2 s/ H* x) g1 `3 a - LL_USART_ConfigAsyncMode(USART1); //其他基本配置7 |. }+ K" D6 @2 Q* }
$ b1 @" G4 S/ v5 n9 I- LL_USART_Enable(USART1); //使能串口( D! F) ?3 @/ z
- ~9 X4 D2 U2 m( q- while((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1)))); //检查相关标志位
: j( L- G) W8 q/ R: g' [; ?3 R - ! c& i2 P& U+ J- @' m: Z
- LL_USART_EnableIT_IDLE(USART1); //使能空闲中断8 R( ?" U# P; K( p& u
- LL_USART_EnableIT_ERROR(USART1); //使能错误中断
2 Q* J) J9 `8 \8 e
, \( ?) x4 s5 z( V1 g/ I- }
复制代码 3 W% c- G) M/ Z/ E
串口中断处理函数:" V0 S% J3 |0 e$ k$ U7 a4 O; `
: A( K3 N l! a: S7 A- void USART1_IRQHandler(void)# r* o$ i2 O8 [0 Y
- {) t s/ y+ O/ p) C1 V) }
- uint32_t isr_reg = 0; 0 n3 H) p5 q* w5 R7 y% i
- isr_reg = LL_USART_ReadReg(USART1, ISR); 6 o' ~* B8 t4 C
- if (LL_USART_IsActiveFlag_IDLE(USART1))6 X, o1 {. z3 Q
- {
. b4 j/ X" b5 f3 F( \, e - LL_USART_ClearFlag_IDLE(USART1);) F4 A- N' F/ |) p) y1 p* v
- //设置串口接收使用DMA,串口接收的数据会自动保存到DMA初始化时配置的缓存内,- f- @* w; Z5 A& K/ a
- //这里可能需要对收取到缓存的数据做一些操作。
: C3 q' T1 y- `. M - }
6 V$ `8 {; k) S" p) t; `& R, g - LL_USART_WriteReg(USART1,ICR,isr_reg)8 V: H9 J" T$ O" @7 z" }
- }
复制代码 x( o% \% f6 Q f( e
串口发送函数:( b# j. n& M# R5 \2 ]
5 e. W p$ j" a( D6 }( B
- void STM32LLUart1SendBuffer(uint8_t *buffer,uint16_t length)
* }! N& }) `& W3 h - {
1 |. w2 g1 Y* x9 M( V - uint16_t i = 0;* X) H; l$ n r' I2 o
- for(i=0;i<length;i++)% M/ X' l {+ R, ~' U; o* o
- {
* G- z$ X, T5 ?; B8 b - while(!LL_USART_IsActiveFlag_TXE(USART1));/ T1 l- m, Y/ E* X% ~
- LL_USART_TransmitData8(USART1,buffer<i>);
9 `- b) d3 a0 _0 G - </i>}8 V6 A4 o7 l( a. F2 O% Y; k# F$ @' U
- }
复制代码
5 a" K3 X, K/ t) r6 F2 j串口数据接收通过DMA进行,不需要串口接收函数,DMA具体配置另作说明。. u( R. h- b9 g
+ e% N; R- a" X' g$ `/ k$ w' A7 C( X
# W8 ^/ s5 F2 e {. h
|