VxWorks 6.8下基于QT的串口编程
文章简要记录了VxWorks 6.8
下基于Qt
实现的串口
编程。
相关的VxWorks
和 串口
,请参阅
VxWorks下的串口测试程序设计和源码
。
VxWorks简介
VxWorks 操作系统是美国WindRiver公司于1983年设计开发的一种嵌入式实时操作系统(RTOS),是嵌入式开发环境的关键组成部分。良好的持续发展能力、高性能的内核以及友好的用户开发环境,在嵌入式实时操作系统领域占据一席之地。它以其良好的可靠性和卓越的实时性被广泛地应用在通信、军事、航空、航天等高精尖技术及实时性要求极高的领域中,如卫星通讯、军事演习、弹道制导、飞机导航等。在美国的 F-16、FA-18战斗机、B-2 隐形轰炸机和爱国者导弹上,甚至连1997年4月在火星表面登陆的火星探测器、2008年5月登陆的凤凰号,和2012年8月登陆的好奇号也都使用到了VxWorks。
串口简介
串行接口(Serial Interface) 简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口,指数据一位一位地顺序传送。
串行接口的特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。常见的有一般计算机应用的RS-232(使用 25 针或 9 针连接器)和工业计算机应用的半双工RS-485与全双工RS-422。
我这里使用了232和422传输方式,在我本人理解这两种方式根据需求硬件已经做好的传输方式(也可以在BIOS设置),我们知道是什么传输方式,做到心中有数和如何搭建测试环境,今天在这里教大家个简单的232-9针连接器的接线方式,一般没接触过的拿过来一脸懵逼,好家伙9跟针都不知道是干嘛的,那么我告诉你如果是 232-9针,什么也别管直接找到第2针和第3针用杜邦线回连,这时你就具备环境自己检测板卡串口模块是否好用,如果测试程序一定记得把第5跟针要连接上,否则会出现数据不精准的情况(文章底部有贴图)。
在软件层面上只需要关注数据位、停止位、奇偶效验、读取方式和效率即可;
232串口接线说明
RS232串口接线方法:直连和交叉接法
一般情况下,设备和电脑的连接通讯,需用到RS232串口线直连线;而设备和设备的连接通讯,就会用到RS232串口线的交叉线。用户在选择的时候,应根据两个设备之间连接的实际情况,选择不同接法的RS232串口线。
代码实例
VxWorks串口所需要包含的头文件
#include "vxWorks.h"
#include "stdIo.h"
#include "ioLib.h"
#include "sysLib.h"
#include "string.h"
#include "taskLib.h"
VxWorks串口配置函数
ioctl(m_SeriPort,SIO_HW_OPTS_SET, CLOCAL | CS8 | PARODD | PARENB); //8位数据位|1位停止位|偶效验
ioctl(m_SeriPort,FIOBAUDRATE,9600); //波特率9600
ioctl(m_SeriPort,FIOSETOPTIONS,OPT_RAW); //设置串口raw模式
ioctl(m_SeriPort,FIOFLUSH,0); //清空输入输出的缓冲区
open函数
#define SERI_NAME "/tyCo/0"
int m_SeriPort = open(SERI_NAME ,O_RDWR,0);
int m_SeriPort = open(SERI_NAME ,O_WRONLY,0);
write函数
char* sendData;
int writeCom = write(m_SeriPort, sendData,strlen(sendData));
read函数
char data;
int readCom = read(m_SeriPort,&data,1);
Seri_Demo_Qt_Vx
#ifndef THREAD_H
#define THREAD_H
#include <QThread>
#include <QDebug>
#include "vxWorks.h"
#include "stdIo.h"
#include "ioLib.h"
#include "sysLib.h"
#include "string.h"
#include "taskLib.h"
class Thread : public QThread
{
Q_OBJECT
public:
explicit Thread(QObject *parent = 0);
~Thread();
void run(); //重写run函数
public:
bool openSeri(QString comPort,int baudRate); //打开串口
void closeSeri(); //关闭串口
void writeSeri(char* sendData); //发送数据
void setFlag(bool flag = true); //线程数据标志位
signals:
void RecvData(char data);
private:
bool seriStop; //读取数据标志位 true读取数据 false退出循环
int m_SeriPort; //串口文件描述符
QString m_SeriName; //串口名
int m_baud; //波特率
};
#endif //THREAD_H
#include "thread.h"
Thread::Thread(QObject *parent) : QThread(parent)
{
}
Thread::~Thread()
{
}
void Thread::run()
{
sysClkRateSet(1000);
char rData;
while(1)
{
int readCom = read(m_SeriPort,&rData,1);
if(readCom > 0)
{
printf("%c\n",rData);
emit RecvData(rData);
if(seriStop == false)
{
qDebug()<< "isStop == false break";
break;
}
}
else
{
taskDelay(10);
}
}
}
bool Thread::openSeri(QString comPort, int baudRate)
{
this->m_SeriName = comPort;
this->m_baud = baudRate;
qDebug()<< "Thread::openSeri" << comPort.toUtf8().data() << baudRate;
m_SeriPort = open(comPort.toUtf8().data(),O_RDWR,0);
if(m_SeriPort == ERROR)
{
qDebug()<< "open :" << comPort.toUtf8().data() << " = " <<m_SeriPort << "failed !";
return false;
}
ioctl(m_SeriPort,SIO_HW_OPTS_SET, CLOCAL | CS8 | PARODD | PARENB);
ioctl(m_SeriPort,FIOBAUDRATE,baudRate);
ioctl(m_SeriPort,FIOSETOPTIONS,OPT_RAW);
ioctl(m_SeriPort,FIOFLUSH,0);
qDebug()<< "open :" << comPort.toUtf8().data() << " = " << m_SeriPort << "succeeded !";
return true;
}
void Thread::closeSeri()
{
if(seriStop == false)
{
qDebug()<< "Thread::closeSeri";
close(m_SeriPort);
}
}
void Thread::writeSeri(char* sendData)
{
if(m_SeriPort == ERROR)
{
openSeri(m_SeriName,m_baud);
}
int writeCom = write(m_SeriPort, sendData,strlen(sendData));
qDebug()<< sendData << writeCom;
}
void Thread::setFlag(bool flag)
{
this->seriStop = flag;
qDebug()<< "Thread::setFlag" << flag;
}
TestSeri_Demo_Qt_Vx_Demo
#ifndef SERI_H
#define SERI_H
#include <QObject>
#include <QDebug>
#include "thread.h"
class Seri : public QObject
{
Q_OBJECT
public:
explicit Seri(QObject *parent = 0);
~Seri();
public:
/* open_Seri 打开串口
* comName 串口名
* comBaud 串口波特率
* return 成功 true 失败 false
*/
bool open_Seri(QString comName,int comBaud);
/* write_Seri 发送数据
* comData 发送数据内容
*/
void write_Seri(QByteArray comData);
/*
* close_Seri 关闭串口
*/
void close_Seri();
signals:
send_Seri(char data);
private:
Thread* m_pThread;
};
#endif // SERI_H
#include "Seri.h"
Seri::Seri(QObject *parent) : QObject(parent)
{
m_pThread = new Thread;
}
Seri::~Seri()
{
if(m_pThread){
delete m_pThread;
m_pThread=NULL;
}
}
bool Seri::open_Seri(QString comName,int comBaud)
{
if(m_pThread->openSeri(comName,comBaud))//如果打开成功
{
m_pThread->setFlag(true);
m_pThread->start();
}
return false;
}
void Seri::write_Seri(QByteArray comData)
{
m_pThread->writeSeri(comData.data());
}
void Seri::close_Seri()
{
if(m_pThread->isRunning())//如果线程还在运行 --> 退出循环接收数据 --> 关闭串口 --> 退出线程 --> 回收线程
{
m_pThread->setFlag(false);
m_pThread->closeSeri();
m_pThread->quit();
m_pThread->wait();
}
}
程序代码说明:
- thread类为配置串口类
- seri类为外部使用类
- 接收到的数据是利用信号槽为接口把数据传输出去