標(biāo)題: 關(guān)于單片機(jī)串口接收一幀數(shù)據(jù),收不到數(shù)據(jù) [打印本頁(yè)]

作者: ninghong    時(shí)間: 2016-12-5 14:13
標(biāo)題: 關(guān)于單片機(jī)串口接收一幀數(shù)據(jù),收不到數(shù)據(jù)
兩個(gè)單片機(jī)通過(guò)串口相互通信,一個(gè)單片機(jī)不停向另一個(gè)單片機(jī)傳送數(shù)據(jù),

發(fā)送數(shù)據(jù)的單片機(jī):

oid Usart_Int(uint32_t BaudRatePrescaler)
{
         SCON  = 0x50;//1位起始位,8位數(shù)據(jù)位,1位停止位,異步,使能接收
         TMOD |= 0x20;//定時(shí)器1,工作方式2,8位自動(dòng)重裝計(jì)數(shù)值
        //例9600,28800/9600=3,TH1=253=FD;
     TH1   =256-(28800/BaudRatePrescaler);
         TL1   =256-(28800/BaudRatePrescaler);
     TCON |=0x40;//啟動(dòng)定時(shí)器1
         IE   |=0x90;//打開串口中斷,MCU總中斷
}
//發(fā)送一個(gè)字節(jié)
uint8_t send_ok=0,Receive_ok=0,TEMP_data[9]={0};
void USART_send_byte(uint8_t Tx_data)
{
        while(send_ok);//等待發(fā)送緩存為空
         SBUF = Tx_data;
        send_ok=1;//緩存標(biāo)志置1
}
//發(fā)送Length-1個(gè)數(shù)據(jù)+1個(gè)數(shù)據(jù)累加和
void USART_Send(uint8_t *Buffer, uint8_t Length)
{
        uint8_t i=0;
        while(i<Length)
        {
                if(i<(Length-1))
                Buffer[Length-1]+=Buffer;
                USART_send_byte(Buffer[i++]);
        }
}
//發(fā)送一幀數(shù)據(jù)
void send_out(int16_t *Data,uint8_t length,uint8_t send)
{
        uint8_t TX_DATA[13],i=0,k=0;
        memset(TX_DATA,0,(2*length+5));//清空發(fā)送數(shù)據(jù)
        TX_DATA[i++]=0X5A;//幀頭
        TX_DATA[i++]=0X5A;//幀頭
        TX_DATA[i++]=send;//功能字節(jié)
        TX_DATA[i++]=2*length;//數(shù)據(jù)個(gè)數(shù)
        for(k=0;k<length;k++)//存入數(shù)據(jù)到緩存TX_DATA數(shù)組
        {
                TX_DATA[i++]=(uint16_t)Data[k]>>8;
                TX_DATA[i++]=(uint16_t)Data[k];
        }
        USART_Send(TX_DATA,(2*length+5));//發(fā)送一幀數(shù)據(jù)        
}

模塊輸出格式,每幀包含 10 個(gè)字節(jié)(十六進(jìn)制):
①.Byte0: 0x5A 幀頭標(biāo)志
②.Byte1: 0x5A 幀頭標(biāo)志
③.Byte2: 0X45 本幀數(shù)據(jù)類型( 0x45:溫度數(shù)據(jù))
④.Byte3: 0x04 數(shù)據(jù)量(以下 4 個(gè)數(shù)據(jù) 2 組為例)
⑤.Byte4: 0x00~0xFF 數(shù)據(jù) 1 高 8 位
⑥.Byte5: 0x00~0xFF 數(shù)據(jù) 1 低 8 位
⑦.Byte6: 0x00~0xFF 數(shù)據(jù) 2 高 8 位
⑧.Byte7: 0x00~0xFF 數(shù)據(jù) 2 低 8 位
⑨.Byte8: 0x00~0xFF 校驗(yàn)和(前面數(shù)據(jù) Byte0-7 累加和, 僅留低 8 位)
⑩. Byte9: 0x01~0x15 ID 號(hào),范圍 0x01~0x15 可以修改,默認(rèn)是 0x14




