QT 串口发送接收(带发送缓冲区)

QT 串口发送接收(带发送缓冲区)

串口代码更改,这里记录一下。接收因为是类似于中断的方式,接收一次处理一次,就没做接收缓冲区。与主板通讯模式为主从模式,串口发送函数用时钟轮询该函数。


变量定义

unsigned char serial_main::Send_Buf[30000][300];//发送缓冲区
unsigned char serial_main::recv_buf[150];//查询接收数据数组

串口初始化

/*********通讯串口初始化*******/
void serial_main::serial_port_init()
{
    qDebug()<<"serial port init.";
    serial_port_1 = new QSerialPort(this);
   //open_serial(m_com4,"/dev/ttyS1");
    open_serial(serial_port_1,"/dev/ttySAC1");
}

打开串口

/********打开串口***********/
void serial_main::open_serial(QSerialPort *serial, QString name)
{
    qDebug()<<"serial port open.";
    serial->setPortName(name);
    serial->setBaudRate(QSerialPort::Baud115200);//设置波特率和读写方向
//    serial->setBaudRate(QSerialPort::Baud57600);//设置波特率和读写方向
    serial->setDataBits(QSerialPort::Data8);		//数据位为8位
    serial->setParity(QSerialPort::EvenParity);	//偶验位
    serial->setFlowControl(QSerialPort::NoFlowControl);//无流控制
    serial->setStopBits(QSerialPort::OneStop); //一位停止位
    if(serial->open(QIODevice::ReadWrite))
    {
        //连接串口接收
        connect(serial, &QSerialPort::readyRead,this,&serial_main::receiveData);
        //连接接收分析函数
        connect(this,SIGNAL(receiveData_analysis_switch_1(QByteArray ,QString )),receive_data_main,SLOT(receiveData_analysis_switch_1(QByteArray ,QString )));
        qDebug()<<"open com" << name << "success!";
        //发送缓冲区初始化
        connect(this,SIGNAL(txd_rxd_data_init()),send_data_main,SLOT(txd_rxd_data_init()));
        emit txd_rxd_data_init();//初始化发送数据缓冲区,发送功能号0x02数据读取主板数据

        qDebug()<<"txd rxd data success!";
        return ;
    }
    else
    {
        qDebug()<<"open com" << name << "failed!";
    }
}

串口发送函数

/*******串口发送函数*********/
void serial_main::sendDate()
{
//    if(Send_fail==0)
//    {
        QByteArray data,temp;
        if(serial_main::Send_Buf[0][0]==0x00)//查询
        {
            unsigned char temp_query_buf[15];
            unsigned int chk = 0;
            temp_query_buf[0] = 0x33;//头
            temp_query_buf[1] = 0x43;//主板编号
            temp_query_buf[2] = 0x0f;//帧长度
            temp_query_buf[3] = 0xff;//随机生成唯一标识符高位
            temp_query_buf[4] = 0xff;//随机生成唯一标识符低位
            temp_query_buf[5] = 0x2c;//功能号
            temp_query_buf[6] = 0x00;//数据地址高位
            temp_query_buf[7] = 0x00;//数据地址低位
            temp_query_buf[8] = 0x00;//数据包序号,0表示没有分包
            temp_query_buf[9] = 0x00;//总数据分成了多少个包,0表示没有分包
            temp_query_buf[10] = 0x01;//当前数据包数据长度

            temp_query_buf[11] = 0x01;//数据内容

            for(int i=0; i <12; ++i)chk = (serial_main::crc16_tab[((chk>>8) ^ temp_query_buf[i]) & 0xFF] ^ (chk << 8));
            temp_query_buf[12] = (chk >> 8);//CRC校验高位
            temp_query_buf[13] = (chk );//CRC校验低位
            temp_query_buf[14] = 0x0d;//尾巴

            for(int i=0;i<15;i++)
            {
                data.clear();
                data.append(temp_query_buf[i]);
                serial_port_1->write(data);
            }

        }
        else
        {
            trans_size = Send_Buf[0][2];
            for(int i=0;i<trans_size;i++)
            {
                data.clear();
                data.append(serial_main::Send_Buf[0][i]);
                temp.append(QString::number(serial_main::Send_Buf[0][i], 16));
                temp.append("-");
                serial_port_1->write(data);
            }
//            qDebug()<<temp<<trans_size;
//            emit ButtonCommunicationDisplay_Send("SendDate:"+temp+" "+"size:"+QString::number(trans_size));
        }

//        /***************************************************************************/
//    //    qDebug()<<"TimeoutCount"<<TimeoutCount;
//        if(serial_main::TimeoutCount>=50000)
//            emit DictionaryQueryComplete(tr("通讯异常,请检查线路或程序是否匹配!"));
//        else
//            serial_main::TimeoutCount++;
//        /***************************************************************************/
//    }
}

