歡迎您光臨本站 登入註冊首頁

模擬串口程序

admin @ 2014-03-14 , reply:0

概述

隨著單片機的使用日益頻繁,用其作前置機進行採集和通信也常見於各種應用,一般是利用前置機採集各種終端數據後進行處理、存儲,再主動或被動上報給管理站。這種情況下下,採集會需要一個串口,上報又需要另一個串口……

隨著單片機的使用日益頻繁,用其作前置機進行採集和通信也常見於各種應用,一般是利用前置
機採集各種終端數據後進行處理、存儲,再主動或被動上報給管理站。這種情況下下,採集會需
要一個串口,上報又需要另一個串口,這就要求單片機具有雙串口的功能,但我們知道一般的51
系列只提供一個串口,那麼另一個串口只能靠程序模擬。
本文所說的模擬串口, 就是利用51的兩個輸入輸出引腳如P1.0和P1.1,置1或0分別代表高低電
平,也就是串口通信中所說的位,如起始位用低電平,則將其置0,停止位為高電平,則將其置
1,各種數據位和校驗位則根據情況置1或置0。至於串口通信的波特率,說到底只是每位電平持續
的時間,波特率越高,持續的時間越短。如波特率為9600BPS,即每一位傳送時間為
1000ms/9600=0.104ms,即位與位之間的延時為為0.104毫秒。單片機的延時是通過執行若干條
指令來達到目的的,因為每條指令為1-3個指令周期,可即是通過若干個指令周期來進行延時的,
單片機常用11.0592M的的晶振,現在我要告訴你這個奇怪數字的來歷。用此頻率則每個指令周期
的時間為(12/11.0592)us,那麼波特率為9600BPS每位要間融多少個指令周期呢?
指令周期s=(1000000/9600)/(12/11.0592)=96,剛好為一整數,如果為4800BPS則為
96x2=192,如為19200BPS則為48,別的波特率就不算了,都剛好為整數個指令周期,妙吧。至於
別的晶振頻率大家自已去算吧。
現在就以11.0592M的晶振為例,談談三種模擬串口的方法。

方法一:延時法

    通過上述計算大家知道,串口的每位需延時0.104秒,中間可執行96個指令周期。
#define uchar unsigned char
sbit P1_0 = 0x90;
sbit P1_1 = 0x91;
sbit P1_2 = 0x92;
#define RXD P1_0
#define TXD P1_1
#define WRDYN 44 //寫延時
#define RDDYN 43 //讀延時

//往串口寫一個位元組
void WByte(uchar input)
{
    uchar i=8;
    TXD=(bit)0;                     //發送啟始
λ
    Delay2cp(39);
    //發送8位數據位
    while(i--)
    {
        TXD=(bit)(input&0x01);     //先傳低位
        Delay2cp(36);
        input=input>>1;
    }
    //發送校驗位(無)
    TXD=(bit)1;                     //發送結束
λ
    Delay2cp(46);
}

//從串口讀一個位元組
uchar RByte(void)
{
    uchar Output=0;
    uchar i=8;
    uchar temp=RDDYN;
    //發送8位數據位
Delay2cp(RDDYN*1.5);         //此處注意,等過起始位
    while(i--)
    {
        Output >>=1;
        if(RXD) Output   =0x80;     //先收低位
        Delay2cp(35);             //(96-26)/2,循環共
佔用26個指令周期
    }
    while(--temp)                    //在指定的
時間內搜尋結束位。
    {
        Delay2cp(1);
        if(RXD)break;             //收到結束位便退出
    }
    return Output;
}

//延時程序*
void Delay2cp(unsigned char i)
{
    while(--i);                     //剛好兩個
指令周期。
}

    此種方法在接收上存在一定的難度,主要是採樣定位存在需較準確,另外還必須知道
每條語句的指令周期數。此法可能模擬若干個串口,實際中採用它的人也很多,但如果你用Keil
C,本人不建議使用此種方法,上述程序在P89C52、AT89C52、W78E52三種單片機上實驗通過。

方法二:計數法

    51的計數器在每指令周期加1,直到溢出,同時硬體置溢出標誌位。這樣我們就可以
通過預置初值的方法讓機器每96個指令周期產生一次溢出,程序不斷的查詢溢出標誌來決定是否
發送或接收下一位。
   
//計數器初始化
void S2INI(void)
{
    TMOD =0x02;                //計數器0,方式2
TH0=0xA0;                    //預值為256-96=140,十六進位A0
    TL0=TH0;       

[admin via 研發互助社區 ] 模擬串口程序已經有2669次圍觀

http://cocdig.com/docs/show-post-375.html