单片机型号:STM32G030C8T6
! W! C3 m, i$ z. ?1 s在初始化完串口后,开启串口接收中断,程序就一直在执行串口中断(此时串口无任何数据),通过在线查看串口外设的相关寄存器(如下图)发现RDR寄存器一直没有被清零,导致ISR寄存器的RXNE位一直有效,串口中断就一直处于触发的状态。+ C% N5 L( W/ |8 W [5 {
5 O% D, x @# }; A. v# G+ w
, Z' S0 p% L) a& ^9 f) B% y' d! E通过查看STM32G0x0 Datasheet章节 26.8.10 Bit5 RXNE位,数据收据里面说到可以通过读取RDR寄存器或者往RXFRQ寄存器写1来清除ISR寄存器的RXNE标志位。4 s$ Q' I' H! g( m
# k* \; F) p+ g0 j2 y+ K7 P( w x
* ~) A- j6 G' ~+ {: g8 b; J7 s" w- A) Z. E6 T9 ^
LL库串口初始化及中断接收代码如下:9 V, Y, {7 G+ Y9 i: |
) @7 W( `; h4 ^- K: s8 l
- void Usart2_Init(u32 baudrate)( @" o# z3 o4 g3 m
- {
V+ s; S4 Y# g - LL_USART_DeInit(USART2);
6 o- H1 S! C6 n$ C - LL_USART_InitTypeDef USART_InitStruct = {0};! [5 K3 c4 Y# e7 n) E2 z" R9 O$ l
- LL_GPIO_InitTypeDef GPIO_InitStruct = {0};( k) Q2 t$ \) Y
- * G. \6 o4 g- |/ l
- /* Peripheral clock enable */4 N0 u9 r6 a2 Q8 k- t
- LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);
7 G5 z+ X& T1 _ - LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
" ^. _7 T5 N- [2 e: s- Q% v1 P: ?% e - $ x# y2 T3 l$ ]; i8 k
- GPIO_InitStruct.Pin = LL_GPIO_PIN_2;. k& N o; p; b" y* n" h8 u9 E6 s. U0 _
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
% G0 w/ G9 q2 u- n2 v: n - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;- r- V( G0 p: q7 X' A
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
: ?: b- s8 u! k$ i( ~: b - GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
6 s: a7 `" i. l - GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
' t$ a" l. `# ]. b4 _4 _; e( H9 v% d - LL_GPIO_Init(GPIOA, &GPIO_InitStruct);% M* S7 J. n0 G5 b8 y$ F; f' _1 ]
-
, T$ C0 F& D8 k0 Q - GPIO_InitStruct.Pin = LL_GPIO_PIN_3;. d' o+ U. P3 {8 K) u* o
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
8 U" Y9 }! z4 { - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;" ]! z. {/ s8 A; e9 W5 t
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;: u# J! N7 G& X& f
- GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
) Z( o; y1 _: H - GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
6 m+ L8 d8 k/ |) E: ~9 i: m. P - LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+ _0 j! Q& \2 B/ F -
! F) F4 R# O4 _. s5 z) P - NVIC_SetPriority(USART2_IRQn, USART_PREPRIORITY);
* G+ X ^( M) [/ L' P% p - NVIC_EnableIRQ(USART2_IRQn);3 J" n4 n# Y9 M! Q, { n
- ( S# H+ |& j% s9 C% ^
- USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;+ d2 q3 z% c1 x7 y" N& @9 Z
- USART_InitStruct.BaudRate = baudrate; //波特率7 C- O* M3 r/ q0 j0 P8 S$ G0 b
- USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; //8位数据
$ O( Z3 N! F& v! p& @ - USART_InitStruct.StopBits = LL_USART_STOPBITS_2; //2位停止位
5 s4 [8 X1 B7 { @ - USART_InitStruct.Parity = LL_USART_PARITY_NONE; //无奇偶校验# S* d% h: G- F$ y# V0 R: H
- USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
3 D5 {7 ~( ?7 Z) {! h. y5 T - USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;% K A1 b8 r0 W' Z M
- USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
. J% q/ E, Q" a/ f, { - LL_USART_Init(USART2, &USART_InitStruct);
$ J8 P* o4 ~1 p [; V" Z - # j. T" Y' `4 X# P: q1 }: H
- LL_USART_SetTXFIFOThreshold(USART2, LL_USART_FIFOTHRESHOLD_1_8);//设置TX缓存阈值为深度的1/8
% J0 e+ X- N; [ - LL_USART_SetRXFIFOThreshold(USART2, LL_USART_FIFOTHRESHOLD_1_8);//设置RX缓存阈值为深度的1/8) M6 ?% [3 W9 O) s# A4 D- ~8 S( Q
- ; Z8 n, |3 W7 I8 U
- LL_USART_EnableIT_RXNE_RXFNE(USART2); //使能串口接收中断% F5 y1 ^8 l6 j# i5 Y: e+ z, a% Z
- LL_USART_Enable(USART2);, d, \: J4 F. h# I1 S6 W
- }# a( c: N/ \0 u3 \+ I
复制代码
- n, G2 g8 m) v; i Xvoid USART2_IRQHandler(void)
* ^/ U2 Y4 X, X& j( `: ^{
6 h- v K) `7 z1 Q% ]* ^! O* C u8 data;" m6 N* h3 G# E
if (LL_USART_IsActiveFlag_RXNE_RXFNE(USART2)) { //判断接收数据寄存器是否有数据
5 \2 ^2 b- P/ r* j$ \ //清除接收中断标志方式一:读取RDR寄存器以自动清除RXNE标志, Z* T. z$ I" j" y
//清除接收中断标志方式二:往RXFRQ寄存器写1(刷新数据)以清除RXNE中断标志: E/ [0 T, a, B) O* ]/ C
data = LL_USART_ReceiveData8(USART2); //读接收到的字节,同时相关标志自动清除
2 s4 ~% V2 [, \$ G6 `' Z" S* U LL_USART_RequestRxDataFlush(USART2);8 t5 `( [/ D& Q! H; E% t
}% J0 K2 v/ m, x% ^2 O" v/ H# I
}
1 R/ B' ~! A6 E. x( m: [5 O2 q! I9 ?6 S+ X0 W+ P
" G5 N) ?2 b; w1 _+ K
/ b, p8 A1 k& K$ x o
|