QT串口通信(1)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011939264/article/details/51815385

       最近帮老师做的项目中使用到了QT串口,然后首先百度了一下,发现网上的QT串口代码都是同一个版本。而且没有公开源代码,遂自己写了个简单的串口通信代码,并将它公布出来,一方面供有需要的人参考,另一方面记录下来,也可以防止自己忘记了。
       本项目没有用到QT自带的串口通信模块,使用了第三方库qextserialport,这个库基本已经满足了串口所有的功能,而且上手也快。好了。废话不多说了,先来张效果图吧。

50

       这是整体效果图,主要实现的是开发板和下位机通信,上位机通过串口发送指令给下位机,下位机再执行相应的操作。本文主要讲讲串口通信的部分吧。
       简单来说,串口通信分为三部分:1:设置端口号和波特率等等,数据位和校验之类的一般的可以提前设定好,再代码中同样也可以设定。2:将数据写入串口,这个时候就要分发送的是多少进制的数据了,虽然计算机在实际存储时是不区分进制的。3:读串口数据,将串口接收到的数据读出来,进行下一步处理。后面我会把全部代码贴出来,代码经过调试已经可以运行了。本文中具体的控件布局我就不讲了,我只讲讲一些核心的代码,大家感兴趣的话可以自己去跑跑我的代码,代码中注释非常详细,每一行都有注释,看起来不费劲。

设置端口和波特率

 //打开串口,波特率和端口号可以通过下拉菜单进行选择
void uwiCMonitorPC::on_openMyComBtn_clicked()
{
    QString portName = portNameComboBox->currentText(); //获取串口名
    myCom = new Win_QextSerialPort(portName,QextSerialBase::EventDriven);
    //定义串口对象,并传递参数,在构造函数里对其进行初始化
    myCom ->open(QIODevice::ReadWrite); //打开串口
    if(baudRateComboBox->currentText()==tr("38400")) //根据下拉菜单中内容对串口进行设置
    //设置波特率
    myCom->setBaudRate(BAUD38400);
    else if(baudRateComboBox->currentText()==tr("115200"))
    myCom->setBaudRate(BAUD115200);
    //设置数据位
    myCom->setDataBits(DATA_8);
    //设置奇偶校验
    myCom->setParity(PAR_NONE);
    //设置停止位 
    myCom->setStopBits(STOP_1);    
    myCom->setFlowControl(FLOW_OFF);  //设置数据流控制,我们使用无数据流控制的默认设置
    myCom->setTimeout(500);  //设置延时
    connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));
    //信号和槽函数关联,当串口缓冲区有数据时,进行读串口操作
    openMyComBtn->setEnabled(false); //打开串口后“打开串口”按钮不可用
    closeMyComBtn->setEnabled(true); //打开串口后“关闭串口”按钮可用
    sendMsgBtn->setEnabled(true); //打开串口后“发送数据”按钮可用
	O2U1->setEnabled(true);
	O2U2->setEnabled(true);
	O2U3->setEnabled(true);
    baudRateComboBox->setEnabled(false); //设置各个组合框不可用
    portNameComboBox->setEnabled(false);
}

    在端口设置和波特率配置中,主要用到的控件有QComboBox,可以实现下拉菜单功能,还没用过这个控件的小伙伴可以自行百度下,很简单的啦。

写串口数据

