打印

下面的通信协议应该如何调试,新手上路

[复制链接]
1451|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
9981|  楼主 | 2007-7-6 13:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
 下面的程序,那位能告诉我,数据包应该怎莫写,我不太理解ASCII码表示,我从串扣发出去,去测试这个协议,多谢





 //PC读MCU指令结构:(中断方式,ASCII码表示) 
//帧:   帧头标志|帧类型|器件地址|启始地址|长度n|效验和|帧尾标志 
//值:    'n' 'y'| 'r'  |  0x01  |   x    |  x  |   x  |0x13 0x10 
//字节数:   2   |  1   |    1   |   1    |  1  |   1  |   2 
//求和: 


///////////////////////////////////////////////////////////////////// 

//功能描述:中断方式:本程序为mcu的串口通讯提供(贞结构)函数接口,包括具体协议部分 
//其他说明:只提供对AT89c51rc具体硬件的可靠访问接口 
//stc试验板调试



///////////////////////////////////////////////////////////////////// 


#include <reg51.h> 

sbit  P1_7=P1^7 ;  //正在通讯

sbit  P1_1=P1^1 ;  //写回应帧发送完毕 

sbit  P1_0=P1^0 ;  //写发送帧发送完毕 

sbit  P1_2=P1^2 ;  //地址正确  

//预定义 帧 
#define F_ST1 0x6e             //帧头标志            n 

#define F_ST2 0x79             //帧头标志             y 

#define F_R 0x72               //帧类型 读             r 

#define F_W 0x77               //帧类型 写           w 

#define F_D 0x64               //帧类型 数据帧        d 

#define F_B 0x62               //帧类型 写回应帧       b 

#define F_C 0x63               //帧类型 重发命令帧   c 

#define F_Q 0x71               //帧类型 放弃帧        q 

#define F_ADDR 0x31            //器件地址              0-9 

#define F_END 0x7a             //帧尾标志             z 

#define F_SPACE 0x30           //空标志                 0 

#define F_ERR1 0x31            //错误标志1,flagerr       1 

#define F_ERR2 0x32            //错误标志2           2 常数 

#define S_MAXBUF 16            //接收/发送数据的最大缓存量 

#define FIELD_MAXBUF 48        //最小场缓存,可以大于48字节,因为协议是以20字节为单位传输的 

#define communicationing P1_7  //正在通讯(1)标志 

#define ERRFRAME_MAX 5         //连续NOFRAME_CNT次帧不正确  

  
#define ERR_NOCNTMAX_RESEND    if(++errframe_cnt<=ERRFRAME_MAX)resend_frame();  else errframe_cnt=communicationing=0; 
                            //若超过  ERRFRAME_MAX 次则令通讯停止ERR_NOCNTMAX_RESEND 

//public 变量 
unsigned char databuf[FIELD_MAXBUF],errframe_cnt; 
//函数 

///////////////////////////////////////////////////////////////////// 
//函 数 名:send() 
//功能描述:向串口发送一个字符 
//函数说明: 
//调用函数: 
//全局变量: 
//输    入:ch-要发送的ASCII字符 
//返    回:无 
///////////////////////////////////////////////////////////////////// 
void send(unsigned char ch) 

