欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

接受不定长协议:

程序员文章站 2022-03-07 09:33:31
...

协议头+数据长度+命令码+数据+校验码

协议头(2字节) 数据长度(1字节) 命令码(1字节) 数据(N-2字节) 校验码(1)
0x55,0xaa 除协议头和数据长度以外的数据,N字节 从0x01开始 可以为空 除校验码以外的所有数据和,取低8位
0 1 2 3 4 5
55 aa N cmd date add

1.命令码输液报警器->上位机

命令码 说明 数据
0x00 收到上位机消息应答 1字节,返回收到消息的命令号
0x01 上传输液报警器的ID 6字节,
0x02 上传输液报设置号码 1字节
0x03 上传输液报警器设定滴速 1字节
0x04 上传输液报警器当前状态 1字节
0x05 上传输液报警器当前滴速与总滴数 1字节+4字节

0x01 ID 0代表没有ID

0x02 号码 0代表还没设号

0x03 滴速 0代表没有设置

0x04 输液报警状态

00正常 01过块 02过慢 03阻塞 04暂停 05完成 06移动 07报警08空闲

2.上位机->输液报警器

命令码 说明 数据1字节
0x80 收到输液报警器消息应答 返回收到消息的命令号
0x81 查询输液报警器ID
0x82 查询输液报警器号码
0x83 查询输液报警器设定滴速
0x84 查询输液报警器当前状态
0x85 查询输液报警器当前滴速与总滴数
0x86 查询

uint8_t S_buff[255];
uint8_t len_s=0,len_temp=0;//开始与结束位置
void MainWindow::serialPortReadyRead()
{
    /* 接收缓冲区中读取数据 */
    uint8_t *str_buf;
    uint8_t sum,temp;
    int i;
    uint8_t b;
    char float_str[80];

    QString AA="输液报警器状态:";
    QString strA ,strB;
    QByteArray date = serialPort->readAll();
    int len=date.size();
     //1.将数据放到缓存空间,计算位置
    //2.从缓存空间开始位置,查到一条命令并处理命令
    //3.处理完成重新计算缓存空间.
    for(i=0;i<len;i++)
    {
        S_buff[len_s+i]=  date[i];
    }
    len_s=len_s+i;
    if(len_s<5)//说明收半包数据
    {
        qDebug("*半包数据*");
        return;
    }
    for(i=0;i<len_s;i++)
    {
        if(i+6>len_s)//说明后面 6个数据都是存在的
        {
            return;
        }
        if(S_buff[i]==0x55&&S_buff[i+1]==0xaa)//头存在
        {
            uint8_t k=i;//记录开始
            uint8_t m;
            //去掉之前错误的数据 数据左移i
            if(k!=0)
            {
                for(m=k;m<len_s;m++)
                {
                    S_buff[m-k]=S_buff[m];
                }
                //重新计算长度
                len_s=len_s-k;
                i=0;//归位
            }
            //55 aa移动到 0位置

            if((S_buff[2]+3)<=len_s)//通过数据长度判断是正包还是半包,
            {//正包

                sum=0;
                for(uint8_t n=0; n<(S_buff[2]+2); n++)
                {
                    sum=S_buff[n]+sum;
                }
                if(S_buff[S_buff[2]+2]!=sum)
                {
                    qDebug("ble_del e -crc");//移除错误的数据
                }else
                {
                    switch(S_buff[3])
                    {
                    case 0:

                        break;
                    case 1:
                        for(temp=0;temp<6;temp++)
                        {
                            ID[temp]= S_buff[4+temp];

                        }
                        sprintf(float_str, "ID:%d",123456);
                        label2[0]->setText(float_str);
                        qDebug("收到ID");

                        break;
                    case 2://设置的号码
                        num=S_buff[4];
                        qDebug("设置号码");

                        sprintf(float_str, "输液号码:%d",num);
                        label2[1]->setText(float_str);
                        break;
                    case 3://设置的滴速 "ID:"<<"输液号码:"<<"设定的滴速:"<<"输液报警器状态:"<<"滴速: 总滴数:";

                        set_speed=S_buff[4];
                        qDebug("设置速度");
                        // receivedData_real(set_speed);
                        sprintf(float_str, "设定的滴速:%d",set_speed);
                        label2[2]->setText(float_str);
                        break;
                    case 4://读取的状态
                        stat=S_buff[4];
                        qDebug("读取状态");

                        switch(stat)
                        {
                        case 0:
                            label2[3]->setText(AA+"正常");
                            break;
                        case 1:
                            label2[3]->setText(AA+"过快");
                            break;
                        case 2:
                            label2[3]->setText(AA+"过慢");
                            break;
                        case 3:
                            label2[3]->setText(AA+"阻塞");
                            break;
                        case 4:
                            label2[3]->setText(AA+"暂停");
                            break;
                        case 5:
                            label2[3]->setText(AA+"完成");
                            break;
                        case 6:
                            label2[3]->setText(AA+"移动");
                            break;

                        }
                        break;
                    case 5://当前速度和滴数
                        speed=S_buff[4];
                        DOP_sum=S_buff[5]+(uint32_t)(S_buff[6]<<8)+(uint32_t)(S_buff[7]<<16)+(uint32_t)(S_buff[8]<<24);//低位在前
                        receivedData_real(set_speed);
                        receivedData(speed);

                        qDebug("--滴速--");

                        //  sprintf(float_str, "滴速:%d 总滴数%ld",speed,DOP_sum);
                        strA=QString::number(speed);
                        strB=QString::number((uint)DOP_sum,10);

                        label2[4]->setText("滴速:"+strA+"  总滴数:"+strB);
                        break;

                    }
                    len_s=len_s-(S_buff[2]+3);
                     b= S_buff[2]+3;
                    if(len_s>0)//说明还有数据
                    {
                        for(m=0;m<len_s;m++)
                        {
                            S_buff[m]=S_buff[b+m];
                        }
                        i=0;//归位
                    }

                }
              // len_s=len_s-k;

            }else//半包
            {

                break;//跳出循环不再判断
            }
        }


    }

    //解析协议
}

相关标签: 协议栈