基于libmodbus的QT串口相关(二)——源代码解读——CPP文件内容

一.类内容

对于main.cpp文件,是常见的QT生成UI界面的程序。

对于头文件中的widget类部分,成员函数有

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void on_comboBox_BoTeLv_currentIndexChanged(const QString &arg1);

    void on_comboBox_DataBit_currentIndexChanged(const QString &arg1);

    void on_comboBox_Port_currentIndexChanged(const QString &arg1);

    void on_comboBox_JiaoYanBit_currentIndexChanged(const QString &arg1);

    void on_comboBox_StopBit_currentIndexChanged(const QString &arg1);

    void on_BTN_OpenPLC_clicked();

    void on_BTN_ClosePLC_clicked();

    void on_BTN_Write_clicked();

    void on_radioButton_XianQuan_clicked();

    void on_radioButton_JiCunQI_clicked();

    void on_BTN_Read_clicked();

private:
    Ui::Widget *ui;
    modbus_t *plc;//libmodbus自带的,不透明数据类型
};

二.public成员函数

析构函数释放了ui的指针内存

Widget::~Widget()
{
    delete ui;
}

对于构造函数,ui->setupUi(this)不讨论。后面代码以注释形式展示

foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())//用于遍历输入对象的系统可用串行端口
{
   QSerialPort serial;//定义一个端口
   serial.setPort(info);//将serial和info设置在一起
   if(serial.open(QIODevice::ReadWrite))//如果串口以读写方式成功打开
   {
      ui->comboBox_Port->addItem(serial.portName());//向串口号comboBox组建添加端口名信息
      serial.close();//关闭设备,重置错误字符串
   }

    ui->comboBox_BoTeLv->addItem("4800");//向波特率组件添加4800
    ui->comboBox_BoTeLv->addItem("9600");//向波特率组件添加9600
    ui->comboBox_BoTeLv->addItem("19200");//向波特率组件添加19200
    ui->comboBox_BoTeLv->addItem("115200");//向波特率组件添加115200
    ui->comboBox_BoTeLv->setCurrentText("9600");//波特率组件默认设置9600
    ui->comboBox_DataBit->addItem("6");//数据位组件添加6
    ui->comboBox_DataBit->addItem("7");//数据位组件添加7
    ui->comboBox_DataBit->addItem("8");//数据位组件添加8
    ui->comboBox_DataBit->setCurrentText("8");//数据位组件默认设置为8
    ui->comboBox_JiaoYanBit->addItem("O");//校验位组件添加O
    ui->comboBox_JiaoYanBit->addItem("E");//校验位组件添加E
    ui->comboBox_JiaoYanBit->addItem("N");//校验位组件添加N
    ui->comboBox_JiaoYanBit->setCurrentText("N");//校验位组件默认设置为N
    ui->comboBox_StopBit->addItem("0");//停止位组件添加0
    ui->comboBox_StopBit->addItem("1");//停止位组件添加1
    ui->comboBox_StopBit->setCurrentText("1");//停止位组件默认设置为1
}

对于其它几个响应槽函数,则有

void Widget::on_comboBox_BoTeLv_currentIndexChanged(const QString &arg1)//改变波特率组件的文字内容
{
    qDebug() << ui->comboBox_BoTeLv->currentText();//将波特率组件内容设置为输入内容
}

对于void Widget::on_BTN_OpenPLC_clicked(),即打开串口,有

