自定义通讯协议

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "5510drv.h"
/*************************************/

unsigned int Gsz[14],Jsz[13],Zqll_k;//调节参数读写

//unsigned int CJz[8];测量I/O点数
unsigned int CJz[15];//测量参数模拟量批量只读
unsigned char YSCBZ[6];//硬手操参数开关量批量只读

//给水阀减温水阀门软手操unsigned int Pgsl[5],Pzql[5],Gsfk_z,Jsfk_z,Gslc;
unsigned int Pgsl[5],Pzql[5],gsi,jsi,Gsfk_z,Jsfk_z,GF_RK,YF_RK,GZ_RK1,GZ_RK2,Gslc;
unsigned char Ygs,Yjs,YGF,YYF,YGZ1,YGZ2;//硬手操标记只读
unsigned char Rgs,Rjs,RGF,RYF,RGZ1,RGZ2;//软手操标记只写
unsigned char Wgs,Wjs,Wgf,Wyf,Wrs;//参数写入标记只写


/***********LQ's DEFINE START**********/
#define UINT_TYPE  1
#define UCHAR_TYPE 2
#define LOCAL_PLC_ID 0x02
#define BROADCAST_ID 0x0f
//static int com_base = 0x3f8;
//unsigned char RecDone = 0, SendDone = 0;
//unsigned char RecByte;
unsigned char count;
unsigned char RecBuffer[40], SendBuffer[40];
unsigned char RecByteCount, SendByteCount;
char RecPacketLength, SendPacketLength;
char StartChannel = 0, EndChannel = 0, ChannelTotal = 1;
unsigned char DataSegLength;
unsigned char PacketDataType;
unsigned char Read_Write_Flag; /*0: read command packet; 1: write command packet*/
/*unsigned int testarray[7]; */

union Data_i    /*unsigned int data*/
    {
     unsigned int i_data;
     unsigned char byte[2];
    }data_i[20];

unsigned char data_c[20];//用于保存转换后的unsigned char类型

char DataSeg[60];

/*************LQ's DEFINE END**********/