我接收單片機(jī)是這樣的寫的,怎么就是收不到數(shù)據(jù)呢,大家?guī)臀铱纯矗?/font>
void Usart_Int(uint32_t BaudRatePrescaler)
{
         SCON  = 0x50;//1位起始位,8位數(shù)據(jù)位,1位停止位,異步,使能接收
         TMOD |= 0x20;//定時(shí)器1,工作方式2,8位自動(dòng)重裝計(jì)數(shù)值
        //例9600,28800/9600=3,TH1=253=FD;
     TH1   =256-(28800/BaudRatePrescaler);
         TL1   =256-(28800/BaudRatePrescaler);
     TCON |=0x40;//啟動(dòng)定時(shí)器1
         IE   |=0x90;//打開串口中斷,MCU總中斷
}

main(void)
{
        float TO=0,TA=0;
     u8 sum=0,i=0;
        int datas[2]={0};
        Usart_Int(9600);
        send_com(0x45);//發(fā)送讀方位角指令
         while(1)
        {
                if(Receive_ok)//串口接收完畢
                {
                        for(sum=0,i=0;i<(TEMP_data[3]+4);i++)//TEMP_data[3]=4
                        sum+=TEMP_data;
                        if(sum==TEMP_data)//校驗(yàn)和判斷
                        {
                                TO=(float)((TEMP_data[4]<<8)|TEMP_data[5])/100;//得到真實(shí)溫度
                                TA=(float)((TEMP_data[6]<<8)|TEMP_data[7])/100;//得到真實(shí)溫度
                     LED = 1;//讓LED燈亮來(lái)判斷數(shù)據(jù)接收完整,//小燈一真沒(méi)亮過(guò)。不知道程序哪里不對(duì),求解
                        }
                        Receive_ok=0;//處理數(shù)據(jù)完畢標(biāo)志
                }
        }
}


void USART_IRQHandler(void)interrupt 4
{
        static uint8_t i=0,rebuf[9]={0};
        uint8_t sum=0;
    if(TI)//發(fā)送完成標(biāo)志
        {
          TI=0;//清發(fā)送完成標(biāo)志
          send_ok=0;//緩存標(biāo)志置0
        }
        if(RI)//接收完成標(biāo)志
        {
                rebuf[i++]=SBUF;
                RI=0;//清中斷接收標(biāo)志
                if (rebuf[0]!=0x5a)//幀頭不對(duì)
                        i=0;        
                if ((i==2)&&(rebuf[1]!=0x5a))//幀頭不對(duì)
                        i=0;
        
        if(i>3)//i等于4時(shí),已經(jīng)接收到數(shù)據(jù)量字節(jié)rebuf[3]
                {
                        if(i!=(rebuf[3]+5))//判斷是否接收一幀數(shù)據(jù)完畢
                                return;        
                        switch(rebuf[2])//接收完畢后處理
                        {
                                case 0x45:
                                        if(!Receive_ok)//當(dāng)數(shù)據(jù)處理完成后才接收新的數(shù)據(jù)
                                        {
                                                memcpy(TEMP_data,rebuf,9);//拷貝接收到的數(shù)據(jù)
                                                Receive_ok=1;//接收完成標(biāo)志
                                        }
                                        break;
                                case 0x15:break;
                                case 0x35:break;
                        }
                        i=0;//緩存清0
                }
        
        }


}





作者: strange233    時(shí)間: 2016-12-6 10:24
你先自己試一下簡(jiǎn)單的通信,你這樣就貼一大段代碼也不知道硬件有沒(méi)有問(wèn)題,一步一步慢慢調(diào)試,代碼都是調(diào)出來(lái)的
作者: 默默玩吉他    時(shí)間: 2016-12-6 11:03
你先自己試一下簡(jiǎn)單的通信,你這樣就貼一大段代碼也不知道硬件有沒(méi)有問(wèn)題,一步一步慢慢調(diào)試,代碼都是調(diào)出來(lái)的
作者: zl2168    時(shí)間: 2016-12-6 11:21
本帖最后由 zl2168 于 2016-12-6 11:29 編輯

實(shí)例77  雙機(jī)串行通信方式1


