单片机型号:STM32G030C8T6
* ~; y" \# e5 d/ Q; [在初始化完串口后,开启串口接收中断,程序就一直在执行串口中断(此时串口无任何数据),通过在线查看串口外设的相关寄存器(如下图)发现RDR寄存器一直没有被清零,导致ISR寄存器的RXNE位一直有效,串口中断就一直处于触发的状态。
. c3 ?/ Z% c, G, U" N
9 c) K" d3 @! S9 V) _" M9 X' v( S- c9 P3 s
通过查看STM32G0x0 Datasheet章节 26.8.10 Bit5 RXNE位,数据收据里面说到可以通过读取RDR寄存器或者往RXFRQ寄存器写1来清除ISR寄存器的RXNE标志位。
2 P6 C5 |8 F2 G6 q
+ s, \6 ~8 \7 ]/ M- d9 U: @7 |) h- a% b2 s r
8 E* d, Q* M2 B
LL库串口初始化及中断接收代码如下:& J. r# D3 W1 a7 b' X% {
/ A2 Y4 E; L9 j) P& F9 j
- void Usart2_Init(u32 baudrate)' ]) R" a* V- ?& i
- {
0 `; r9 k# f' t - LL_USART_DeInit(USART2);
8 E, E9 y% ]4 Y2 B5 O( s# a' E# I - LL_USART_InitTypeDef USART_InitStruct = {0};: Z1 ?# S1 @# ?& d( }. |3 j
- LL_GPIO_InitTypeDef GPIO_InitStruct = {0};# B7 n! Y& ?; m& |) R1 H
-
6 o& _, G; X d2 g) n- r - /* Peripheral clock enable */6 i' ~! U$ u3 ?0 g( x, _5 \
- LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);+ D! ~! x4 }. I, F" L1 {! w k) c
- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
4 M' |3 v5 ]) l+ d6 X - 0 b& J9 g. z% t9 v" B) Z' H
- GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
; }' l2 c! L) Z3 A' {- N8 ? - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;3 M2 B* T0 X5 W' U. n+ `
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
- L |" B4 Y9 f; g7 F; g - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
: x+ x3 V" P1 m$ `( V. Y - GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;! I/ K7 f# o7 ]5 K7 z4 W- O
- GPIO_InitStruct.Alternate = LL_GPIO_AF_1;& [( Z9 p x/ Q, z9 L/ F
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);) a* A7 j6 o5 C: ~
-
6 c! n! I5 x5 |5 U. _ - GPIO_InitStruct.Pin = LL_GPIO_PIN_3;
$ ^+ W/ o$ u$ f& B, f& L- c - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;0 w; j- ^3 D6 p' i- D0 v
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;* j+ O. H; L# x/ h* y3 i0 C2 U
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
) p* U8 z! @ w+ f6 l" q - GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
4 K- m0 A) t+ ?5 q - GPIO_InitStruct.Alternate = LL_GPIO_AF_1; W! i" l/ M. o- G0 G8 L
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);: N, A& k3 p7 s# K. J( b
-
5 h3 |0 a& d( U3 x0 q3 |+ k - NVIC_SetPriority(USART2_IRQn, USART_PREPRIORITY);: {" ?2 ?$ y2 V& l2 J% U
- NVIC_EnableIRQ(USART2_IRQn);8 h& M! [6 G7 g! I/ Y/ E3 \2 V
-
4 J. I$ Q5 a" V- n0 q* c8 B - USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;1 |8 |/ w- _' s# c6 v
- USART_InitStruct.BaudRate = baudrate; //波特率
" y! I1 I( [/ A+ R" v) L2 f - USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; //8位数据
2 v* l! c1 D6 T. }) G+ R - USART_InitStruct.StopBits = LL_USART_STOPBITS_2; //2位停止位5 S$ `' u; B1 X" S, G( I9 u R( s
- USART_InitStruct.Parity = LL_USART_PARITY_NONE; //无奇偶校验
6 ]; T: M$ ^8 l! S ^# }( V: [ - USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;4 U2 Y" H" |; B8 R9 z2 u0 B4 D
- USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
/ r! x. n) u; e5 N - USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;% x( s: {; T' i( M/ R3 u
- LL_USART_Init(USART2, &USART_InitStruct);
" E v& V; A, R8 P -
, c) N, t8 z2 x0 Y, d/ U2 y - LL_USART_SetTXFIFOThreshold(USART2, LL_USART_FIFOTHRESHOLD_1_8);//设置TX缓存阈值为深度的1/8
& X% n6 ~5 i0 a- _* Q$ ~9 ` - LL_USART_SetRXFIFOThreshold(USART2, LL_USART_FIFOTHRESHOLD_1_8);//设置RX缓存阈值为深度的1/8
$ v* I- \3 q/ c) s" P5 z - 9 \+ c& m& j# [+ B& u9 S A
- LL_USART_EnableIT_RXNE_RXFNE(USART2); //使能串口接收中断
/ V1 L1 ], c5 P; d% U) J: o - LL_USART_Enable(USART2);
7 y& K. t. H: \& `' x - }2 D( B$ v) t9 m# s2 e6 y
复制代码 2 N+ N$ t- d. X% i
void USART2_IRQHandler(void)1 l+ f& y" s6 O' l5 w% U6 ^
{/ Q- g' V' o q2 o& F8 z
u8 data;3 { {! M' m5 A: c( m
if (LL_USART_IsActiveFlag_RXNE_RXFNE(USART2)) { //判断接收数据寄存器是否有数据
$ T: V+ L% t3 Z2 g //清除接收中断标志方式一:读取RDR寄存器以自动清除RXNE标志% M9 u$ C5 L! \, m) u
//清除接收中断标志方式二:往RXFRQ寄存器写1(刷新数据)以清除RXNE中断标志) G4 O* G, x- d- f
data = LL_USART_ReceiveData8(USART2); //读接收到的字节,同时相关标志自动清除2 ^' Y( ]- W+ d; K( I
LL_USART_RequestRxDataFlush(USART2);1 Z" N$ g% y. U* A1 Y6 O
}. a0 ^( ]7 g1 _1 G; v
}
& Z# l) j9 \) e9 A' A- t4 y" x: V, b' B
$ {7 \* F3 c1 Y8 O) Q
4 e# x" m! Q' Y4 r0 j
|