新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 中斷方式下進行串口通訊的正確方法

        中斷方式下進行串口通訊的正確方法

        作者: 時間:2016-11-30 來源:網絡 收藏
        一般普遍的把串口通訊分為查詢方式和中斷方式。查詢方式比較容易理解,各種書籍上都介紹的比較清楚。但中斷方式,沒有幾本書講得好的,甚至有些例程根本無法實際應用。
        問題有:
        1,半中斷法。只使用接收中斷,不使用發送中斷,發送時還是依靠查詢中斷標志的辦法;如下:
        ES = 0;//若是接收使用中斷方式,某些單片機需要關中斷。但C51不一定需要。這里只是示例。
        SBUF = needsendchar;
        While (!TI);
        TI = 0;
        ES = 1;
        這里的問題是:發送數據時需要等待數據發完才能繼續其他工作,程序效率降低;發送時需要關中斷,影響數據接收。
        2,接收中斷的處理方法錯誤。如下:
        中斷程序:
        void ser() interrupt 4 {
        RI = 0;
        temp = SBUF; //讀走數據,放入緩存(全局的)變量
        rx_flag = 1; //設置接收標志
        }
        主程序:
        void main(){
        …;//初始化
        While (1) {
        If (rx_flag ==1){//查詢接收標志
        rx_flag = 0; //清楚接收標志
        x = temp; //從暫存變量讀取數據
        …;//接收處理
        }
        …; //其它操作
        }
        }
        這里的問題是:如果串口接收數據的間隔時間小于“接收處理”和“其它操作”所用的時間時,接收數據會丟失一部分。
        正確使用中斷方式處理串口收發應達到以下目的:
        1,完全使用中斷控制接收和發送,以達到最快的收發速度。
        2,接收和發送互不影響,達到全雙工通訊效果。
        3,應用程序不發生等待,以達到最高運行效率。
        正確的中斷發送方法如下:
        1,建立一個足夠大小的環形發送緩沖區,建立一個信號量(用于指示發送的數據量),建立一個發送標志位(用于指示發送狀態)。
        2,應用程序將數據寫入環形發送緩沖區,查詢發送接收標志,若不在發送狀態,手動觸發中斷。
        3,產生發送中斷時,查詢信號量,以判別發送緩沖區內是否有數據;若有,置發送標志位,從緩沖區讀取數據發送,累減信號量;若無,清除發送標志位。
        C51的例程如下:
        //變量定義
        #define BUF_SIZE 0x10//環形收發緩沖區長度
        //發送參數
        char tx_circbuf[BUF_SIZE];//環形發送緩沖區
        uint8 tx_sem;//信號量
        bool tx_run;//發送標志位
        uint8 tx_circin;//進環形緩沖區的位置指示
        uint8 tx_circout;//出環形緩沖區的位置指示
        //發送初始化程序
        void tx_init(void){
        //硬件初始化 略
        //發送參數初始化
        tx_sem = 0;
        tx_run = False;
        tx_circin = 0;
        tx_circout = 0;
        }
        //中斷程序
        void tx_int(void) interrupt 4 {
        if (TI){
        TI = 0;
        if (tx_sem){
        SBUF = tx_circbuf [tx_circout]; // 發送緩沖區中的字符
        if (++tx_circout >= BUF_SIZE) tx_circout = 0;
        tx_sem--;//累減信號量
        tx_run = True;//置發送標志位
        }
        else tx_run = False;//清除發送標志位
        }
        }
        //發送處理程序,由應用程序調用
        //輸入:發送數據指針,發送數據長度
        void tx_data(char * txbuf,uint8 len){
        while (len){
        tx_circbuf [tx_circin] = *txbuf++;// 存入數據到發送緩沖區
        if (++tx_circin >= BUF_SIZE) tx_circin = 0;
        tx_sem++;//累減信號量
        len--;
        if (tx_run == False)TI=1;//查詢發送狀態標志。若發送空閑,觸發中斷,發送數據的工作由中斷程序自動完成。
        }
        }
        正確的中斷接收方法如下:
        1,建立一個足夠大小的環形接收緩沖區,建立一個信號量(用于指示接收的數據量)。
        2,發生接收中斷時,讀出字節放入接收緩沖區,并累加信號量。
        3,應用程序查詢接收標志,如信號量不為0,則從接收緩沖區讀取數據進行處理,累減信號量。
        C51的例程如下:
        //變量定義
        #define BUF_SIZE 0x10//環形收發緩沖區長度
        //接收參數
        char rx_circbuf[BUF_SIZE];// 環形接收緩沖區
        uint8 rx_sem;// 信號量
        uint8 rx_circin;//進環形緩沖區的位置指示
        uint8 rx_circout;//出環形緩沖區的位置指示
        //接收初始化程序
        void rx_init(void){
        //硬件初始化 略
        //接收參數初始化
        rx_sem = 0;
        rx_circin = 0;
        rx_circout = 0;
        }
        //中斷程序
        void rx_int(void) interrupt 4 {
        if (RI){
        RI = 0;
        rx_circbuf [rx_circin] = SBUF;// 讀出字節放入接收緩沖區
        if (++rx_circin >= BUF_SIZE) rx_circin = 0;
        rx_sem++;//累加信號量
        }
        }
        //接收處理程序,由應用程序調用
        //輸出:讀出數據指針;返回:接收到的數據長度
        uint8 rx_data(char * rxbuf){
        uint8 i;
        i = 0;
        while (rx_sem){
        *rxbuf++ = rx_circbuf [rx_circout];// 從接收緩沖區讀取數據
        if (++rx_circout >= BUF_SIZE) rx_circout = 0;
        rx_sem--;//累減信號量
        i++;
        }
        return i;
        }
        上述的收發中斷程序在應用中合并在一起,即:
        void uart_init(void) interrupt 4 {
        if (TI){
        TI = 0;
        …;
        }
        if (RI){
        RI = 0;
        …;
        }
        }
        例程中分開表述,只是為了將流程說得更明白些。
        上述例程中,未包含環形收發緩沖區溢出狀況的處理,需要時自行添加。
        上述例程表明了正確使用中斷方式處理串口通訊的思路。當然程序還可以有其它的寫法,特別是環形緩沖區中數據出入的方法和信號量的用法。如在有操作系統的情況下,上述信號量的使用就可以得到操作系統更好支持。
        完全中斷方式收發數據總結:
        1。數據的收發操作,完全由中斷程序自動進行,可以達到最快的收發速度。即,接收時中斷程序負責把數據放入緩沖區,數據的處理由應用程序另行處理;發送時應用程序直接將數據放入緩沖區,啟動發送中斷后,發送的工作由中斷程序自動完成。
        2。由于發送的工作完全由中斷處理,因此,應用程序將數據放入緩沖區后,就可以繼續運行其它工作,這種“發了不管”的方式極大地提高程序運行效率。
        3。接收數據時,由中斷負責將數據放入緩沖區,再由應用程序處理。應用程序輪詢及處理的時間長短,不會影響接收,就不會導致數據丟失。
        4。由于應用程序中不出現開關中斷的操作,因此,發送和接收互不影響,可以達到全雙工收發的效果。
        期望上述文字能給予大家借鑒,如有差錯,望予指正,謝謝。


        關鍵詞: 中斷方式串口通

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 天峻县| 五河县| 石首市| 瑞金市| 临安市| 四子王旗| 万州区| 八宿县| 阳城县| 长治县| 汤阴县| 瑞安市| 桦南县| 肇东市| 霍林郭勒市| 南岸区| 沁阳市| 梁山县| 怀来县| 左贡县| 新宁县| 卫辉市| 体育| 临朐县| 周至县| 长宁区| 博乐市| 如东县| 阳春市| 福海县| 东至县| 鹤庆县| 松桃| 白山市| 郁南县| 湄潭县| 尼玛县| 静宁县| 新竹县| 兴仁县| 饶平县|