单片机型号:STM32G030C8T6& [% }: Q- q! d# y
在初始化完串口后,开启串口接收中断,程序就一直在执行串口中断(此时串口无任何数据),通过在线查看串口外设的相关寄存器(如下图)发现RDR寄存器一直没有被清零,导致ISR寄存器的RXNE位一直有效,串口中断就一直处于触发的状态。
5 [ z r7 ?* c) \$ H/ Q
! m+ ~7 d" y7 F4 F$ a+ A- c* U0 ~& B \& A [
通过查看STM32G0x0 Datasheet章节 26.8.10 Bit5 RXNE位,数据收据里面说到可以通过读取RDR寄存器或者往RXFRQ寄存器写1来清除ISR寄存器的RXNE标志位。
* M+ g" Y" v6 U) X8 x6 s* c* w* `2 L9 x% z W# Z4 E* c, \! o
% c0 S9 [0 ] i) V' @! {9 J! P" I1 w
LL库串口初始化及中断接收代码如下:
% D% \- _! K0 i" f8 M. F8 u# k5 w, {- ^( a
- void Usart2_Init(u32 baudrate)
6 M% K, {3 ]; T* B( w - {! ?+ E0 s7 x. ]. M
- LL_USART_DeInit(USART2);
/ [/ Y3 S) g$ t8 ]5 u1 T0 C - LL_USART_InitTypeDef USART_InitStruct = {0};
2 G. i: O& t( U1 d- g - LL_GPIO_InitTypeDef GPIO_InitStruct = {0};+ |/ a) M2 S% l, b
- # A) A4 \3 g( j' o4 H% n
- /* Peripheral clock enable */
2 R' E, d6 x) _4 F% a' ^ - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);! L1 A8 D0 ^* `/ E2 G- R% p5 D
- LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
2 e" R& K9 k6 C8 O7 ~/ B6 R - " U7 L! k J4 o3 ], b
- GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
4 F0 }7 D8 g( c1 {4 v' A9 x! G G: T - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
: V8 d; u8 ?4 @, m1 G3 S2 } - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
, u0 B" Y- B- e7 U% ]! u9 z; P7 a, H" U - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;1 L* ~/ O- k: G1 B; r6 f
- GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
8 }! Z% |% E# M5 q& C - GPIO_InitStruct.Alternate = LL_GPIO_AF_1;8 P8 ^( l d8 p7 `
- LL_GPIO_Init(GPIOA, &GPIO_InitStruct);% Y p( h5 G8 }5 t( p; W
-
4 D& Q( X$ {7 v4 f - GPIO_InitStruct.Pin = LL_GPIO_PIN_3;
, C* t4 N( b9 w - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
$ F# _1 C4 S- Y - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
+ ]/ ~+ @7 I" K% I - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
4 ?! o2 S2 G+ [. x8 J } - GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
( B- J" y+ O% `. c' _ - GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
% @% }+ V* C5 ^4 N - LL_GPIO_Init(GPIOA, &GPIO_InitStruct);1 z# s7 Z/ ~0 d9 @2 A; u
- 4 N+ e. H0 |" h, j
- NVIC_SetPriority(USART2_IRQn, USART_PREPRIORITY);
4 l( O/ ]1 B( V$ Y) ` - NVIC_EnableIRQ(USART2_IRQn);2 o5 l5 y& {& M' |# b. ~! b
-
# |0 d* O) ?4 u6 T. S; \; w' D) T - USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;
x" T% ]+ u Y$ ]/ d4 X4 M w" {1 P - USART_InitStruct.BaudRate = baudrate; //波特率3 a8 x2 J( i! k) s
- USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; //8位数据' H) s L* S" F5 q G
- USART_InitStruct.StopBits = LL_USART_STOPBITS_2; //2位停止位
6 Q# @6 @& x1 G - USART_InitStruct.Parity = LL_USART_PARITY_NONE; //无奇偶校验
K" e) v: e# J$ R/ F - USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
" h% t$ C3 {: P - USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
6 G( Y) z! w' i - USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
7 M# w) X& |! R - LL_USART_Init(USART2, &USART_InitStruct);
# e% V/ f9 M) q) y5 l! |9 H - . c: K; U+ e& k' m
- LL_USART_SetTXFIFOThreshold(USART2, LL_USART_FIFOTHRESHOLD_1_8);//设置TX缓存阈值为深度的1/8$ }# N2 k) z2 L4 G; p6 i5 {$ v' g4 P
- LL_USART_SetRXFIFOThreshold(USART2, LL_USART_FIFOTHRESHOLD_1_8);//设置RX缓存阈值为深度的1/8/ W. u/ `+ Y) M
- 8 E( n# v* Z6 U0 A
- LL_USART_EnableIT_RXNE_RXFNE(USART2); //使能串口接收中断4 w0 Z% R' j) M* \: I
- LL_USART_Enable(USART2);& N9 B: m+ o* D; ~! Z: A# S$ B( b$ `4 i
- }4 U# ~- I# T8 ]2 h* g/ H
复制代码 8 B8 u3 O7 f b
void USART2_IRQHandler(void)
, D ^5 t: h/ I# _{/ p* O$ k: Q# j" s* ?
u8 data;
3 U( c& G9 |, H* o if (LL_USART_IsActiveFlag_RXNE_RXFNE(USART2)) { //判断接收数据寄存器是否有数据+ E) z8 l/ M% j6 R4 R4 m
//清除接收中断标志方式一:读取RDR寄存器以自动清除RXNE标志1 a: z; c1 B% O, r* Q
//清除接收中断标志方式二:往RXFRQ寄存器写1(刷新数据)以清除RXNE中断标志+ P- k; S8 I; X2 H
data = LL_USART_ReceiveData8(USART2); //读接收到的字节,同时相关标志自动清除3 l% `" e- p# y5 H$ V7 m
LL_USART_RequestRxDataFlush(USART2);. K$ u; N! Y9 Y- v' |/ G
}
5 w0 i! S' \9 n8 u- \$ r} i. a( ~. s9 f$ H: h
% C7 F1 \! B* J, V4 b* ]$ M5 D* o# B6 d3 R
, {# D# A. D* b |