/*************LQ's FUNCTION START*******/
unsigned char CheckID (unsigned char CheckByte)
{
    char PlcID;
    char Command;
    
    PlcID = CheckByte >> 4;
    Command = CheckByte & 0x0f;
    if ((PlcID == LOCAL_PLC_ID) || ((PlcID == BROADCAST_ID))//&& (Command == 0x03 || Command == 0x04)))
    {
        return 1;   /*the right packet or broadcast packet*/
    }
    
    return 0;
}

char CalcPacketLength (unsigned char CommandType, unsigned char ChannelNum)
{
    char Length;
    char RealChannelNum;
    
    if (((CommandType & 0x0f) == 0x01)||((CommandType & 0x0f) == 0x02))
    //读取开关量或者测量数据都用计算通道
    {
        StartChannel = ChannelNum >> 4;
        EndChannel = ChannelNum & 0x0f;
        ChannelTotal = RealChannelNum = (EndChannel - StartChannel + 1);
        
        if (ChannelTotal < 0)
        {
            return -1;
        }
    }
    else
    {
        ChannelTotal = RealChannelNum = 1;   /*it's single channel when the command is write float value*/
     }   
        switch (CommandType & 0x0f)
        {
            case 0x01:
            case 0x02:
            case 0x05:
                Length = 4;        /*read command packet*/
                break;
            case 0x03:
                Length = 4 + RealChannelNum * 2;    /*write command packet(unsigend int)*/
                break;
            case 0x04:
                Length = 4 + RealChannelNum;        /*write command packet(unsigned char)*/
                break;
            case 0x06:
                Length = 4 + RealChannelNum * 2;    /*write command packet(float)*/
                break;
        }
    
        
    return Length;
}

unsigned char RecData (void)
{
    unsigned char RecDone = 0;
    unsigned char RecByte;
    unsigned char ByteCount = 1;
    char PacketLength = 4;
    unsigned char InterruptFlag;

    RecByte = com_rx();
    //outportb(com_base + 5, 0x00);
    //if (RecByte != NULL);  printf("%x ", RecByte);
    if (RecByte != '\0' && RecByte == '@')
    {
	    /*还要加点预防读数据漏字节,读不够包长的处理措施*/
        RecBuffer[0] = RecByte;
        while (ByteCount < PacketLength)
        {
	        //InterruptFlag = inportb(com_base + 5);
	        //InterruptFlag = InterruptFlag & 0x01;

            if (com_rx_empty() != TRUE)
            {
                RecByte = com_rx();
		        //outportb(com_base + 5, 0x00);
	            /*	printf("%x ", RecByte);*/
                if (ByteCount == 1)
                    if (!CheckID(RecByte))
                        return RecDone;
                if (ByteCount == 2)
                {
                    PacketLength = CalcPacketLength(RecBuffer[1], RecByte);
                    if (PacketLength == -1)
                    {
                        return RecDone;
                    }
		            /*printf("     %x        ", PacketLength);*/
                }
                
                RecBuffer[ByteCount++] = RecByte;
            }
        }
        
        RecPacketLength = PacketLength;
        /* printf("\n");*/
        RecDone = 1;
    }
    
    return RecDone;
}

/*verify the content of packet whether is right*/
unsigned char VerifyPacket(unsigned char PacketLength)
{
    unsigned char CheckSum = 0;
    unsigned char i;
    
    for (i = 0; i < PacketLength - 1; i++)
    {
        CheckSum += RecBuffer[i];
    }
    
    if(CheckSum == RecBuffer[PacketLength - 1])
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

/*生成出错应答数据包*/
void CreateErrReplyPacket(void)
{
    SendBuffer[0] = '!';
    SendBuffer[1] = RecBuffer[1] | 0x08;
    SendPacketLength = 2;
}

void GetData(void)
{
    char i, j;
    
    if (ChannelTotal > 1)
    { 
    	if (PacketDataType == UINT_TYPE)
    	   for (i = StartChannel, j = 0; i <= EndChannel; i++, j++)
                {
	        //testarray[i] = (unsigned int)CJz[i];
                 data_i[j].i_data = CJz[i];
                 }
        else if (PacketDataType == UCHAR_TYPE)//开关量硬手操,只读            
    	   for (i = StartChannel, j = 0; i <= EndChannel; i++, j++)
                {
	        //testarray[i] = (unsigned int)CJz[i];
                   data_c[0]  = YSCBZ[i];
                 }        
    }
    else
    {
        if (PacketDataType == UINT_TYPE)
        {
            if (RecBuffer[2] >= 50 && RecBuffer[2] <= 63)
            {
                data_i[0].i_data = Gsz[RecBuffer[2] - 50];
            }
            else if (RecBuffer[2] >= 70 && RecBuffer[2] <= 82)
            {
                data_i[0].i_data = Jsz[RecBuffer[2] - 70];
            }
            else if (PacketDataType == UCHAR_TYPE)//参数修改标志开关量,读写;不用
            {
             
           	
                //data_c[0] =
            }
        }
    }
}

void SetData(void)
{
    unsigned int iTemp;
    
    switch (PacketDataType)
    {
        case UCHAR_TYPE:
            switch(RecBuffer[2] & 0xff)
            {
                case 0x00:
                    Rgs = RecBuffer[3] & 0xff;
                    break;
                case 0x01:
                    Rjs = RecBuffer[3] & 0xff;
                    break;
                case 0x02:
                    Wgs = RecBuffer[3] & 0xff;
                    break;
                case 0x03:
                    Wjs = RecBuffer[3] & 0xff;
                    break;
               case 0x04:
                    Wgf = RecBuffer[3] & 0xff;
                    break;  
               case 0x05:
                    Wyf = RecBuffer[3] & 0xff;
                    break;    
               case 0x06:
                    Wrs = RecBuffer[3] & 0xff;
                    break;        
              case 0x07:
                    RGF = RecBuffer[3] & 0xff;
                    break; 
              case 0x08:
                    RYF = RecBuffer[3] & 0xff;
                    break;      
              case 0x09:
                    RGZ1 = RecBuffer[3] & 0xff;
                    break;                                 
              case 0x0A:
                    RGZ2 = RecBuffer[3] & 0xff;
                    break;       
                                               
            }
            break;
        case UINT_TYPE:
            iTemp = RecBuffer[3];
            iTemp <<= 8;
            iTemp |= (unsigned int)RecBuffer[4];
            if (RecBuffer[2] >= 20 && RecBuffer[2] <= 22)
            {
                switch(RecBuffer[2])
                {
                    case 20:
                        Zqll_k = iTemp;
                        break;
                    case 21:
                        Gsfk_z = iTemp;
                        break;
                    case 22:
                        Jsfk_z = iTemp;
                        break;
                    case 23:
                        GF_RK = iTemp;
                        break;        
                    case 24:
                        YF_RK = iTemp;
                        break;     
                    case 25:
                        GZ_RK1 = iTemp;
                        break;    
                    case 26:
                        GZ_RK2 = iTemp;
                        break;                                                                            
                }
            }
            else if (RecBuffer[2] >= 50 && RecBuffer[2] <= 63)
            {
                Gsz[RecBuffer[2] - 50] = iTemp;
            }
            else if (RecBuffer[2] >= 70 && RecBuffer[2] <= 82)
            {
                Jsz[RecBuffer[2] - 70] = iTemp;
            }
            break;
    }
}
void AnalysePacket(void)
{
    switch(RecBuffer[1] & 0x0f)  /*switch by command type*/
    {
        case 0x01:   /*read AI channel value(unsigned int)*/
            Read_Write_Flag = 0;
            PacketDataType = UINT_TYPE;
            GetData();
            break;
        case 0x02:   /*read switch channel value(unsigned char)*/
            Read_Write_Flag = 0;
            PacketDataType = UCHAR_TYPE;
            GetData();
            break;
        case 0x03:   /*write AI channel value(unsigned int)*/
            Read_Write_Flag = 1;
            PacketDataType = UINT_TYPE;
            SetData();
            break;
        case 0x04:   /*write switch channel value(unsigned char)*/
            Read_Write_Flag = 1;
            PacketDataType = UCHAR_TYPE;
            SetData();
            break;
        case 0x05:   /*read AI channel value(float)*/
            Read_Write_Flag = 0;
            PacketDataType = UINT_TYPE;
            GetData();
            break;
  //case 0x06:   /*write AI channel value(float)*/
  //Read_Write_Flag = 1;
  //PacketDataType = FLOAT_TYPE;
  //break;
    }
}

/*convert the collected data with org. type to the byte type, and then push them
  into the array of dataseg */
void ConvertData(unsigned char DataType)
{
    unsigned char i, j;
    unsigned char bcount = 0;
    
    switch(DataType)
    {
        //case FLOAT_TYPE:  /*when the org. type of the data is float(4 bytes)*/
        //for (i = 0; i < DataLength; i++)
        //	for (j = 0; j < 4; j++)
        //	    DataSeg[count++] = data_f[i].byte[3 - j];
        //break;
        //case FLOAT_TYPE:
        case UINT_TYPE :  /*when the org. type of the data is unsigned int(2 bytes)*/
            for (i = 0; i < ChannelTotal; i++)
            for (j = 0; j < 2; j++)
            DataSeg[bcount++] = data_i[i].byte[1 - j];
            break;
        case UCHAR_TYPE:  /*when the org. type of the data is unsigned char(1 byte)*/
            for (i = 0; i < ChannelTotal; i++)
            DataSeg[bcount++] = data_c[i];
            break;
    }
    
    DataSegLength = bcount - 1;
}

void CreateNormalReplyPacket(unsigned char read_write_flag)
{
    //char TmpByte;
    char i;
    /*the reply packet for write command packet*/
    SendBuffer[0] = '!';
    SendBuffer[1] = RecBuffer[1];
    SendPacketLength = 2;
    /* printf("  read_write_flag = %c", !read_write_flag?'r':'w');*/
    if (!read_write_flag)
    {
        ConvertData(PacketDataType);

        SendBuffer[2] = RecBuffer[2];

        /*put data into packet*/
        for (i = 0; i < DataSegLength + 1; i++)
        {
            SendBuffer[3 + i] = DataSeg[i];
        }

        /*calculate the check sum and put it into packet*/
        SendBuffer[4 + DataSegLength] = 0;
        for (i = 0; i < 4 + DataSegLength ; i++)     
        {
            SendBuffer[4 + DataSegLength] += SendBuffer[i];
        }

        SendPacketLength = 5 + DataSegLength;
    }
}

void SendData(void)
{
    unsigned char i;
    /*printf("\nSendPacketLength = %x\n", SendPacketLength);*/
    for (i = 0; i < SendPacketLength; i++)
    {
        com_tx(SendBuffer[i]);
        
        while(!com_tx_empty());
        /*printf("%x ", SendBuffer[i]);*/
    }
    /* SendDone = 1; */
    /*printf("\n");*/
}

/*串口通讯主循环*/
void EnterCommLoop(void)
{
    //count = 0;
    while (RecData())
    {
        if (!VerifyPacket(RecPacketLength))
        {
            /*printf("%c", '%');*/
            CreateErrReplyPacket();
        }
        else
        {
            AnalysePacket();
            CreateNormalReplyPacket(Read_Write_Flag);
        }
    
        SendData();
    }
}

void InitCom(void)
{
    //int CommStatus;
    com_install(1);
    //CommStatus = com_485_install();
    //if (CommStatus != 0)
    //    printf("The 485 com port has been installed!");
    com_set_format(8, 0, 1);
    com_set_speed((unsigned long)38400);
    //com_flush_tx();   /*清空发送缓冲区*/
    //com_flush_rx();   /*清空接收缓冲区*/
}
/*************LQ's FUNCTION END*********/


main()
{
 unsigned char t_idx,m,n;
 
 Timer_Init();
 LED_init();
 Init5017H(0);
 InitCom();
 t_idx=Timer_Set(100); /*set time 100ms */

 while(1)
 {
  while(tmArriveCnt[t_idx]==0)  /* 100ms? */
  {
   EnterCommLoop();   /*communication*/
  }
  /***************  100ms ***************/
  Timer_Reset(t_idx);    /* reset time */
  if((n==0)&&(YGS==0||YJWS==0||YGF==0||YYF==0||YGZ1==0||YGZ2==0))
  for(m=0;m<15;m++)
       {CJZ[m]=2048;n=0;}//所有的测量值都统一

  YGS=YJWS=YGF=YYF=YGZ1=YGZ2=1;//设为硬手操1打开,不可写
  
  if(RGF==1){CJZ[12]=CYSW=GF_RK;YGF=0;}//如果PC软手操打开,硬手操关闭
  if(RYF==1){CJZ[13]=CYST=YF_RK;YYF=0;}
  if(RGZ1==1){CJZ[8]=GZF1=GZ_RK1;YGZ1=0;}
  if(RGZ2==1){CJZ[9]=GZF2=GZ_RK2;YGZ2=0;}  
  if(Rgs==1){CJZ[0]=gsi=Gsfk_z;YGS=0;}
  if(Rjs==1){CJZ[1]=jsi=Jsfk_z;YJWS=0;}
  
   if((n==0)&&(Wgs==0||Wjs==0||Wgf==0||Wyf==0||Wrs==0))  
      //传送调解参数,没有写入标记
    {
     for(m=0;m<14;m++)	
      {Gsz[m]=100;
       Jsz[m]=100;
       }
    }
 
    
  }
} ...

http://www.hackchina.com/r/95026/mysql_version.h__html

你可能感兴趣的:(自定义通讯协议)