新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 關于模擬串口的波特率的分析研究

        關于模擬串口的波特率的分析研究

        作者: 時間:2016-11-18 來源:網絡 收藏
        (聲明:本程序是以網上下載程序為基礎,并根據需要做了適當修改得來的)
        在用單片機開發各種嵌入式應用系統中,由于異步串行通訊連接簡單,因而成為經常用到的一種通信模式,很多應用中還要求實現多路異步串行通信。為了提高系統的性能價格比,就要求設計工程師用軟件增加實現一路或多路異步串行通信。本文即是對模擬串口波特率做出的一點分析。
        首先簡單的介紹一下串行異步通訊的數據格式定義,發送或接收一個完整的字節信息,必須有“起始位”、“若干數據位”、“奇偶校驗位”和“停止位”;定義每位信息的時間寬度——每秒發送的信息位個數,即為“波特率”。本文附帶的模擬串口源程序采用數據幀的格式為 1位起始位(低電平),8位數據位(先低位在高位),1位停止位(高電平),且在線路空閑狀態時總是保持為高電平。當在11M晶振時鐘頻率下,采用波特率為9600或19200時。該模擬串口都可以無誤差的進行傳輸,具體分析后面進行。
        參照源程序,我們知道,在這個模擬串口設計中,模擬的是單片機串行異步通訊方式1,由P1^0做接收端,P1^1做發送端,通過定時器1定時溢出中斷來確定每位數據的時間,由StartBitOn()函數不斷查詢接收端的狀態,當出現低電平(即起始位)的時候,調用接收程序,接收發送的數據。
        針對以下附帶的源程序分析知,PGetChar(),PSendChar()都是通過移位方式來接收數據,每接收一位數據,需要定時器溢出產生中斷一次,故要得到一幀的數據,就必須經過10個數據位的時間才能完成,同樣的,在模擬串口的發送端,要完整的發送一幀數據也要經過10個數據位的時間。因而在如下連接時,引出了以下的問題。
        當RS232單次發送一個字符時,可以正常接收和發送回RS232。
        當RS232連續發送一串字符時,通過模擬串口返回給RS232的字符只有原來的一半。如發送1234567890這樣一個字符串時,接收的字符為13579。
        那為什么在單獨發送一個字符是不會丟失,而連續發送時就只有原來的一半了呢!
        __________________________________________
        ||||
        ||||
        | PC|---------->| PGetChar()|
        |RS232|||MCU|
        |||V|
        ||<----------| PSendChar()|
        --------------------------------------------
        源程序:
        /**********************************************
        IO 口模擬232串行異步通訊程序

        **********************************************/
        #include
        sbit BT_SND =P1^1;
        sbit BT_REC =P1^0;

        #define F_TM F0//自定義標志位,作為中斷標志位
        #define TIMER0_ENABLETL0=TH0; TR0=1;//TR0 = 1,啟動T
        #define TIMER0_DISABLE TR0=0;

        // Acc 累加器做發送的移位寄存器
        sbit ACC0 = ACC^0;
        sbit ACC1 = ACC^1;
        sbit ACC2 = ACC^2;
        sbit ACC3 = ACC^3;
        sbit ACC4 = ACC^4;
        sbit ACC5 = ACC^5;
        sbit ACC6 = ACC^6;
        sbit ACC7 = ACC^7;

        //定時器計數器0的中斷
        void IntTimer0() interrupt 1
        {
        F_TM=1;
        }
        //發送一個字符
        //數據格式一個啟動位(0),8數據位,一個停止位(1)
        void PSendChar(unsignedCHARGetch)
        {
        ACC=Getch;
        F_TM=0;
        BT_SND=0; //啟動位
        TIMER0_ENABLE; //記數器0啟動
        while(!F_TM) ;
        BT_SND=ACC0; //先送出低位
        F_TM=0;
        while(!F_TM) ;
        BT_SND=ACC1;
        F_TM=0;
        while(!F_TM);
        BT_SND=ACC2;
        F_TM=0;
        while(!F_TM);
        BT_SND=ACC3;
        F_TM=0;
        while(!F_TM);
        BT_SND=ACC4;
        F_TM=0;
        while(!F_TM);
        BT_SND=ACC5;
        F_TM=0;
        while(!F_TM);
        BT_SND=ACC6;
        F_TM=0;
        while(!F_TM);
        BT_SND=ACC7;
        F_TM=0;
        while(!F_TM);
        BT_SND=1;
        F_TM=0;
        while(!F_TM);
        TIMER0_DISABLE; //停止timer
        }
        //接收一個字符
        unsignedCHARPGetChar()
        {
        unsignedCHARrch,ii;
        TIMER0_ENABLE;
        F_TM=0;
        ii=0;
        rch=0;
        while(!F_TM); //等過起始位

        while(ii<8)
        {
        rch>>=1;
        if(BT_REC)
        {
        rch|=0x80;
        }
        ii++;
        F_TM=0;
        while(!F_TM);

        }
        F_TM=0;
        while(!F_TM)
        {
        if(BT_REC)
        {
        break;
        }
        }
        TIMER0_DISABLE; //停止timer
        return rch;

        }
        //檢查是不是有起始位
        bit StartBitOn()
        {
        return(BT_REC==0);

        }
        void main()
        {
        unsignedCHARGetch;

        TMOD=0x22; /*定時器1為工作模式2(8位自動重裝),0為模式2(8位
        自動重裝) */
        PCON=00;
        TR0=0; //在發送或接收才開始使用
        TF0=0;
        TH0=(256-96); //9600bps 就是 1000000/9600=104.167微秒 執行的
        //時間是104.167*11.0592/12= 96
        TL0=TH0;
        ET0=1;//定時器/記數器T0的溢出中斷允許位,ET,允 許中斷
        EA=1;
        while(1)
        {

        if(StartBitOn())
        {
        Getch=PGetChar();
        PSendChar(Getch);
        }
        }
        }
        實驗環境:
        串口調試助手軟件
        AT89S51單片機及相應的硬件設備


        關鍵詞: 模擬串口波特

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 绿春县| 宝坻区| 哈密市| 麦盖提县| 招远市| 大化| 扬中市| 芒康县| 房山区| 金湖县| 分宜县| 五河县| 庄河市| 河东区| 辽阳市| 北川| 冕宁县| 无棣县| 临颍县| 丹阳市| 微博| 古丈县| 丽水市| 永登县| 灌阳县| 阿坝| 武城县| 长治市| 赤壁市| 营口市| 邵武市| 定日县| 焉耆| 潮州市| 安平县| 台安县| 浙江省| 西乌珠穆沁旗| 肃宁县| 苏尼特左旗| 余江县|