发送缓冲区插入

/***********发送缓冲区插入main函数***********/
void serial_send_data::txd_All(int FuntionNumber,unsigned int address,int DateNumber,int DateLength_All,QString txd_date)
{
    switch(FuntionNumber)
    {
        case 0x66://停止命令
        {
            //遍历缓存区,原始数据下移,此数据插入第一行
            txd_All_0x66(FuntionNumber,address,DateNumber,DateLength_All,txd_date);
            break;
        }
//        case 0x16://手动的伺服动作
//        {
//            //清空缓冲区,此数据插入第一行
//            txd_All_0x16(FuntionNumber,address,DateNumber,DateLength_All,txd_date);
//            break;
//        }
        default:
        {
            //插入缓存区末尾
            txd_All_default(FuntionNumber,address,DateNumber,DateLength_All,txd_date);
            break;
        }
    }

//    QString temp_SendBug;
//    for(int i=0;i<tail_pointer+1;i++)
//    {
//        for(int j=0;j<trans_size;j++)
//        {
//            QByteArray temp;
//            temp.append(Send_Buf[i][j]);
//            temp_SendBug += temp.toHex();
//            temp_SendBug += "-";
//        }
//        qDebug()<<"Send_Buf:"<<temp_SendBug;
//        temp_SendBug.clear();
//    }

    serial_main::long_set_flag = 1;

//    stopbz=1;
//    tx_count=0;
//    commandflag=1;
//    myreadstate.manualflag=2;
}
/*********停止命令 遍历缓存区,原始数据下移,此数据插入第一行**********/
void serial_send_data::txd_All_0x66(int FuntionNumber,unsigned int address,int DateNumber,int DateLength_All,QString txd_date)
{
    bool ok;
    int j=11;
    unsigned int chk=0;
    QByteArray Data_ByteArray;
    /*********************************************************************/
    int Tail_Pointer = 0;
    for(int i=0;i<30000;i++)
    {
        if(serial_main::Send_Buf[i][0]==0x00)
        {
            Tail_Pointer = i;
            break;
        }
    }
    for(int i=Tail_Pointer;i>0;i--)
    {
        for(int j=0;j<300;j++)
        {
            serial_main::Send_Buf[i][j] = serial_main::Send_Buf[i-1][j];
        }
    }
    /*********************************************************************/
    QTime randtime;
    randtime = QTime::currentTime();
    qsrand(randtime.msec()+randtime.second()*1000); //以当前时间ms为随机种子
    serial_main::Send_RandomNumber = qrand() % 6000;    //产生0~6000的随机整数

    serial_main::Send_Buf[0][0] = SYNC;//0x33
    serial_main::Send_Buf[0][1] = SM_ADDR;//0x43
    serial_main::Send_Buf[0][2] = (14+(txd_date.length()/2));//帧长度
    serial_main::Send_Buf[0][3] = (serial_main::Send_RandomNumber&0xff00)>>8;//以随机数生成唯一标识符
    serial_main::Send_Buf[0][4] = (serial_main::Send_RandomNumber&0x00ff);
    serial_main::Send_Buf[0][5] = FuntionNumber;//功能号,0~255
    serial_main::Send_Buf[0][6] = (address&0xff00)>>8;//数据地址
    serial_main::Send_Buf[0][7] = (address&0x00ff);
    serial_main::Send_Buf[0][8] = DateNumber;//数据包序号,0表示没有分包
    serial_main::Send_Buf[0][9] = DateLength_All;//总数据分成了多少个包,0表示没有分包
    serial_main::Send_Buf[0][10] = (txd_date.length()/2);//当前数据包数据长度

    for(int i=0;i<txd_date.length()/2;i++)
    {
        Data_ByteArray.clear();
        Data_ByteArray.append(txd_date.mid(2*i, 2));
        serial_main::Send_Buf[0][j] = Data_ByteArray.toInt(&ok, 16);//将字符串代表的16进制数转换成10进制
        j++;
    }
    /*********************************************************************/
    for(int i=0; i <j; ++i)
    chk = serial_main::crc16_tab[((chk>>8) ^ serial_main::Send_Buf[0][i]) & 0xFF] ^ (chk << 8);
    serial_main::Send_Buf[0][j] = (chk >> 8);
    serial_main::Send_Buf[0][j+1] = (chk );
    serial_main::Send_Buf[0][j+2]=FRAME_END;
//    sys_txd.combuf[3]=sys_txd.combuf[3]+2;
//    memcpy(ser_queue[XMIT_QUEUE].entry[temp].buf,sys_txd.combuf,j+2);
    serial_main::trans_size=j+3;
//    if (myreadstate.manualflag!=0)
//          txerrcount=200;
    /*********************************************************************/
}
/********手动的伺服动作 清空缓冲区,此数据插入第一行**********/
void serial_send_data::txd_All_0x16(int FuntionNumber,unsigned int address,int DateNumber,int DateLength_All,QString txd_date)
{
    bool ok;
    int j=11;
    unsigned int chk=0;
    QByteArray Data_ByteArray;
    /************************************************/
    for(int i=0;i<30000;i++)
    {
        for(int j = 0;j<300;j++)serial_main::Send_Buf[i][j] = 0x00;
    }
    /************************************************/
    QTime randtime;
    randtime = QTime::currentTime();
    qsrand(randtime.msec()+randtime.second()*1000); //以当前时间ms为随机种子
    serial_main::Send_RandomNumber = qrand() % 6000;    //产生0~6000的随机整数

    serial_main::Send_Buf[0][0] = SYNC;//0x33
    serial_main::Send_Buf[0][1] = SM_ADDR;//0x43
    serial_main::Send_Buf[0][2] = (14+(txd_date.length()/2));//帧长度
    serial_main::Send_Buf[0][3] = (serial_main::Send_RandomNumber&0xff00)>>8;//以随机数生成唯一标识符
    serial_main::Send_Buf[0][4] = (serial_main::Send_RandomNumber&0x00ff);
    serial_main::Send_Buf[0][5] = FuntionNumber;//功能号,0~255
    serial_main::Send_Buf[0][6] = (address&0xff00)>>8;//数据地址
    serial_main::Send_Buf[0][7] = (address&0x00ff);
    serial_main::Send_Buf[0][8] = DateNumber;//数据包序号,0表示没有分包
    serial_main::Send_Buf[0][9] = DateLength_All;//总数据分成了多少个包,0表示没有分包
    serial_main::Send_Buf[0][10] = (txd_date.length()/2);//当前数据包数据长度

    for(int i=0;i<txd_date.length()/2;i++)
    {
        Data_ByteArray.clear();
        Data_ByteArray.append(txd_date.mid(2*i, 2));
        serial_main::Send_Buf[0][j] = Data_ByteArray.toInt(&ok, 16);//将字符串代表的16进制数转换成10进制
        j++;
    }
    /*********************************************************************/
    for(int i=0; i <j; ++i)
    chk = serial_main::crc16_tab[((chk>>8) ^ serial_main::Send_Buf[0][i]) & 0xFF] ^ (chk << 8);
    serial_main::Send_Buf[0][j] = (chk >> 8);
    serial_main::Send_Buf[0][j+1] = (chk );
    serial_main::Send_Buf[0][j+2]=FRAME_END;
//    sys_txd.combuf[3]=sys_txd.combuf[3]+2;
//    memcpy(ser_queue[XMIT_QUEUE].entry[temp].buf,sys_txd.combuf,j+2);
    serial_main::trans_size=j+3;
//    if (myreadstate.manualflag!=0)
//          txerrcount=200;
    /*********************************************************************/
}
/*******插入缓冲区末尾***********/
void serial_send_data::txd_All_default(int FuntionNumber,unsigned int address,int DateNumber,int DateLength_All,QString txd_date)
{
    bool ok;
    int j=11;
    unsigned int chk=0;
    QByteArray Data_ByteArray;

    int tail_pointer = 0;
    for(int i=0;i<30000;i++)
    {
        if(serial_main::Send_Buf[i][0]==0x00)
        {
            tail_pointer = i;
            break;
        }
    }

    serial_main::Send_RandomNumber = qrand() % 6000;    //产生0~6000的随机整数

    serial_main::Send_Buf[tail_pointer][0] = SYNC;//0x33
    serial_main::Send_Buf[tail_pointer][1] = SM_ADDR;//0x43
    serial_main::Send_Buf[tail_pointer][2] = (14+(txd_date.length()/2));//帧长度
    serial_main::Send_Buf[tail_pointer][3] = (serial_main::Send_RandomNumber&0xff00)>>8;//以随机数生成唯一标识符
    serial_main::Send_Buf[tail_pointer][4] = (serial_main::Send_RandomNumber&0x00ff);
    serial_main::Send_Buf[tail_pointer][5] = FuntionNumber;//功能号,0~255
    serial_main::Send_Buf[tail_pointer][6] = (address&0xff00)>>8;//数据地址
    serial_main::Send_Buf[tail_pointer][7] = (address&0x00ff);
    serial_main::Send_Buf[tail_pointer][8] = DateNumber;//数据包序号,0表示没有分包
    serial_main::Send_Buf[tail_pointer][9] = DateLength_All;//总数据分成了多少个包,0表示没有分包
    serial_main::Send_Buf[tail_pointer][10] = (txd_date.length()/2);//当前数据包数据长度


    for(int i=0;i<txd_date.length()/2;i++)
    {
        Data_ByteArray.clear();
        Data_ByteArray.append(txd_date.mid(2*i, 2));
        serial_main::Send_Buf[tail_pointer][j] = Data_ByteArray.toInt(&ok, 16);//将字符串代表的16进制数转换成10进制
        j++;
    }
    /*********************************************************************/
    for(int i=0; i <j; ++i)
    chk = serial_main::crc16_tab[((chk>>8) ^ serial_main::Send_Buf[tail_pointer][i]) & 0xFF] ^ (chk << 8);
    serial_main::Send_Buf[tail_pointer][j] = (chk >> 8);
    serial_main::Send_Buf[tail_pointer][j+1] = (chk );
    serial_main::Send_Buf[tail_pointer][j+2]=FRAME_END;
    //    sys_txd.combuf[3]=sys_txd.combuf[3]+2;
    //    memcpy(ser_queue[XMIT_QUEUE].entry[temp].buf,sys_txd.combuf,j+2);
    serial_main::trans_size=j+3;
//    if (myreadstate.manualflag!=0)
//          txerrcount=200;
    /*********************************************************************/
}