已知甲乙機(jī)以串行方式1進(jìn)行數(shù)據(jù)傳送,fOSC=11.0592MHz,波特率為1200b/sSMOD=0。甲機(jī)發(fā)送16個(gè)數(shù)據(jù)(設(shè)為16進(jìn)制數(shù)09、AF的共陽(yáng)字段碼),間隔1秒,發(fā)送后,輸出到P1口顯示;乙機(jī)接收后輸出到P2口顯示。

Proteus仿真一下,確認(rèn)有效。
實(shí)例77 雙機(jī)通信方式1.rar (40.4 KB, 下載次數(shù): 29)

以上摘自張志良編著80C51單片機(jī)仿真設(shè)計(jì)實(shí)例教程——基于Keil CProteus》清華大學(xué)出版社ISBN 978-7-302-41682-1,內(nèi)有常用的單片機(jī)應(yīng)用100案例,用于仿真實(shí)驗(yàn)操作,電路與程序真實(shí)可靠可信可行。書中電路和程序設(shè)計(jì)有詳細(xì)說(shuō)明,程序語(yǔ)句條條有注解。


作者: zl2168    時(shí)間: 2016-12-6 11:25
本帖最后由 zl2168 于 2016-12-6 11:27 編輯

實(shí)例78  雙機(jī)串行通信方式2


已知甲乙機(jī)以串行方式2進(jìn)行數(shù)據(jù)傳送,fOSC=12MHzSMOD=0,TB8/RB8作為奇偶校驗(yàn)位。甲機(jī)每發(fā)送一幀數(shù)據(jù)(設(shè)為09共陽(yáng)字段碼,存在外ROM中),同時(shí)在P1口顯示;用P2.7(驅(qū)動(dòng)LED燈)顯示奇偶校驗(yàn)位(10暗);接到乙機(jī)回復(fù)信號(hào)后,顯示暗0.5秒(作為幀間隔);然后發(fā)送下一數(shù)據(jù),直至10個(gè)數(shù)據(jù)串送完畢;顯示再暗0.5秒(作為周期間隔),然后重新開始第二輪重復(fù)循環(huán)操作。乙機(jī)接收甲機(jī)發(fā)送的一幀數(shù)據(jù)后,送P2口顯示;用P1.1顯示第9位數(shù)據(jù)(10暗),用P1.0顯示接收數(shù)據(jù)的奇偶性(奇亮偶暗);并進(jìn)行奇偶校驗(yàn),向甲機(jī)發(fā)送回復(fù)信號(hào)(00H表示校驗(yàn)正確,FFH表示出錯(cuò))。若正確,甲機(jī)繼續(xù)串行發(fā)送(共10幀);若出錯(cuò),甲機(jī)再重發(fā)一遍,直至乙機(jī)發(fā)回正確回復(fù)信號(hào)。
Proteus仿真一下,確認(rèn)有效。
實(shí)例78 雙機(jī)通信方式2.rar (46.57 KB, 下載次數(shù): 19)

以上摘自張志良編著80C51單片機(jī)仿真設(shè)計(jì)實(shí)例教程——基于Keil CProteus》清華大學(xué)出版社ISBN 978-7-302-41682-1內(nèi)有常用的單片機(jī)應(yīng)用100案例,用于仿真實(shí)驗(yàn)操作,電路與程序真實(shí)可靠可信可行。書中電路和程序設(shè)計(jì)有詳細(xì)說(shuō)明,程序語(yǔ)句條條有注解。

作者: zl2168    時(shí)間: 2016-12-6 11:29
本帖最后由 zl2168 于 2016-12-6 11:36 編輯

實(shí)例79  雙機(jī)串行通信方式3
Proteus仿真一下,確認(rèn)有效。
實(shí)例79 雙機(jī)通信方式3.rar (45.3 KB, 下載次數(shù): 16)

以上摘自張志良編著80C51單片機(jī)仿真設(shè)計(jì)實(shí)例教程——基于Keil CProteus》清華大學(xué)出版社ISBN 978-7-302-41682-1,內(nèi)有常用的單片機(jī)應(yīng)用100案例,用于仿真實(shí)驗(yàn)操作,電路與程序真實(shí)可靠可信可行書中電路和程序設(shè)計(jì)有詳細(xì)說(shuō)明,程序語(yǔ)句條條有注解。





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1