STM32串口中断的4种接收数据的实现方式
生活随笔
收集整理的這篇文章主要介紹了
STM32串口中断的4种接收数据的实现方式
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
本例程通過PC機的串口調試助手將數(shù)據(jù)發(fā)送至STM32,接收數(shù)據(jù)后將所接收的數(shù)據(jù)又發(fā)送至PC機。
實例一:
void USART1_IRQHandler(u8 GetData) {u8 BackData;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //中斷產生{ USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中斷標志.GetData = UART1_GetByte(BackData); //也行GetData=USART1->DR; USART1_SendByte(GetData); //發(fā)送數(shù)據(jù)GPIO_SetBits(GPIOE, GPIO_Pin_8 ); //LED閃爍,接收成功發(fā)送完成delay(1000);GPIO_ResetBits(GPIOE, GPIO_Pin_8 );} } ?這是最基本的,將數(shù)據(jù)接收完成后又發(fā)送出去,接收和發(fā)送在中斷函數(shù)里執(zhí)行,main函數(shù)里無其他要處理的。
優(yōu)點:簡單,適合很少量數(shù)據(jù)傳輸。
缺點:無緩存區(qū),并且對數(shù)據(jù)的正確性沒有判斷,數(shù)據(jù)量稍大可能導致數(shù)據(jù)丟失 。
實例二:
void USART2_IRQHandler() {if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中斷產生{ USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中斷標志Uart2_Buffer[Uart2_Rx_Num] = USART_ReceiveData(USART2);Uart2_Rx_Num++;}//判斷最后接收的數(shù)據(jù)是否為設定值,確定數(shù)據(jù)正確性if((Uart2_Buffer[0] == 0x5A)&&(Uart2_Buffer[Uart2_Rx_Num-1] == 0xA5)) Uart2_Sta=1; if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) //溢出{USART_ClearFlag(USART2,USART_FLAG_ORE); //讀SRUSART_ReceiveData(USART2); //讀DR } }if( Uart2_Sta ) {for(Uart2_Tx_Num=0;Uart2_Tx_Num < Uart2_Rx_Num;Uart2_Tx_Num++)USART2_SendByte(Uart2_Buffer[Uart2_Tx_Num]); //發(fā)送數(shù)據(jù)Uart2_Rx_Num = 0; //初始化Uart2_Tx_Num = 0;Uart2_Sta = 0; }這是加了數(shù)據(jù)頭和數(shù)據(jù)尾的接收方式,數(shù)據(jù)頭和尾的個數(shù)可增加,此處只用于調試之用。中斷函數(shù)用于接收數(shù)據(jù)以及判斷數(shù)據(jù)的頭尾,第二個函數(shù)在main函數(shù)里按照查詢方式執(zhí)行。
優(yōu)點:較簡單,采用緩存區(qū)接收,對提高數(shù)據(jù)的正確行有一定的改善 。
缺點:要是第一次數(shù)據(jù)接收錯誤,回不到初始化狀態(tài),必須復位操作 。
實例三:
void USART2_IRQHandler() { if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中斷產生 { USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中斷標志. Uart2_Buffer[Uart2_Rx] = USART_ReceiveData(USART2); Uart2_Rx++; Uart2_Rx &= 0x3F; //判斷是否計數(shù)到最大} if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) //溢出 { USART_ClearFlag(USART2,USART_FLAG_ORE); //讀SR USART_ReceiveData(USART2); //讀DR } }if( Uart2_Tx != Uart2_Rx ) { USART2_SendByte(Uart2_Buffer[Uart2_Tx]); //發(fā)送數(shù)據(jù) Uart2_Tx++; Uart2_Tx &= 0x3F; //判斷是否計數(shù)到最大 } 采用FIFO方式接收數(shù)據(jù),由0x3F可知此處最大接收量為64個,可變,中斷函數(shù)只負責收,另一函數(shù)在main函數(shù)里執(zhí)行,FIFO方式發(fā)送。
優(yōu)點:發(fā)送和接收都很自由,中斷占用時間少,有利于MCU處理其它。
缺點:對數(shù)據(jù)的正確性沒有判斷,一概全部接收。
實例四:?
void USART2_IRQHandler() { if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中斷產生 { USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中斷標志Uart2_Buffer[Uart2_Rx] = USART_ReceiveData(USART2); Uart2_Rx++; Uart2_Rx &= 0xFF; } if(Uart2_Buffer[Uart2_Rx-1] == 0x5A) //頭 Uart2_Tx = Uart2_Rx-1; if((Uart2_Buffer[Uart2_Tx] == 0x5A)&&(Uart2_Buffer[Uart2_Rx-1] == 0xA5)) //檢測到頭的情況下檢測到尾 { Uart2_Len = Uart2_Rx-1- Uart2_Tx; //長度 Uart2_Sta=1; //標志位 } if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) //溢出 { USART_ClearFlag(USART2,USART_FLAG_ORE); //讀SR USART_ReceiveData(USART2); //讀DR } }if( Uart2_Sta ) { for(tx2=0;tx2 <= Uart2_Len;tx2++,Uart2_Tx++) USART2_SendByte(Uart2_Buffer[Uart2_Tx]); //發(fā)送數(shù)據(jù) Uart2_Rx = 0; //初始化 Uart2_Tx = 0; Uart2_Sta = 0; }數(shù)據(jù)采用數(shù)據(jù)包的形式接收,接收后存放于緩存區(qū),通過判斷數(shù)據(jù)頭和數(shù)據(jù)尾(可變)來判斷數(shù)據(jù)的“包”及有效性,中斷函數(shù)用于接收數(shù)據(jù)和判斷頭尾以及數(shù)據(jù)包長度,另一函數(shù)在main函數(shù)里執(zhí)行,負責發(fā)送該段數(shù)據(jù)。
優(yōu)點:適合打包傳輸,穩(wěn)定性和可靠性很有保證,可隨意發(fā)送,自動挑選有效數(shù)據(jù)。
缺點:緩存區(qū)數(shù)據(jù)長度要根據(jù)“包裹”長度設定, 要是多次接收后無頭無尾,到有頭有尾的那一段數(shù)據(jù)恰好跨越緩存區(qū)最前和最后位置時,可能導致本次數(shù)據(jù)丟失,不過這種情況幾乎沒有可能。
實例一:
void USART1_IRQHandler(u8 GetData) {u8 BackData;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //中斷產生{ USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中斷標志.GetData = UART1_GetByte(BackData); //也行GetData=USART1->DR; USART1_SendByte(GetData); //發(fā)送數(shù)據(jù)GPIO_SetBits(GPIOE, GPIO_Pin_8 ); //LED閃爍,接收成功發(fā)送完成delay(1000);GPIO_ResetBits(GPIOE, GPIO_Pin_8 );} } ?這是最基本的,將數(shù)據(jù)接收完成后又發(fā)送出去,接收和發(fā)送在中斷函數(shù)里執(zhí)行,main函數(shù)里無其他要處理的。
優(yōu)點:簡單,適合很少量數(shù)據(jù)傳輸。
缺點:無緩存區(qū),并且對數(shù)據(jù)的正確性沒有判斷,數(shù)據(jù)量稍大可能導致數(shù)據(jù)丟失 。
實例二:
void USART2_IRQHandler() {if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中斷產生{ USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中斷標志Uart2_Buffer[Uart2_Rx_Num] = USART_ReceiveData(USART2);Uart2_Rx_Num++;}//判斷最后接收的數(shù)據(jù)是否為設定值,確定數(shù)據(jù)正確性if((Uart2_Buffer[0] == 0x5A)&&(Uart2_Buffer[Uart2_Rx_Num-1] == 0xA5)) Uart2_Sta=1; if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) //溢出{USART_ClearFlag(USART2,USART_FLAG_ORE); //讀SRUSART_ReceiveData(USART2); //讀DR } }if( Uart2_Sta ) {for(Uart2_Tx_Num=0;Uart2_Tx_Num < Uart2_Rx_Num;Uart2_Tx_Num++)USART2_SendByte(Uart2_Buffer[Uart2_Tx_Num]); //發(fā)送數(shù)據(jù)Uart2_Rx_Num = 0; //初始化Uart2_Tx_Num = 0;Uart2_Sta = 0; }這是加了數(shù)據(jù)頭和數(shù)據(jù)尾的接收方式,數(shù)據(jù)頭和尾的個數(shù)可增加,此處只用于調試之用。中斷函數(shù)用于接收數(shù)據(jù)以及判斷數(shù)據(jù)的頭尾,第二個函數(shù)在main函數(shù)里按照查詢方式執(zhí)行。
優(yōu)點:較簡單,采用緩存區(qū)接收,對提高數(shù)據(jù)的正確行有一定的改善 。
缺點:要是第一次數(shù)據(jù)接收錯誤,回不到初始化狀態(tài),必須復位操作 。
實例三:
void USART2_IRQHandler() { if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中斷產生 { USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中斷標志. Uart2_Buffer[Uart2_Rx] = USART_ReceiveData(USART2); Uart2_Rx++; Uart2_Rx &= 0x3F; //判斷是否計數(shù)到最大} if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) //溢出 { USART_ClearFlag(USART2,USART_FLAG_ORE); //讀SR USART_ReceiveData(USART2); //讀DR } }if( Uart2_Tx != Uart2_Rx ) { USART2_SendByte(Uart2_Buffer[Uart2_Tx]); //發(fā)送數(shù)據(jù) Uart2_Tx++; Uart2_Tx &= 0x3F; //判斷是否計數(shù)到最大 } 采用FIFO方式接收數(shù)據(jù),由0x3F可知此處最大接收量為64個,可變,中斷函數(shù)只負責收,另一函數(shù)在main函數(shù)里執(zhí)行,FIFO方式發(fā)送。
優(yōu)點:發(fā)送和接收都很自由,中斷占用時間少,有利于MCU處理其它。
缺點:對數(shù)據(jù)的正確性沒有判斷,一概全部接收。
實例四:?
void USART2_IRQHandler() { if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中斷產生 { USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中斷標志Uart2_Buffer[Uart2_Rx] = USART_ReceiveData(USART2); Uart2_Rx++; Uart2_Rx &= 0xFF; } if(Uart2_Buffer[Uart2_Rx-1] == 0x5A) //頭 Uart2_Tx = Uart2_Rx-1; if((Uart2_Buffer[Uart2_Tx] == 0x5A)&&(Uart2_Buffer[Uart2_Rx-1] == 0xA5)) //檢測到頭的情況下檢測到尾 { Uart2_Len = Uart2_Rx-1- Uart2_Tx; //長度 Uart2_Sta=1; //標志位 } if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) //溢出 { USART_ClearFlag(USART2,USART_FLAG_ORE); //讀SR USART_ReceiveData(USART2); //讀DR } }if( Uart2_Sta ) { for(tx2=0;tx2 <= Uart2_Len;tx2++,Uart2_Tx++) USART2_SendByte(Uart2_Buffer[Uart2_Tx]); //發(fā)送數(shù)據(jù) Uart2_Rx = 0; //初始化 Uart2_Tx = 0; Uart2_Sta = 0; }數(shù)據(jù)采用數(shù)據(jù)包的形式接收,接收后存放于緩存區(qū),通過判斷數(shù)據(jù)頭和數(shù)據(jù)尾(可變)來判斷數(shù)據(jù)的“包”及有效性,中斷函數(shù)用于接收數(shù)據(jù)和判斷頭尾以及數(shù)據(jù)包長度,另一函數(shù)在main函數(shù)里執(zhí)行,負責發(fā)送該段數(shù)據(jù)。
優(yōu)點:適合打包傳輸,穩(wěn)定性和可靠性很有保證,可隨意發(fā)送,自動挑選有效數(shù)據(jù)。
缺點:緩存區(qū)數(shù)據(jù)長度要根據(jù)“包裹”長度設定, 要是多次接收后無頭無尾,到有頭有尾的那一段數(shù)據(jù)恰好跨越緩存區(qū)最前和最后位置時,可能導致本次數(shù)據(jù)丟失,不過這種情況幾乎沒有可能。
總結
以上是生活随笔為你收集整理的STM32串口中断的4种接收数据的实现方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SM32的USART串口设置
- 下一篇: STM32串口使用详解