「STM32」關於UART2發送後中斷常犯錯誤大全,你中招了嗎?

* Input : None

* Output : None

* Return : None

*********/

void USART1_IRQHandler(void)

{

if( USART_GetITStatus(USART1, USART_IT_TC) == SET )

{

if( *pDataByte == ‘\0’ )//TC需要 讀SR+寫DR 方可清0,當發送到最後,到‘\0’的時候用個if判斷關掉

USART_ClearFlag(USART1, USART_FLAG_TC);//不然TC一直是set, TCIE也是打開的,導致會不停進入中斷。 clear掉即可,不用關掉TCIE

else

USART_SendData(USART1, *pDataByte++ );

其中u8 *pDataByte;是一個外部指針變量

在中斷處理程序中,發送完該字符串後,不用關閉TC的中斷使能TCIE,只需要清掉標誌位TC;這樣就能避免TC == SET 導致反覆進入中斷了。

這裡請問一個問題:開TC中斷USART_ITConfig如果放在我的USART_SendDataString中再開,會丟失字符串的第一字節。必須放在串口初始化函數中才不會丟。不知道為什麼?

這裡筆者可以給出解釋,你看下SECTION1 就可以知道為什麼呢,你這樣做的原理和SECTION1講解的差不多,就相當於延時,而你後面沒有丟失數據的主要原因就是你代碼中有這麼一句 USART_ClearFlag(USART1, USART_FLAG_TC);//清除傳輸完成標誌位,否則可能會丟失第1個字節的數據。網友提供。

再說判斷TXE。即Tx DR Empty,發送寄存器空。當使能TXEIE後,只要Tx DR空了,就會產生中斷。所以,發送完字符串後必須關掉,否則會導致重複進入中斷。這也是和TC不同之處。

發送函數如下:

USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//只要發送寄存器為空,就會一直有中斷,因此,要是不發送數據時,把發送中斷關閉,只在開始發送時,才打開。

}

中斷處理函數如下:

********/

if( USART_GetITStatus(USART1, USART_IT_TXE) == SET )

{

if( *pDataByte == ‘\0’ )//待發送的字節發到末尾了

USART_ITConfig(USART1, USART_IT_TXE, DISABLE);//因為是 發送寄存器空 的中斷,所以發完字符串後必須關掉,否則只要空了,就會進中斷

在串口初始化函數中就不用打開TXE的中斷了(是在發送函數中打開的)如下:

/************

名稱: USART_Config

功能: 設置串口參數

輸入: 無

輸出: 無

返回: 無

************/

void USART_Config

{

USART_InitTypeDef USART_InitStructure;//定義一個包含串口參數的結構體

USART_InitStructure.USART_BaudRate = 9600; //波特率9600

USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位數據位

USART_InitStructure.USART_StopBits = USART_StopBits_1;//1位停止位

USART_InitStructure.USART_Parity = USART_Parity_No;//無校驗

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件流控制

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//輸入加輸出模式

USART_InitStructure.USART_Clock = USART_Clock_Disable;//時鐘關閉

USART_InitStructure.USART_CPOL = USART_CPOL_Low;

USART_InitStructure.USART_CPHA = USART_CPHA_2Edge;

USART_InitStructure.USART_LastBit = USART_LastBit_Disable;

USART_Init(USART1, &USART_InitStructure);//設置到USART1

USART_Cmd(USART1, ENABLE); //使能USART1


分享到:


相關文章: