久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

模擬串口自動測量波特率的單片機(jī)程序

作者:萬致遠(yuǎn)   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時間:2012年07月27日   【字體:

我這個程序能夠測量串口的波特率,并且將自身的波特率設(shè)置到通訊波特率。
這個在STC89C52/STC15F104(其實(shí)主要針對STC15F104,因?yàn)樗鼪]有串口)上面通過。不過因?yàn)槭悄M串口,在11.0592 12T的情況下,最多到19200。
然后在STC15F104上面,要適量的減少補(bǔ)償值……
順便說一句,編譯器建議使用sdcc。keil的SB printf函數(shù)搞死我了……在22.1184 6T的情況下大約能到57600.
當(dāng)然在STC15F系列到115200毫無壓力,可是是半雙工的。要做全雙工只能減倍波特率……
測量波特率的方法很簡單。校準(zhǔn)他的波特率的方法就是發(fā)送沒有連續(xù)低電平的字符,類似0x55/0xff/0x7f之類的。使用這個特性還可以將它用在STC自動冷啟動下載器中。不過注意要限制校準(zhǔn)波特率。否則你的正常串口通訊可能會被干擾,因?yàn)槟惚热?15200通訊的時候,正好波形類似57600的7F,校準(zhǔn)上去了把你的連接掐了,估計(jì)很多人都會看看程序是不是跑飛了……所以一定要把同步波特率降到4800以下,因?yàn)镾TC-ISP的默認(rèn)最低波特率是從1200~4800.
這個也可以適用于不準(zhǔn)晶振的單片機(jī)和計(jì)算機(jī)通訊。方法就是計(jì)算機(jī)以不同波特率發(fā)送校準(zhǔn)信號,找出誤碼率最低的波特率,然后發(fā)送確認(rèn),讓單片機(jī)在這個重載值下運(yùn)行,也適用于時鐘速度可能變化的單片機(jī)/懶得計(jì)算重載值的人使用。
然后低于4800的波特率在11.0592的速度下面只能分頻,這也是不得已的……
上代碼:

/*
* 自適應(yīng)波特率模擬串口程序,
* BY 萬致遠(yuǎn)@rwzy.co.cc
* CRYSTAL:任意
*/
#include <hwconfig.h>
#include <type-def.h>
#include <stdio.h>
#define MIS_0 0
#define MIS_2 1
#define MIS_4 2
#define MIS_8 3
#define MIS_16 4
#define TX1 P1_0 //發(fā)送數(shù)據(jù)端口
#define RX1 P1_1 //接收數(shù)據(jù)端口
BYTE min_mode;//減倍模式
void WaitTF1()
{
    while(!TF1);
    TF1=0;
    if(min_mode==MIS_2)
    {// /2
        while(!TF1);
        TF1=0;
    }
    else if(min_mode == MIS_4)
    {// /4
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
    }
    else if(min_mode == MIS_8)
    {// /8
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
    }
    else if(min_mode == MIS_16)
    {// /16
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
        while(!TF1);
        TF1=0;
    }
}

void WByte(BYTE out)
{
    //發(fā)送啟始位
    BYTE i=8;
    BYTE tmp=out;
    TR1=1;//開定時器
    TX1=0;
    WaitTF1();
    //發(fā)送8位數(shù)據(jù)位
    while(i--)
    {
        TX1=(tmp&0x01);     //先傳低位
        tmp=tmp>>1;
        WaitTF1();
    }
    //發(fā)送校驗(yàn)位(無)
    //發(fā)送結(jié)束位
    TX1=1;
    WaitTF1();
    TR1=0;
}   
void putchar(char ch)
{
    WByte(ch);
}
BYTE RByte()
{
    BYTE in=0;
    BYTE cnt;
    while(RX1==1);//等待RXD變低,啟動定時器,這個是阻塞模式
    TR1=1;//同步開定時器//這里……
    //while(!TF1);
    //TF1=0;   
    WaitTF1();
    if(min_mode !=0)
    {
        while(!TF1);//注意這里的周期稍微長。要補(bǔ)償
        TF1=0;
    }
    for(cnt=0;cnt<8;cnt++)
    {
        in=in >>1;//從高移到低
        if(RX1==1) in = in | 0x80;//如果RXD=1,則最高置位
        WaitTF1();//等待一位過去
    }
    while(!TF1);//注意這里的周期稍微長。要補(bǔ)償
    TF1=0;
    TR1=0;//關(guān)閉定時器
    return in;
}

