亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 51單片機模擬串口的三種方法.txt

?? 51單片機模擬串口的三種方法 有興趣的同志可以嘗試下
?? TXT
字號:
51單片機模擬串口的三種方法 分類:默認欄目
隨著單片機的使用日益頻繁,用其作前置機進行采集和通信也常見于各種應用,一般是利用前置
機采集各種終端數據后進行處理、存儲,再主動或被動上報給管理站。這種情況下下,采集會需
要一個串口,上報又需要另一個串口,這就要求單片機具有雙串口的功能,但我們知道一般的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;        
    TR0=1;                        //開始計數
    TF0=0;
}

void WByte(uchar input)
{
    //發送啟始位
    uchar i=8;
    TR0=1;
    TXD=(bit)0;
    WaitTF0();
    //發送8位數據位
    while(i--)
    {
        TXD=(bit)(input&0x01);     //先傳低位
        WaitTF0();
        input=input>>1;
    }
    //發送校驗位(無)
    //發送結束位
    TXD=(bit)1;
    WaitTF0();
    TR0=0;
}    
//查詢計數器溢出標志位
void WaitTF0( void )
{
    while(!TF0);
    TF0=0;
}
    接收的程序,可以參考下一種方法,不再寫出。這種辦法個人感覺不錯,接收和發送
都很準確,另外不需要計算每條語句的指令周期數。

方法三:中斷法

    中斷的方法和計數器的方法差不多,只是當計算器溢出時便產生一次中斷,用戶可以
在中斷程序中置標志,程序不斷的查詢該標志來決定是否發送或接收下一位,當然程序中需對中
斷進行初始化,同時編寫中斷程序。本程序使用Timer0中斷。
#define TM0_FLAG P1_2 //設傳輸標志位
//計數器及中斷初始化
void S2INI(void)
{
    TMOD =0x02;                //計數器0,方式2
TH0=0xA0;                    //預值為256-96=140,十六進制A0
    TL0=TH0;        
    TR0=0;                         //在發送或
接收才開始使用
    TF0=0; 
    ET0=1;                         //允許定時
器0中斷
    EA=1;                         //中斷允許
總開關
}

//接收一個字符
uchar RByte()
{
    uchar Output=0;
    uchar i=8;
TR0=1;                         //啟動Timer0
TL0=TH0;
    WaitTF0();                    //等過起始
    //發送8位數據位
    while(i--)
    {
        Output >>=1;
        if(RXD) Output   =0x80;     //先收低位
WaitTF0();                //位間延時
    }
    while(!TM0_FLAG) if(RXD) break;
    TR0=0;                         //停止
Timer0
    return Output;
}
//中斷1處理程序
void IntTimer0() interrupt 1
{
    TM0_FLAG=1;                //設置標志位。
}
//查詢傳輸標志位
void WaitTF0( void )
{
while(!TM0_FLAG); 
TM0_FLAG=0;                 //清標志位
}
    中斷法也是我推薦的方法,和計數法大同小異。發送程序參考計數法,相信是件很容
易的事。
另外還需注明的是本文所說的串口就是通常的三線制異步通信串口(UART),只用RXD、TXD、GND。 
//***********************************************************************************************

AVR軟件模擬串口程序





來源:coldra資料室  作者:coldra

M48,8MHz 
9600,1,8,1 

輸出:用定時器控制普通IO口輸出位 
輸入:用外部中斷+定時器,判斷位的寬度 

好幾天沒休息,利用閑暇寫的,也沒找到別人的參考程序,不過終于算是穩定了,其實還應該有很多其它的方法可以試一下,比如用PWM輸出串行數據,用輸入捕獲接收數據,或定時查詢,或用任意一個IO口中斷,則每個引腳都有可能 

現在還有些問題,全雙工同時收發時發送偶爾出錯,占用兩個定時器有些浪費,以后再修改吧,最好加上各種波率 

本程序為直接摘出部分,刪了無關的部分,在此可能有些變量沒用,或有段落遺漏,請諒 

#include  
#include  
#include  
#include  