//发送消息
void uwiCMonitorPC::on_sendMsgBtn_clicked()
{ 
if(O2U1->isChecked()||O2U2->isChecked()||O2U3->isChecked())//判断选择的是那种功能
{
	QString num;
	if(O2U1->isChecked())//配置查询
	{
	  int table[20]={0x2e,0x2d,0x3d,0x3e,0x00,0x0d,0x01,0x00,0x00,0x00,0x00};
	  int *p=table;
	  int wCRC =CRC16(p,11);
	  table[11]=wCRC>>8;
	  table[12]=wCRC&0x00ff;
	  for(int i=0;i<13;i++)
		num+=table[i];
	 }	
	else if(O2U2->isChecked())//地址配置
	{
      int table[20]={0x2e,0x2d,0x3d,0x3e,0x00,0x11,0x02,0x00,0x00,0x00,0x00,0x00,0x0c,0x01,0x02};
	  table[11]=edit1->text().toInt();
	  int *p=table;
	  int wCRC =CRC16(p,15);
	  table[15]=wCRC>>8;
	  table[16]=wCRC&0x00ff;
	  for(int i=0;i<17;i++)
		num+=table[i];
	}
	else if(O2U3->isChecked())//功能配置
	{
       int table[20]={0x2e,0x2d,0x3d,0x3e,0x00,0x0e,0x03,0x00,0x00,0x00};
	   if(device->currentText()==tr("投料机"))           table[10]=0x01;
	   else if(device->currentText()==tr("增氧泵"))      table[10]=0x02;
	   else if(device->currentText()==tr("三合一"))      table[10]=0x03;
	   else if(device->currentText()==tr("氨  氮"))      table[10]=0x04;
	   else if(device->currentText()==tr("气象站"))      table[10]=0x05;
	   else if(device->currentText()==tr("三合一和氨氮")) table[10]=0x06;
	   else                                             table[10]=0x07;
	   table[11]=edit5->text().toInt();
	   int *p=table;
	   int wCRC =CRC16(p,12);
	   table[12]=wCRC>>8;
	   table[13]=wCRC&0x00ff;
	   for(int i=0;i<14;i++)
		num+=table[i];
	 
	}
	QByteArray outData=num.toAscii();//将16进制数转化为可以发送的QByteArray 数据
    myCom->write(outData);//将数据写入串口
}

    数据格式转换真心累啊,我在后面中会给大家介绍我在数据格式转换中遇到的坑,大家可以参考,写入数据部分,其实最主要的控件就是一个lineedit,也即文本框,将要发送的数据输入到文本框,然后读取文本框中的内容即可 table[11]=edit1->text().toInt();将edit1中输入的内容转换成10进制,并存贮在table中,然后就可以写入串口了,当然怎么写入的我们就可以不用管了,你只要负责把数据准备好就可以了,直接送到函数 myCom->write(outData);中就可以了,调用了第三方库,很多步骤我们都省了。

读串口数据

if (myCom->bytesAvailable()<=0)
{return;}//如果没有收到数据就返回
	Sleep(100);//延时100ms确保数据可以一次读出
    QByteArray temp = myCom->readAll();//得到全部数据
	QString tempDataHex=uwiCMonitorPC::ByteArrayToHexStr(temp);//字节数组变为字符串
    textBrowser->insertPlainText(tempDataHex+"\n");	//返回数据显示

    读串口部分也就是一个函数 myCom->readAll();读之前需要延时一段时间以确保串口数据可以一次接受完成。将得到的数据转换为QString类型,然后就可以送进去显示了。

    串口通信主要的核心部分大概就是这三部分了,调用第三方库,主要难点就在于数据类型转换,因为串口发送和文本框接受显示的数据类型是不一样的,还有发送16进制数据时也得进行数据类型转换。反正我在格式转换上面花了很多时间,我在下篇博客中会贴出各种格式转换的代码,供大家参考。
    对串口通信原理不了解的可以自己先去网上自行了解下原理,等了解原理后再写串口程序就游润有余了,整个代码我已经打包好了,只要用cmake编译下就可以运行了(所有的控件都是用代码实现的,没有基于qt caeater,控件不是拖拽来的,当然为了学习,为了提高代码能力,我建议不拖拽,如果在实际项目中那就不一样了),我过会会将所有代码上传,有问题的欢迎留言讨论。


关于我自己

  • 一个正派但不正经的程序员

  • 18年计算机专业硕士毕业生,腾讯SNG部门实习生,现加盟快手科技 ,后端研发工程师一枚

  • 喜欢技术,喜欢互联网

  • 民遥控 ,赵雷、陈粒、宋冬野

  • 公众号:编程美学,时不时写篇文章,偶尔数羊,其实说到底,只是想和你聊聊
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u011939264/article/details/51815385