* 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
閱讀更多 電子發燒友網 的文章
關鍵字: 中斷 技術 Transmission