单片机型号:STM32G030C8T6
: L6 G0 v0 J% S6 ?+ v在初始化完串口后,开启串口接收中断,程序就一直在执行串口中断(此时串口无任何数据),通过在线查看串口外设的相关寄存器(如下图)发现RDR寄存器一直没有被清零,导致ISR寄存器的RXNE位一直有效,串口中断就一直处于触发的状态。
2 b4 C; \& i$ Q/ q
3 ^3 Z* J! Q9 _5 H9 V
; U: k9 Z a4 ^: M/ t通过查看STM32G0x0 Datasheet章节 26.8.10 Bit5 RXNE位,数据收据里面说到可以通过读取RDR寄存器或者往RXFRQ寄存器写1来清除ISR寄存器的RXNE标志位。4 Q' M, e; I' Y& T6 ?, s3 r m/ w* ?
3 g" s, b' C. l0 M* ]4 c W8 `; H+ P# D+ V4 M$ Z' X
- M0 N1 m0 i0 i5 n
LL库串口初始化及中断接收代码如下:
" [! S h/ I* w( u- U3 `5 g' f- x: A; L
- void Usart2_Init(u32 baudrate)
) u; o& v# p( i5 k# e0 u - {) |. Z+ p9 r. h9 @
- LL_USART_DeInit(USART2);
i& ], u% x a/ W$ g - LL_USART_InitTypeDef USART_InitStruct = {0};
' S. x! g+ j4 q2 M7 t) z - LL_GPIO_InitTypeDef GPIO_InitStruct = {0};1 f. u/ u/ Z; O/ Y9 ?; o2 a; M
-
; W* R! _$ }7 l3 I% Y& \1 u - /* Peripheral clock enable */
8 o, e( w4 B( y- { - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);( P9 V* h0 I9 E
- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
. A2 s5 f( `) W! ? -
4 m9 [1 h2 J8 R3 } - GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
' V+ O( O/ b7 @# d7 ? - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
% A2 o/ A. Z! r$ V - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;, |4 z% F( c) `* B+ i
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
- _4 ` X. Y7 \8 N y) J - GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;3 L A3 h' | \) m0 j0 p2 V
- GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
. J! u- |/ U* W4 }" o2 q! V4 h - LL_GPIO_Init(GPIOA, &GPIO_InitStruct);9 |7 y8 t4 i4 w5 `7 X
- - Y" @* L3 y: Q5 V) A- V* v
- GPIO_InitStruct.Pin = LL_GPIO_PIN_3;5 ]$ T0 E7 \8 P* [3 ~
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
: p! y3 O& z& ], B/ d- m! @ - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
& h0 X* A) r- \! A. v8 h: T3 ` - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;, @* ]/ C* h' \) m2 V U) V
- GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
* `& D6 [3 P- { - GPIO_InitStruct.Alternate = LL_GPIO_AF_1;: ]" g% k, M% f1 E
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);, J L& R0 r; H$ Q9 e2 }: ^7 F3 a
- ( |# T. [* [* e& N( p. W# @
- NVIC_SetPriority(USART2_IRQn, USART_PREPRIORITY); Q( C6 x5 `/ H& @
- NVIC_EnableIRQ(USART2_IRQn);5 l5 B& @2 n7 s% R+ R4 C1 w: ~
-
/ B' p' B1 o( I - USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;
: `4 ^" m* y7 B" |# F' K - USART_InitStruct.BaudRate = baudrate; //波特率
7 }! B4 N% _6 \: d - USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; //8位数据. _ v8 B Q; U4 A2 ~
- USART_InitStruct.StopBits = LL_USART_STOPBITS_2; //2位停止位3 M8 N" [! J) u( x! `
- USART_InitStruct.Parity = LL_USART_PARITY_NONE; //无奇偶校验
8 }, _1 ]( R' Y6 g" C+ N - USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
/ f2 X3 v; h; b C+ e - USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
: z+ y) @# F" A; {' `( Y - USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
* c' U. O9 T6 n& H& _" k. A - LL_USART_Init(USART2, &USART_InitStruct);( b8 R7 T {5 P7 z
- % y* f( ~2 o8 G0 A3 X' G, \
- LL_USART_SetTXFIFOThreshold(USART2, LL_USART_FIFOTHRESHOLD_1_8);//设置TX缓存阈值为深度的1/8; b+ Y7 j5 {. b4 I1 E
- LL_USART_SetRXFIFOThreshold(USART2, LL_USART_FIFOTHRESHOLD_1_8);//设置RX缓存阈值为深度的1/8' z# n0 F% y7 [/ i
-
7 O" p6 u& ~& F2 v' H4 @ - LL_USART_EnableIT_RXNE_RXFNE(USART2); //使能串口接收中断
( F; K2 I, C* {* F) N5 T: Q - LL_USART_Enable(USART2);' \) z$ m: G* }1 b) A3 P
- }
/ H: c& V: W& Q# z
复制代码 ! d9 F# \, P# {) m% H! k0 h
void USART2_IRQHandler(void)4 F& v0 I+ s3 N; v. k1 _7 M
{
1 X( k* i/ A2 G5 h N4 r u8 data;0 T4 A! s. G: D8 f+ w* }. N9 L0 v5 ~
if (LL_USART_IsActiveFlag_RXNE_RXFNE(USART2)) { //判断接收数据寄存器是否有数据
4 c: @( s* t S# d( W //清除接收中断标志方式一:读取RDR寄存器以自动清除RXNE标志2 Y" y9 Q0 u, P% w
//清除接收中断标志方式二:往RXFRQ寄存器写1(刷新数据)以清除RXNE中断标志
) m- P, K7 P3 `+ Z: G, e% M data = LL_USART_ReceiveData8(USART2); //读接收到的字节,同时相关标志自动清除3 m+ R3 t* E" r% v
LL_USART_RequestRxDataFlush(USART2);
# p' l4 a( q1 J _2 }* q }
' a M |5 E+ K6 j4 r. [}: V$ o# P5 f3 W! ~4 W3 N
, W1 s- r7 u5 ?: [% W
& {+ c. b+ { [2 y( V0 s! G( Y$ a$ B& ?, @) Y$ K* U
|