void Widget::on_BTN_OpenPLC_clicked()//打开串口槽函数
{
    QString Port = ui->comboBox_Port->currentText();//定义一个port字符串并赋值为comboBox_Port组件当前文本
    int BoTeLv = ui->comboBox_BoTeLv->currentText().toInt();//将波特率转化为的数字赋值给int
    QString JiaoYanBit = ui->comboBox_JiaoYanBit->currentText();//定义一个JiaoYanBit字符串并赋值为comboBox_JiaoYanBit组件当前文本
    int DataBit = ui->comboBox_DataBit->currentText().toInt();//将数字位转化为的数字赋值给int
    int StopBit = ui->comboBox_StopBit->currentText().toInt();//将停止位转化为的数字赋值给int
    int SheBeiDiZhi = ui->lineEdit_SheBeiDiZhi->text().toInt();//将设备地址转化为数字赋值给int
    const char *port = Port.toLatin1().constData();//将字节数组传递给char*以qbytearray形式返回字符串的拉丁文-1表示形式。 
    if(JiaoYanBit == "O")
    {
        plc = modbus_new_rtu(port, BoTeLv, 'O', DataBit, StopBit);//生成一个modbus_t *结构体指针返回给PLC变量并执行相关RTU模型通信配置,采用奇数校验
    }
    else if(JiaoYanBit == "E")
    {
        plc = modbus_new_rtu(port, BoTeLv, 'E', DataBit, StopBit);//同上,采用偶数校验
    }
    else if(JiaoYanBit == "N")
    {
        plc = modbus_new_rtu(port, BoTeLv, 'N', DataBit, StopBit);//同上,无奇偶校验
    }
    qDebug() << Port;//输出端口号
    qDebug() << QString::number(BoTeLv, 10);//将BoTeLv变量转化为10进制
    qDebug() << JiaoYanBit;//输出校验位
    qDebug() << QString::number(DataBit, 10);//将DataBit变量转化为10进制
    qDebug() << QString::number(StopBit, 10);//将StopBit变量转化为10进制
    plc = modbus_new_rtu(port, BoTeLv, 'N', DataBit, StopBit);生成一个modbus_t *结构体指针返回给PLC变量并执行相关RTU模型通信配置,采用无奇偶校验
    modbus_set_slave(plc, SheBeiDiZhi);//设置从机的设备地址
    qDebug() << QString::number(SheBeiDiZhi, 10);//将SheBeiDiZhi变量转化为10进制
    int plccount = modbus_connect(plc);//与PLC变量建立连接
    struct timeval time;//实例化一个timeval的结构体
    time.tv_sec = 0;//0s
    time.tv_usec = 1000000;//1000000us
    modbus_set_response_timeout(plc, (int)&time.tv_sec, (int)&time.tv_usec);//设置响应时间
    if(plccount == 0)
    {
        qDebug() << "连接PLC成功";//输出连接PLC成功
    }
    else
    {
        qDebug() << "连接PLC失败";//输出连接PLC失败
    }
}

对于qDebug函数,使用数据流输出需要加入头文件#include<QDebug>,将字符串当做传参的话不需要加入相关头文件。

对于void Widget::on_BTN_ClosePLC_clicked()函数

void Widget::on_BTN_ClosePLC_clicked()
{
    modbus_close(plc);//关闭跟plc变量的连接
    modbus_free(plc);//释放modbus环境
}

有两个函数是QDebug,调用radioButton组件不管。对于on_BTN_Write_clicked()函数:

void Widget::on_BTN_Write_clicked()
{
    int Adress = ui->lineEdit_JiCunQiDIZhiWrite->text().toInt();//将写寄存器地址赋值给adress
    int ShuZhi = ui->lineEdit_JiCunQiShuZhi->text().toInt();//将写寄存器数值赋值给ShuZhi
    if(ui->radioButton_XianQuan->isChecked() == true)//如果线圈的radiobutton被按下
    {
        qDebug() << "写入线圈";
        modbus_write_bit(plc, Adress, ShuZhi);//强制单线圈
    }
    else//如果寄存器的radiobutton被按下
    {
       qDebug() << "写入寄存器";
       modbus_write_register(plc, Adress, ShuZhi);//强制单寄存器
    }
}

对于on_BTN_Read_clicked()函数:

void Widget::on_BTN_Read_clicked()
{
    uint16_t read_reg[255] = {0};//定义一个unsigned short数组
    uint8_t read_reg_bit[255] = {0};//定义一个unsigned char数组
    int Adress = ui->lineEdit_JiCunQiDIZhiRead->text().toInt();//将读寄存器地址赋值给Adress 
    int Count = ui->lineEdit_Count->text().toInt();/将读寄存器数量赋值给Count 
    if(ui->radioButton_XianQuan->isChecked() == true)//线圈radiobutton是否被按下
    {
        qDebug() << "读取线圈";
        for (int i = 0; i < Count; i++)
        {
            modbus_read_bits(plc, Adress, Count, read_reg_bit);//读取线圈状态
            qDebug() << read_reg_bit[i];//输出线圈状态
        }
    }
    else//如果寄存器被按下
    {
       qDebug() << "读取寄存器";
       for (int i = 0; i < Count; i++)
       {
           modbus_read_registers(plc, Adress, Count, read_reg);//读取保存寄存器
           qDebug() << read_reg[i];//输出寄存器内容
       }
    }
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值