UINT f_Test(void)//測試脈寬
{
    TMOD=0x10;//設(shè)置計(jì)數(shù)器1為方式一計(jì)數(shù)器模式
    TH1=0;
    TL1=0;//定時器CLR
    while(!RX1);//等待頻率腳變高,這個是測低電平的
    while(RX1);//等待腳變低,更換符號可以測正脈沖
    TR1=1;//開啟定時器
    while(!RX1);//等待變高
    TR1=0;//停止計(jì)數(shù)
    //cyc=TH0<<8;
    //cyc=cyc+TL0;
    return (TH1<<8)+TL1;
}
void baud_t()
{
    BYTE k;//復(fù)用變量
    ULONG frq=0; //周期變量
    for(k=0;k<5;k++)// 變量復(fù)用大法
    {
        frq=frq+f_Test();//測試
    }//測量5次取平均
    frq=frq/5;
    if(frq<0xff)
    {
        k=0x100-(frq&0xff);
        min_mode=MIS_0;
    }
    else
    {
        if(frq / 2 < 0xff)
        {//2400baud
            k=0x100-((frq/2)&0xff); //2分頻
            min_mode=MIS_2;
        }
        else if(frq / 4 < 0xff)
        {//1200baud
            k=0x100-((frq/4)&0xff);//4分頻
            min_mode=MIS_4;
        }
        else if(frq / 8 < 0xff)
        {//1200baud
            k=0x100-((frq/8)&0xff);//8分頻
            min_mode=MIS_8;
        }
        else if(frq / 16 < 0xff)
        {//1200baud
            k=0x100-((frq/16)&0xff);//16分頻
            min_mode=MIS_16;
        }
    }
    if(k > 0x50)
    {
        k=k+6;//加補(bǔ)償,因?yàn)閕f語句讓機(jī)器周期加長
        //如果對于STC的新MCU,這里要按照情況調(diào)整
    }
    TMOD=0x20;//設(shè)置定時器1為自動裝載模式
    TH1=k;//載入新波特率
    TL1=k;
}
void main()
{
    while(1)
    {
        baud_t();//測量波特率,阻塞模式
        printf("Hello world!\n");
        printf("Here:mode=%d,T1=0x%X\r\n",min_mode,TH1);//這里如果你要使用keil請自己寫字符串發(fā)送函數(shù),和sprintf配合使用
        printf("Could you please test another baudrate?\r\n");
        printf("But I think that I couldn't to do.....\r\n");
    }
}

萬致遠(yuǎn)@rwzy.co.cc
求M~~~

關(guān)閉窗口

相關(guān)文章

主站蜘蛛池模板: 欧美日韩成人 | 中国黄色录像 | 中文在线视频 | 进去里视频在线观看 | 国产一区二区中文字幕 | 成人免费在线播放 | av手机在线免费观看 | 五月婷婷影院 | 欧美午夜精品久久久久免费视 | 黄网免费看| 亚洲福利在线观看 | 免费av网址在线观看 | 神马九九 | 色天天综合网 | www.国产精品.com | 日韩综合精品 | 狠狠躁夜夜躁人爽 | 国产美女福利 | 三级a毛片| 黄色影音 | 亚洲国产天堂 | 91丨九色丨蝌蚪丨丝袜 | 破处视频在线观看 | 日韩一区二区在线播放 | 精品日韩在线 | 黄色一级免费看 | 亚洲欧美国产精品 | 成人一区在线观看 | 国精产品99永久一区一区 | 午夜网站在线观看 | 国产人成一区二区三区影院 | 91性高潮久久久久久久久 | 精品国产aⅴ麻豆 | 成人精品福利 | 亚洲经典av | 欧美日韩激情视频 | 综合久久99 | 黄色成人在线视频 | 在线不欧美 | 特黄视频| 日韩理论在线观看 |