{

  SBUF=ch;

  while(TI==0);
  
  TI=0;
  


///////////////////////////////////////////////////////////////////// 
//函 数 名:receive() 
//功能描述:从串口接收一个字符 
//函数说明: 
//调用函数: 
//全局变量: 
//输    入:无 
//返    回:一个ASCII字符 

///////////////////////////////////////////////////////////////////// 
unsigned char receive(void) 

{
   while(RI==0);
   
   RI=0;
   
   return SBUF;
   
 } 

///////////////////////////////////////////////////////////////////// 
//函 数 名:CharToHex() 
//功能描述:把ASCII字符转换为16进制 
//函数说明: 
//调用函数: 
//全局变量: 
//输    入:ASCII字符 
//返    回:16进制 
///////////////////////////////////////////////////////////////////// 
unsigned char CharToHex(unsigned char bChar)


    if((bChar>=0x30)&&(bChar<=0x39)) 

        bChar -= 0x30; 

    else if((bChar>=0x41)&&(bChar<=0x46))//大写字母 

        bChar -= 0x37; 

    else if((bChar>=0x61)&&(bChar<=0x66))//小写字母 

        bChar -= 0x57; 

    else bChar = 0xff; 

    return bChar; 


///////////////////////////////////////////////////////////////////// 
//函 数 名:HexToChar() 
//功能描述:把16进制转换为ASCII字符 
//函数说明: 
//调用函数: 
//全局变量: 
//输    入:16进制 
//返    回:ASCII字符 
///////////////////////////////////////////////////////////////////// 
unsigned char HexToChar(unsigned char bHex)


    if((bHex>=0)&&(bHex<=9)) 

        bHex += 0x30; 

    else if((bHex>=10)&&(bHex<=15))//大写字母 

        bHex += 0x37; 

    else bHex = 0xff; 

    return bHex; 


///////////////////////////////////////////////////////////////////// 
//函 数 名:com_int() 
//功能描述:初始化串口 
//函数说明:默认其他参数为[baud_rate],n,8,1 
//调用函数: 
//全局变量: 
//输    入:baud_rate 波特率 
//返    回:无 
///////////////////////////////////////////////////////////////////// 
void com_init(unsigned int baud_rate)


    EA=1;
    
    ES=1;//ET1=1; 
      
    SCON = 0x50;    /* 0x52;//SCON */ 

    TMOD = 0x20;    /*0x20;// TMOD */ 

    TCON = 0x60;    /*0x60;// TCON */ 

    PCON=PCON&0x7f; 

    switch(baud_rate)//波特率设置 
    
    {    
        case 1200:
         
            TL1=0xe8;TH1=0Xe8;break;//1200 

        case 2400: 

            TL1=0xf4;TH1=0Xf4;break;//2400 

        case 4800: 

            TL1=0xfa;TH1=0Xfa;break;//4800 

        case 9600: 

            TL1=0xfd;TH1=0Xfd;break;//9600 

        case 19200: 

            PCON=PCON|0x80;TL1=0xfd;TH1=0Xfd;break;//19200 

        case 38400: 

            PCON=PCON|0x80;TL1=0xfe;TH1=0Xfe;break;//38400 

        default: 

             TL1=0xfd;TH1=0Xfd;break;//9600 
    } 

///////////////////////////////////////////////////////////////////// 
//函 数 名:resend_frame() 
//功能描述:发送重发帧 
//函数说明:通知PC重发 
//调用函数: 
//全局变量: 
//输    入:无 
//返    回:无 
///////////////////////////////////////////////////////////////////// 
void resend_frame(void)

    send(F_ST1);
    send(F_ST2);
    send(F_C);
    send(F_SPACE);
    send(F_SPACE);//发送效验和 
    send(F_END); 


///////////////////////////////////////////////////////////////////// 
//函 数 名:quit_frame() 
//功能描述:发送放弃帧 
//函数说明:通知PC放弃通讯 
//调用函数: 
//全局变量: 
//输    入:无 
//返    回:无 
///////////////////////////////////////////////////////////////////// 
void quit_frame(void)

    send(F_ST1);
    send(F_ST2);
    send(F_Q);
    send(F_ERR1);
    send(F_ERR1);//发送效验和 
    send(F_END); 


///////////////////////////////////////////////////////////////////// 
//函 数 名:com_int() 
//功能描述:串口中断 
//函数说明: 
//调用函数: 
//全局变量: 
//输    入:无 
//返    回:无 
///////////////////////////////////////////////////////////////////// 
void com_int()interrupt 4

     unsigned char i,csaddr,clen,csum,tempbuf[S_MAXBUF]; 

     csum=0; 

      if(receive()==F_ST1)//是侦

      { 

      if(receive()==F_ST2)//头判断完
      
      { 
        communicationing =0; //设置通讯状态为正常即启动通讯 

        switch(receive())
        
        { 
            case F_R://是读指令帧r 

                if(receive()==F_ADDR)//地址正确
                
                    {    
                        P1_2=!P1_2;  
                               
                        csaddr=CharToHex(receive())<<4;

                        csaddr+=CharToHex (receive()); 

                        clen=CharToHex(receive())<<4;

                        clen+=CharToHex(receive()); 

                        csum=csaddr+clen;
                         
                        i=CharToHex(receive())<<4;

                        i+=CharToHex(receive()); 

            if(i==csum)//效验和正确 
              {
                 if(receive()==F_END)//结束标志正确开始发送数据帧 
                 
                   {
                         
                     csum=0;

                     send(F_ST1);

                     send(F_ST2);

                     send(F_D); 

                     send (HexToChar((clen&0xf0)>>4));

                     send(HexToChar(clen&0x0f));

                     csum+=clen; 

                     for (i=0;i<clen;i++)
                     
                     { 
                             
                     send(HexToChar((databuf[i+csaddr]&0xf0)>>4));

                     send(HexToChar(databuf [i+csaddr]&0x0f)); 
                             
                     csum+=databuf[i+csaddr];
                      
                         } //if (csum>127)csum-=128; 
                            
                            send (HexToChar((csum&0xf0)>>4));

                            send(HexToChar(csum&0x0f));

                            send(F_END);//发送数据帧完毕  
                             
                            
                            P1_0=!P1_0; 

                        }  else 
                         
                      {
                          ERR_NOCNTMAX_RESEND  
                          
                           break;//结束标志错误 
                          
                       }

                      }else
                      
                       {
                       
                        ERR_NOCNTMAX_RESEND 
                      
                        break;//效验和错误
                      
                      } 

                      }//地址不正确 
                break; 

            case F_W://是PC写指令帧w 

                if(receive()==F_ADDR)//地址正确 
                
                   {
                    csaddr=CharToHex(receive())<<4;

                    csaddr+=CharToHex(receive()); 

                    clen=CharToHex(receive()) <<4;

                    clen+=CharToHex(receive()); 

                    csum=csaddr+clen; 

                    for(i=0;i<clen;i++)
                     { 
                        tempbuf[i+csaddr] =CharToHex(receive())<<4;

                        tempbuf[i+csaddr]+=CharToHex(receive()); 

                        csum+=tempbuf [i+csaddr]; 

                      } 

                    i=CharToHex(receive()) <<4;

                    i+=CharToHex(receive()); 

                    if(csum!=i) 
                    
                    {
                       ERR_NOCNTMAX_RESEND break;
                       
                    }//效验和错误 

                   if(F_END!=receive()) 
                   
                   {
                   
                   ERR_NOCNTMAX_RESEND break;
                   
                   }//结束标志错误 

            for (i=csaddr;i<clen+csaddr;i++)
            
             databuf[i-csaddr]=tempbuf[i-csaddr];//正确则保存数据 

                }//从PC获得数据写完毕//开始发送写回应帧 

                send(F_ST1);

                send(F_ST2);

                send(F_B);

                send (F_SPACE);

                send(F_SPACE);//发送效验和 

                send(F_END);//写回应帧发送完毕 

                P1_1=!P1_1; 

                break; 

            case F_Q://检测接收放弃帧 

                csaddr=receive();

                csum+=csaddr;//csaddr兼做放弃帧码标志 

                if(csaddr!=F_ERR1 && csaddr!=F_ERR2) 
                
                {  
                
                  ERR_NOCNTMAX_RESEND 
                  
                  break;
                
                } 

                if(csum!=receive()) 
                
                {
                   ERR_NOCNTMAX_RESEND
                   
                    break;
                    
                } 

                if(F_END!=receive())
                 
                {
                
                  ERR_NOCNTMAX_RESEND  
                  
                  break;
                  
                } 
                communicationing=0;//出错退出通讯 

                break; 

            default: 

                resend_frame();//要求从发 
        } 
    }//忽略     
}//忽略 
if(!communicationing)quit_frame();//调用放弃帧,通知PC 放弃通讯 

///////////////////////////////////////////////////////////////// 

//主函数 

///////////////////////////////////////////////////////////////// 
void main(void)


unsigned char i; 

for (i=0;i<FIELD_MAXBUF;i++)

databuf=i+0x30; 

com_init(9600); 

while(1)


/*可以处理非串口任务*/ 




相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

5

帖子

0

粉丝