单片机型号:STM32G030C8T69 N4 Q7 g4 Z! X+ j: Y# p- H7 Z7 r) v
在初始化完串口后,开启串口接收中断,程序就一直在执行串口中断(此时串口无任何数据),通过在线查看串口外设的相关寄存器(如下图)发现RDR寄存器一直没有被清零,导致ISR寄存器的RXNE位一直有效,串口中断就一直处于触发的状态。
( v: N- g5 A9 F8 X, |% {3 D+ f& E' I" y! f [2 [
( f: e: D' @5 N) b" t- s# H3 y- W; s通过查看STM32G0x0 Datasheet章节 26.8.10 Bit5 RXNE位,数据收据里面说到可以通过读取RDR寄存器或者往RXFRQ寄存器写1来清除ISR寄存器的RXNE标志位。
5 c7 G% U9 }' {3 A4 N3 B% M8 S$ f# ^' K! B1 x, K9 P4 S
* X1 Y ~5 m. b
2 e: K5 ~% I! Y/ v" s. W; q# dLL库串口初始化及中断接收代码如下:
8 r- z6 W( R8 C0 B% f7 h% d& ?6 l& Z. P
- void Usart2_Init(u32 baudrate)
: A& Q8 {$ p* H- d - {
# z! h4 k. K* }/ e2 M% ~0 @ - LL_USART_DeInit(USART2);
/ g* V. l/ X& n4 A - LL_USART_InitTypeDef USART_InitStruct = {0};
' C# T9 P9 \. @- l - LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
* ?/ t/ [% Y0 A* c: @0 v$ S -
6 X' a, U9 h& {6 ]7 d - /* Peripheral clock enable */
3 d; J$ R6 U8 @/ ^! K" z8 g - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);
. [3 v1 u3 }. \1 K9 O5 b6 q v - LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);) i4 K* d0 q# p) M$ }2 V6 @- s
-
( ^: m5 b: X+ D& n - GPIO_InitStruct.Pin = LL_GPIO_PIN_2;0 Q; @* \8 X4 J6 O, P
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;( a$ H4 m1 _, E( b, R
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
: D, a7 z4 `4 ]2 ^6 y" W0 g - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;' {% } x' ?* c1 g/ V! ~4 @
- GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
% w, Z8 s4 E8 _$ Q' z - GPIO_InitStruct.Alternate = LL_GPIO_AF_1;% v4 ?* g2 X n9 ?( @5 a
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
' c3 U _" O; b - 6 w. z! T1 P! R$ M8 I1 t
- GPIO_InitStruct.Pin = LL_GPIO_PIN_3;
0 A8 A, T* V6 }5 t; m" h& C. N7 T - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;& |# z, Q% P; p- B) }. g; t
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;4 Z( Z' K/ y3 I8 \+ w
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;( ]# n( ?$ }5 `) z3 r8 q9 Q
- GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;7 _: Y5 A+ U. k# W1 s( D
- GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
! z1 ]% M. t, j+ D$ S% ?3 Y' P' D - LL_GPIO_Init(GPIOA, &GPIO_InitStruct);1 V" i/ O% X* r: Q
- 6 n6 Z1 J$ o. W% ~& ]( j/ I$ Y
- NVIC_SetPriority(USART2_IRQn, USART_PREPRIORITY);5 ?, z3 A4 X; {* M/ k
- NVIC_EnableIRQ(USART2_IRQn);
/ ~5 a# C6 I/ y: D" V! x! E5 U -
) e0 o, V4 I7 L3 D - USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;# G2 a6 H/ s! [2 d
- USART_InitStruct.BaudRate = baudrate; //波特率
/ \+ v5 m% w/ h - USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; //8位数据
, t$ A8 L+ Z; k; H+ ]$ I3 B& Q - USART_InitStruct.StopBits = LL_USART_STOPBITS_2; //2位停止位
$ q9 l* F8 a$ A* F7 ~ - USART_InitStruct.Parity = LL_USART_PARITY_NONE; //无奇偶校验
) t4 B' ?' j3 e b* ] - USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;$ s7 I) Z" Y- ^
- USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;9 d/ u3 U8 C& j$ S3 z G! M
- USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;" h& e+ B- Y! J
- LL_USART_Init(USART2, &USART_InitStruct);0 Z2 E! Z0 F3 B' }$ s! W0 L
-
4 Y8 b/ r: U1 K& q" @; L - LL_USART_SetTXFIFOThreshold(USART2, LL_USART_FIFOTHRESHOLD_1_8);//设置TX缓存阈值为深度的1/8
; ]0 k: D3 }& e$ |: y; M* F - LL_USART_SetRXFIFOThreshold(USART2, LL_USART_FIFOTHRESHOLD_1_8);//设置RX缓存阈值为深度的1/8
1 z/ r# U! X/ e! h - ( G, b" a' x5 n3 m
- LL_USART_EnableIT_RXNE_RXFNE(USART2); //使能串口接收中断
; u. O9 H( B+ C - LL_USART_Enable(USART2);# K, }5 f. C% e5 Z; N4 T4 g
- }, M: g' e6 r7 j
复制代码 / q- P9 B7 X; ?$ B4 {
void USART2_IRQHandler(void)
. N& D: l+ N" O9 w" r& [{
. X3 o6 Y7 R% F/ _& p2 N/ F u8 data;
( Z% |- k6 d. A* Q) u1 C" [ if (LL_USART_IsActiveFlag_RXNE_RXFNE(USART2)) { //判断接收数据寄存器是否有数据
! `9 F0 _# ]% _% i4 I //清除接收中断标志方式一:读取RDR寄存器以自动清除RXNE标志
1 p, A4 ?1 Z/ ~. c I/ p //清除接收中断标志方式二:往RXFRQ寄存器写1(刷新数据)以清除RXNE中断标志
* T1 R. B9 Y$ h f+ Y3 r data = LL_USART_ReceiveData8(USART2); //读接收到的字节,同时相关标志自动清除+ P8 u% M6 v$ ?) p
LL_USART_RequestRxDataFlush(USART2);
; G8 N8 g6 U3 j0 D( o0 d" s/ l- r5 @: Q }- Q' U* n+ A' Z
}$ ~7 f+ P u1 E# f$ ]
; g& [3 I, ]) f
# S! S2 @/ r" k; w5 \
, X0 E- ?6 n; B' g; |5 k v" D# H; s |