#define Sbit1() PORTD =1<#define Sbit0() PORTD&=~(1<

volatile unsigned int 
eep_ms,//毫秒計時 
keytime,                    //等待時間 
SoundOnTime;                    //// 
volatile unsigned  char  
rdata, 
key, 
start=0, 
keycode,        // 
*TxPoint, 
rtime, 
INT0_time,                //中斷次數 

RxLength=0,        //接收長度 
RUDR,            //摸擬串口接收的數據 
TxLength,                    //串口發送數據長度 
SUDR;                        //串口發送的數據 

unsigned char arr[10],DispBuff[10]; 


void Initial_IO(void)//IO口初始化 
    { 
     DDRD = 0X82;              //PD1串口輸出,PD0串口輸入,PD2模擬串口輸入(INT0) 
     PORTD = 0X82;             //PD1輸出高電平 
    } 

void Initial_INT0(void) 
    { 
    EICRA =(1<     EIMSK =1<    } 

void Initial_timer0(void)                         //定時器0初始化 
    { 
     TCCR0B =(1<     TIMSK0 =(1<    } 

void Initial_timer1(void) 
    { 
     TCCR1A=(1<          TCCR1B=(1<     ICR1=1000; 
     TIMSK1 =(1<    } 

void Initial_timer2(void) 
    { 
     TCCR2B=(1<     TIMSK2 =(1<    } 


void Initial_WDR(void)                                       //看門狗初始化 
    { 
    wdt_enable(WDTO_1S); 
    wdt_reset(); 
    } 


void Initial(void) 
{ 
    Initial_IO(); 
    Initial_timer0(); 
    Initial_timer1(); 
    Initial_timer2(); 
    Initial_INT0(); 
    Initial_WDR(); 
    sei(); 
} 


/*啟動串口發送*/ 
void SendData(unsigned char *P,unsigned char DataLength) 
    { 
    TxLength=DataLength; 
    TxPoint=P;  
    start=0; 
    } 
     

int main (void) 
    { 

    Initial(); 

    while(1) 
        { 
        wdt_reset(); 
        if((rdata)&&(eep_ms>10))//收到數據延時10mS后啟動發送,回送驗證數據 
            { 
            key=0; 
            SendData(&DispBuff[0],9);//發送DispBuff[0]的9位數據 
            while(TxLength);//等待發送完成 
            rdata=0; 
            eep_ms=0; 
            } 
        } 
    } 


/*定時器0,100us溢出中斷*/ 
SIGNAL(SIG_OVERFLOW0) 
    { 
    TCNT0=151;//重載數據,計時區間為151---255,共104uS,一個位的時間 
    if(TxLength)// 
        { 
        if(start==0) 
            { 
            Sbit0();//起始位 
            SUDR=*(TxPoint++); 
            } 
        else 
            { 
            if((start<=8)) 
                { 
                if(SUDR&(1<<(start-1)))Sbit1();//數據1 
                else Sbit0();//數據0 
                } 
            else Sbit1();//停止位 
            } 
        if(start<10)start++; 
        else  
            { 
            TxLength--;//一字節 發送完成,字節數減1 
            start=0; 
            }// 
        } 
    } 

/*定時器1,1ms溢出中斷*/ 
SIGNAL(SIG_OVERFLOW1) 
{ 
    eep_ms++; 
} 
/*定時器2*/  
SIGNAL(SIG_OVERFLOW2) 
    { 
    sei();     
    if(INT0_time)//有數據 
        { 
        INT0_time=0;//中斷次數清0 
        rdata=1;//置有數據標志 
        eep_ms=0; 
        if(RxLength<10)DispBuff[RxLength++]=RUDR; 
         
        } 
    if(rtime<4)rtime++;//字節間隔時間,間隔3個字節重新開始一幀 
    else RxLength=0; 
    } 
     
SIGNAL(SIG_INTERRUPT0)//INT0,邊沿觸發中斷 
    { 
    unsigned char temp,temp2=0; 
    static unsigned char pre_TCNT2,j=0; 
    if(INT0_time==0)//一個字節第一個下降沿中斷,起始位開始 
        { 
        TCNT2=130; 
        pre_TCNT2=130; 
        RUDR=0xff;//接收的數據初值 
        j=0;    //位數清零 
        INT0_time++;//中斷次數加一 
        } 
    else  
        { 
        temp=TCNT2; 
        if(temp>pre_TCNT2)temp2=temp-pre_TCNT2;//取一個高/低電平的寬度 
        if(temp2>10)//濾過窄電平(干擾信號) 
            { 
            pre_TCNT2=temp;//記錄前一次的時間值 
            temp=0; 
            while(temp2>13)//計算位的個數,約13為一個位(8*13=104uS) 
                    { 
                    temp2-=13;// 
                    temp++; 
                    } 
            if(temp2>6)temp++;//計算位的個數,一般13為一個位 
            if(INT0_time==1)temp-=1; 
            if(INT0_time&1)//奇數次中斷 
                { 
                while(temp)//位0的個數 
                    { 
                    RUDR&=~(1<                    temp--; 
                    j++; 
                    } 
                } 
            else j+=temp;//偶數,位1的個數,跳過 
            INT0_time++;//中斷次數加一 
            } 
        } 
    rtime=0; 
    }

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91女人视频在线观看| 色中色一区二区| 国产.欧美.日韩| 99精品一区二区三区| 色综合天天综合网国产成人综合天| 色婷婷av一区二区三区大白胸 | 亚洲午夜电影在线观看| 午夜av电影一区| 国内一区二区视频| 91麻豆精品视频| 日韩女优视频免费观看| 国产精品色在线| 午夜精品免费在线观看| 国产一区视频在线看| 欧洲视频一区二区| 久久中文娱乐网| 日本一区二区三区四区 | 午夜电影网亚洲视频| 国产综合久久久久久久久久久久| www..com久久爱| 日韩精品资源二区在线| 一区二区中文字幕在线| 蜜桃视频在线观看一区二区| 精品在线播放免费| 国产精品1区2区3区在线观看| 色偷偷久久一区二区三区| 欧美一区日韩一区| 一区二区三区国产精华| 国产一区二区三区在线观看精品| 欧美午夜免费电影| 国产精品免费视频观看| 奇米在线7777在线精品| 欧美在线观看视频在线| 中文字幕av一区二区三区| 男女性色大片免费观看一区二区 | 欧美日韩视频在线一区二区 | 欧美精品v国产精品v日韩精品 | 亚洲成人av一区二区| 成人99免费视频| 久久精品一区蜜桃臀影院| 日韩av电影一区| 欧美亚洲动漫精品| 亚洲素人一区二区| 粉嫩aⅴ一区二区三区四区| 日韩精品一区二区三区四区视频 | 国产精品一区二区在线看| 在线播放亚洲一区| 26uuu国产在线精品一区二区| 视频一区免费在线观看| 在线观看免费成人| 亚洲免费伊人电影| 91丨九色porny丨蝌蚪| 久久久久免费观看| 国产福利一区二区三区视频在线| 精品免费国产二区三区 | 中文字幕中文字幕一区二区| 国产高清不卡二三区| 久久久亚洲国产美女国产盗摄 | 51精品视频一区二区三区| 亚洲国产精品一区二区尤物区| 成人污污视频在线观看| 中文一区一区三区高中清不卡| 国产在线一区二区| 国产日本欧美一区二区| 懂色av一区二区三区蜜臀| 国产欧美视频一区二区| 成人手机在线视频| 亚洲伦理在线免费看| 欧美性色黄大片| 亚洲一区二区五区| 91精品在线麻豆| 激情久久五月天| 中文字幕在线一区免费| 91免费看`日韩一区二区| 亚洲欧美在线视频观看| 色综合久久久久综合99| 亚洲va韩国va欧美va精品| 欧美日本一区二区在线观看| 三级欧美韩日大片在线看| 日韩欧美一区二区久久婷婷| 国产成人免费视频网站高清观看视频 | 久久奇米777| 99久精品国产| 日韩成人一区二区三区在线观看| 日韩美女一区二区三区四区| 韩国v欧美v亚洲v日本v| 亚洲色图丝袜美腿| 欧美日韩三级视频| 激情深爱一区二区| 最新国产精品久久精品| 欧美久久久久中文字幕| 国产老妇另类xxxxx| 亚洲视频中文字幕| 日韩一级免费观看| 国产精品白丝jk黑袜喷水| 亚洲精品国产高清久久伦理二区| 91精品欧美一区二区三区综合在| 国产精品99久久久| 亚洲国产视频a| 久久久久久久久久久久电影| 欧美影院一区二区| 国产在线视频不卡二| 一区二区三区免费在线观看| 精品日韩在线一区| 色先锋aa成人| 国产成人在线免费观看| 日本麻豆一区二区三区视频| 国产精品久久国产精麻豆99网站 | 日韩黄色小视频| 国产精品久久毛片av大全日韩| 欧美三级日韩三级国产三级| 国产精品亚洲第一区在线暖暖韩国| 一区二区三区欧美| 中文字幕中文字幕一区二区| 日韩一级二级三级| 欧美在线啊v一区| 成人午夜激情片| 国产精品一区二区男女羞羞无遮挡| 亚洲va韩国va欧美va| 亚洲男人的天堂网| 国产精品毛片高清在线完整版| 精品福利在线导航| 在线中文字幕不卡| 99久久99久久精品免费观看| 国产一级精品在线| 精品一区二区三区久久| 无码av中文一区二区三区桃花岛| 亚洲美女一区二区三区| 中文久久乱码一区二区| 日韩久久久精品| 91精品国产91热久久久做人人| 欧美色老头old∨ideo| 一道本成人在线| 成人黄页毛片网站| 成人网在线播放| 成人小视频在线| 精品一区二区三区免费播放| 久久精品国产**网站演员| 日韩成人一区二区| 久久国产日韩欧美精品| 男女性色大片免费观看一区二区| 亚洲乱码精品一二三四区日韩在线| 亚洲国产中文字幕| 老汉av免费一区二区三区| 国产精品一区二区三区99| 91污片在线观看| 欧美老肥妇做.爰bbww视频| 精品成人一区二区三区四区| 国产精品嫩草99a| 天堂资源在线中文精品| 免费人成精品欧美精品| 日韩成人一级大片| 国产精品亚洲综合一区在线观看| 91麻豆精品视频| 日韩精品中文字幕在线一区| 国产欧美va欧美不卡在线| 亚洲一区二区三区视频在线 | 日韩精品中文字幕在线不卡尤物 | 精品国产乱码久久久久久老虎| 亚洲欧洲韩国日本视频| 一区2区3区在线看| 韩国精品主播一区二区在线观看| 不卡的av中国片| 日韩片之四级片| 亚洲女性喷水在线观看一区| 久久精品国产免费| 色综合网站在线| 久久亚洲一区二区三区明星换脸| 中文字幕亚洲区| 久久精品理论片| 欧美视频精品在线| 国产精品欧美一区二区三区| 日本成人在线一区| 一本一本久久a久久精品综合麻豆| 日韩欧美高清一区| 亚洲精品视频在线观看免费| 韩国午夜理伦三级不卡影院| 欧美日韩国产在线播放网站| 中文字幕精品一区二区三区精品 | 一区二区三区鲁丝不卡| 国产精品影视在线观看| 欧美精品日韩综合在线| 亚洲男人电影天堂| av午夜一区麻豆| 精品国产乱码久久久久久夜甘婷婷| 亚洲动漫第一页| 99这里只有精品| 国产精品你懂的在线欣赏| 久久69国产一区二区蜜臀| 在线电影国产精品| 亚洲一区二区三区免费视频| 色综合久久综合| 亚洲色图欧洲色图婷婷| 懂色av噜噜一区二区三区av| 久久综合给合久久狠狠狠97色69| 日本美女一区二区| 欧美理论电影在线| 日韩va亚洲va欧美va久久| 欧美久久免费观看| 日本不卡高清视频|