新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 51單片機串口問題

        51單片機串口問題

        作者: 時間:2016-11-25 來源:網絡 收藏
        51單片機的串口,是個全雙工的串口,發送數據的同時,還可以接收數據。
        當串行發送完畢后,將在標志位 TI 置 1,同樣,當收到了數據后,也會在 RI 置 1。
        無論 RI 或 TI 出現了 1,只要串口中斷處于開放狀態,單片機都會進入串口中斷處理程序。
        在中斷程序中,要區分出來究竟是發送引起的中斷,還是接收引起的中斷,然后分別進行處理。
        看到過一些書籍和文章,在串口收、發數據的處理方法上,很多人都有不妥之處。
        接收數據時,基本上都是使用“中斷方式”,這是正確合理的。
        即:每當收到一個新數據,就在中斷函數中,把 RI 清零,并用一個變量,通知主函數,收到了新數據。
        發送數據時,很多的程序都是使用的“查詢方式”,就是執行 while(TI ==0); 這樣的語句來等待發送完畢。
        這時,處理不好的話,就可能帶來問題。
        看了一些網友編寫的程序,發現有如下幾條容易出錯:
        1.有人在發送數據之前,先關閉了串口中斷!等待發送完畢后,再打開串口中斷。
        這樣,在發送數據的等待期間內,如果收到了數據,將不能進入中斷函數,也就不會保存的這個新收到的數據。
        這種處理方法,就會遺漏收到的數據。
        2.有人在發送數據之前,并沒有關閉串口中斷,當 TI = 1 時,是可以進入中斷程序的。
        但是,卻在中斷函數中,將 TI 清零!
        這樣,在主函數中的while(TI ==0);,將永遠等不到發送結束的標志。
        3.還有人在中斷程序中,并沒有區分中斷的來源,反而讓發送引起的中斷,執行了接收中斷的程序。
        對此,做而論道發表自己常用的方法:
        接收數據時,使用“中斷方式”,清除 RI 后,用一個變量通知主函數,收到新數據。
        發送數據時,也用“中斷方式”,清除 TI 后,用另一個變量通知主函數,數據發送完畢。
        這樣一來,收、發兩者基本一致,編寫程序也很規范、易懂。
        更重要的是,主函數中,不用在那兒死等發送完畢,可以有更多的時間查看其它的標志。


        實例:
        求一個PC與單片機串口通信的程序,要求如下:
        1、如果在電腦上發送以$開始的字符串,則將整個字符串原樣返回(字符串長度不是固定的)。
        2、如果接收到1,則將P10置高電平,接收到0,P10置低電平。(用來控制一個LED
        單片機是STC89C52RC/晶振11.0592/波特率要求是9600或4800。謝謝!
        問題補充:可能會將【$ABCD,123456,987654ccc,aasdasd,aaaa,sssd,4D】這樣的字符串(字符串長度約為50-150個字符)傳送給單片機,只能能原樣返回。

        最佳答案:
        下列程序,已經調試成功。
        #include
        sbit LED = P1^0;
        unsigned char UART_buff;
        bit New_rec = 0, Send_ed = 1, Money = 0;
        //----------------------------------------------
        void main (void)
        {
        SCON = 0x50; //串口方式1, 8-n-1, 允許接收.
        TMOD = 0x20; //T1方式2
        TH1 = 0xFD; [url=]//9600bps@11.0592MHz[/url]
        TL1 = 0xFD;
        TR1 = 1;
        ES= 1; //開中斷.
        EA= 1;
        while(Money == 0); //等著交費,呵呵,等著接收$.
        while(1){
        if ((New_rec == 1) && (Send_ed == 1)){//如果收到新數據及發送完畢
        SBUF = UART_buff; //那就發送.
        New_rec = 0;
        Send_ed = 0;
        } }
        }
        //----------------------------------------------
        void ser_int (void) interrupt 4
        {
        if(RI == 1) {//如果收到.
        RI = 0; //清除標志.
        New_rec = 1;
        UART_buff = SBUF;//接收.
        if(UART_buff == 1)LED = 1;
        if(UART_buff == 0)LED = 0;
        if(UART_buff == $)Money = 1;
        }
        else{ //如果送畢.
        TI = 0; //清除標志.
        Send_ed = 1;
        }
        }
        //----------------------------------------------


        關鍵詞: 51單片機串口問

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 三河市| 普兰县| 通州区| 嵩明县| 县级市| 平舆县| 镇平县| 宁乡县| 天津市| 镇沅| 泸西县| 昆明市| 信宜市| 宜宾市| 都江堰市| 临泉县| 瑞安市| 平谷区| 万源市| 天长市| 喀喇| 班戈县| 明水县| 奉贤区| 连州市| 乌拉特中旗| 中阳县| 浏阳市| 师宗县| 黎城县| 武夷山市| 普宁市| 剑川县| 邢台市| 开化县| 昌乐县| 金溪县| 博兴县| 朝阳县| 磴口县| 旅游|