设为首页 加入收藏

TOP

线程+定时实现Linux下的Qt串口编程
2014-11-24 03:22:26 来源: 作者: 【 】 浏览:1
Tags:线程 +定时 实现 Linux 串口 编程

说明:本设计采用的是线程+定时实现Linux下的Qt串口编程,而非网上资料非常多的Qt编写串口通信程序全程图文讲解系列,因为Qt编写串口通信程序全程图文讲解系列是很好实现,那只是在windows下面的,可是在Linux下面实现串口的通信并非如此,原因在于QextSerialBase::EventDriven跟QextSerialBase::Polling这两个事件的区别,EventDriven属于异步,Polling属于同步,在windows下面使用的是EventDriven很容易实现,只要有数据就会触发一个串口事件,网上说Linux下面需要的是Polling,可是还是不行的,只要串口有数据的时候他会在QByteArray temp = myCom->readAll(); 这句一直读取数据,没能退出,直到断掉串口的时候才能把接受到的串口数据通过ui->textBrowser->insertPlainText(temp);打印在界面上,一直没能解决这个问题,所以只好采用线程+定时实现Linux下的Qt串口编程进行设计。


一、安装环境:


二、软件需求及下地地址:


Qt版本 qt-Linux-SDK-4.6.2


注意:此处使用的是qt-Linux-SDK-4.6.2版本,编译通过了,之后需要把他移植到qt-embedded-Linux-opensource-src-4.5.3.tar.gz,通过qte编译后移植到开发板中,采用的测试开发板为Micro2440,


下载地址:略


三、程序编写过程


程序编程流程:


先新建一个工程空白工程,再建立Ui文件,通过designer进行Ui界面设计,设计完保存,编译生成ui_mainwindow.h头文件,编写线程头文件及线程处理.cpp文件,建立串口处理头文件及 .cpp文件,最后完成main.cpp文件。


1、 Ui文件的设计:


建立Ui_MainWindow主窗口,在窗口上添加三个QPushButton,分别命名为closeButton、writeButton、readButton,再添加一个QTextBrowser显示串口接收数据,保存退出,编译一下就可以生成ui_mainwindow.h文件。


2、线程程序设计:


编写一个线程程序,其不需要进行界面设计,直接实现线程的管理,实现串口的收发工作,其主要程序及说明如下:


1) 新建一个thread.h头文件,内容如下:


#ifndef THREAD_H


#define THREAD_H


#include


class Thread:public QThread


{


Q_OBJECT


public:


Thread();


char buf[128];


volatile bool stopped;


volatile bool write_rs;


volatile bool read_rs;


protected:


virtual void run();


};


#endif


程序定义一个Thread类,它继承于QThread,设有一些变量和一个run函数,virtual表示为虚函数,你也可以去掉,加上去会增加一些内存开销,但提高了效率,对于这个小程序是看不出什么效果的,volatile为一函数数据类型,是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量,其可以在不同数据类型间进行转化,保证对此变量的读写操作都不会被优化。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。


2)新建一个thread.cpp文件,内容如下:


#include"thread.h"


#include


#include


#include


#include //串口用到的


#include


#include


#include


#include


#define BAUDRATE B9600


#define RS_DEVICE "/dev/ttyS0" //串口1


//#define RS_DEVICE "/dev/ttySAC1" //串口1


Thread::Thread()


{} //析构


void Thread::run() //这就是线程的具体工作了


{


int fd,c=0,res;


struct termios oldtio,newtio; //termios结构是用来保存波特率、字符大小等


printf("start... ");


fd=open(RS_DEVICE,O_RDWR|O_NOCTTY); //以读写方式打开串口。不控制TTY


if(fd<0)


{


perror("error");


exit(1); //失败退出


}


printf("Open... ");


tcgetattr(fd,&oldtio); //保存当前设置到oldtio


bzero(&newtio,sizeof(newtio)); //清除newtio结构,并重新对它的成员设置如下


newtio.c_cflag=BAUDRATE|CS8|CLOCAL|CREAD; //9600、8位、忽略DCD信号、启用接收装置


newtio.c_iflag|=IGNPAR; //忽略奇偶


newtio.c_oflag=0;


newtio.c_lflag=0;


newtio.c_cc[VMIN]=0;


newtio.c_cc[VTIME]=100; //在规定时间(VTIME)内读取(VMIN)个字符;


tcflush(fd,TCIFLUSH); //清除所有队列在串口的输入与输出;


tcsetattr(fd,TCSANOW,&newtio); //把我们的设置写入termios


while(stopped) //stopped为0时将退出线程


{


if(write_rs) //write_rs为1时把字符串从串口中输出


{


write_rs=0;


write(fd,"QtEmbedded-4.5.3",16);


}


if(read_rs) //read_rs为1时读取,并存在buf


{


read_rs=0;


res=read(fd,buf,10);


buf[res]=0;


emit finished(); //读完后发一个信号


}


}


printf("Close... ");


tcsetattr(fd,TCSANOW,&oldtio); //重新设置回原来的


close(fd);


quit();


}


通过stopped变量来实现线程控制。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux下Python执行C函数 下一篇QT下实现对Linux Shell调用的几种..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·常用meta整理 | 菜鸟 (2025-12-25 01:21:52)
·SQL HAVING 子句:深 (2025-12-25 01:21:47)
·SQL CREATE INDEX 语 (2025-12-25 01:21:45)
·Shell 传递参数 (2025-12-25 00:50:45)
·Linux echo 命令 - (2025-12-25 00:50:43)