使用例子

QString temp_string = NULL;
            int temp_int = ui->speed_lineedit->text().toInt();
            int temp_position_plus = (ui->position_plus_lineedit->text().toFloat())*100;
            int temp_position_re = (ui->position_reduce_lineedit->text().toFloat())*100;

            temp_string += "70";//按钮命令值
            temp_string += "00";//轴选择命令值
            temp_string += serial_send_data_1->txd_All_QStringAnalysis(temp_int);//速度
            temp_string += serial_send_data_1->txd_All_QStringAnalysis(((temp_position_plus&0xff0000)>>16));//位置+高位
            temp_string += serial_send_data_1->txd_All_QStringAnalysis((temp_position_plus&0xff00)>>8);//位置+中位
            temp_string += serial_send_data_1->txd_All_QStringAnalysis(temp_position_plus&0x00ff);//位置+低位
            temp_string += serial_send_data_1->txd_All_QStringAnalysis(((temp_position_re&0xff0000)>>16));//位置-高位
            temp_string += serial_send_data_1->txd_All_QStringAnalysis((temp_position_re&0xff00)>>8);//位置-中位
            temp_string += serial_send_data_1->txd_All_QStringAnalysis(temp_position_re&0x00ff);//位置-低位
            serial_send_data_1->txd_All(0x03,0x0070,0x00,0x00,temp_string);
QString serial_send_data::txd_All_QStringAnalysis(unsigned char analysis_string)
{
    serial_main::long_set_flag = 1;
    QString temp = NULL;
    if(QString::number(analysis_string,16).length()==1)
    {
        temp = "0"+QString::number(analysis_string,16);
    }
    else
    {
        temp = QString::number(analysis_string,16);
    }
    return temp;
}

总结

有些功能还没做完,这里记录一下。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值