新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32串口中斷接收方式詳細比較

        STM32串口中斷接收方式詳細比較

        作者: 時間:2016-11-26 來源:網絡 收藏
        本例程通過PC機的串口調試助手將數據發送至STM32,接收數據后將所接收的數據又發送至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);//發送數據
        GPIO_SetBits(GPIOE, GPIO_Pin_8 ); //LED閃爍,接收成功發送完成
        delay(1000);
        GPIO_ResetBits(GPIOE, GPIO_Pin_8 );
        }
        }
        這是最基本的,將數據接收完成后又發送出去,接收和發送在中斷函數里執行,main函數里無其他要處理的。
        優點:簡單,適合很少量數據傳輸。
        缺點:無緩存區,并且對數據的正確性沒有判斷,數據量稍大可能導致數據丟失


        實例二:
        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++;
        }

        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);//讀SR
        USART_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]); //發送數據

        Uart2_Rx_Num = 0; //初始化
        Uart2_Tx_Num = 0;
        Uart2_Sta = 0;
        }
        這是加了數據頭和數據尾的接收方式,數據頭和尾的個數可增加,此處只用于調試之用。中斷函數用于接收數據以及判斷數據的頭尾,第二個函數在main函數里按照查詢方式執行。
        優點:較簡單,采用緩存區接收,對提高數據的正確行有一定的改善 。
        缺點:要是第一次數據接收錯誤,回不到初始化狀態,必須復位操作 。

        實例三:
        vvoid 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; //判斷是否計數到最大
        }
        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]); //發送數據
        Uart2_Tx++;
        Uart2_Tx &= 0x3F; //判斷是否計數到最大
        }
        采用FIFO方式接收數據,由0x3F可知此處最大接收量為64個,可變,中斷函數只負責收,另一函數在main函數里執行,FIFO方式發送。
        優點:發送和接收都很自由,中斷占用時間少,有利于MCU處理其它。
        缺點:對數據的正確性沒有判斷,一概全部接收。

        實例四:
        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]); //發送數據
        Uart2_Rx = 0; //初始化
        Uart2_Tx = 0;
        Uart2_Sta = 0;
        }

        數據采用數據包的形式接收,接收后存放于緩存區,通過判斷數據頭和數據尾(可變)來判斷數據的“包”及有效性,中斷函數用于接收數據和判斷頭尾以及數據包長度,另一函數在main函數里執行,負責發送該段數據。
        優點:適合打包傳輸,穩定性和可靠性很有保證,可隨意發送,自動挑選有效數據。
        缺點:緩存區數據長度要根據“包裹”長度設定, 要是多次接收后無頭無尾,到有頭有尾的那一段數據恰好跨越緩存區最前和最后位置時,可能導致本次數據丟失,不過這種情況幾乎沒有可能。


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 玛沁县| 象州县| 霍邱县| 平南县| 阜阳市| 社会| 通许县| 防城港市| 鸡东县| 布拖县| 砚山县| 宝清县| 金山区| 永泰县| 政和县| 潜山县| 定南县| 邳州市| 赤城县| 巨鹿县| 邢台市| 四川省| 阳山县| 淮南市| 滦南县| 六盘水市| 阳春市| 桦甸市| 宾川县| 临沭县| 西贡区| 大丰市| 茂名市| 昌吉市| 湘乡市| 大姚县| 沙湾县| 建平县| 无锡市| 长岛县| 莱芜市|