在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > AVR軟件模擬串口程序

            AVR軟件模擬串口程序

            作者: 時間:2011-02-18 來源:網絡 收藏


            M48,8MHz
            9600,1,8,1

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

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

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

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

            #include
            #include
            #include
            #include

            #defineSbit1()PORTD|=1#defineSbit0()PORTD=~(1

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

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

            unsignedchararr[10],DispBuff[10];


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

            voidInitial_INT0(void)
            {
            EICRA|=(1EIMSK|=1}

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

            voidInitial_timer1(void)
            {
            TCCR1A=(1TCCR1B=(1ICR1=1000;
            TIMSK1|=(1}

            voidInitial_timer2(void)
            {
            TCCR2B=(1TIMSK2|=(1}


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


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


            /*啟動串口發(fā)送*/
            voidSendData(unsignedchar*P,unsignedcharDataLength)
            {
            TxLength=DataLength;
            TxPoint=P;
            start=0;
            }


            intmain(void)
            {

            Initial();

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


            /*定時器0,100us溢出中斷*/
            SIGNAL(SIG_OVERFLOW0)
            {
            TCNT0=151;//重載數據,計時區(qū)間為151---255,共104uS,一個位的時間
            if(TxLength)//
            {
            if(start==0)
            {
            Sbit0();//起始位
            SUDR=*(TxPoint++);
            }
            else
            {
            if((start=8))
            {
            if(SUDR(1(start-1)))Sbit1();//數據1
            elseSbit0();//數據0
            }
            elseSbit1();//停止位
            }
            if(start10)start++;
            else
            {
            TxLength--;//一字節(jié)發(fā)送完成,字節(jié)數減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(RxLength10)DispBuff[RxLength++]=RUDR;

            }
            if(rtime4)rtime++;//字節(jié)間隔時間,間隔3個字節(jié)重新開始一幀
            elseRxLength=0;
            }

            SIGNAL(SIG_INTERRUPT0)//INT0,邊沿觸發(fā)中斷
            {
            unsignedchartemp,temp2=0;
            staticunsignedcharpre_TCNT2,j=0;
            if(INT0_time==0)//一個字節(jié)第一個下降沿中斷,起始位開始
            {
            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_time1)//奇數次中斷
            {
            while(temp)//位0的個數
            {
            RUDR=~(1temp--;
            j++;
            }
            }
            elsej+=temp;//偶數,位1的個數,跳過
            INT0_time++;//中斷次數加一
            }
            }
            rtime=0;
            }


            評論


            相關推薦

            技術專區(qū)

            關閉