Linux下基于QT串口编程测试一
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
环境:
主机:Fedora12
开发软件:QT
目标板:MINI6410
实现功能:
目标板接收PC串口传过来的信息并在终端输出,目标板串口接收信息用SELECT机制
源代码:
widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QDebug>
#include <QTimer>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/param.h>
#include <QVector>
#include <QByteArray>
#include <QQueue>
#include <QSemaphore>
#include <iostream>
#include <QFile>
#include "QThread"
#include <QtGui>
#include <QMutex>
#include <QtNetwork>
#include <QUdpSocket>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <linux/soundcard.h>
#include <alsa/asoundlib.h>
#include <QtGui/QMainWindow>
#include <QtGui/QDialog>
#include <QtGui/QPushButton>
#include <QtGui/QHBoxLayout>
#include <QtGui/QVBoxLayout>
#include <QtGui/QGridLayout>
#include <QTextCodec>
#include <QtGui/QToolButton>
#include <qsocketnotifier.h>
#include <QTimer>
#include <QtNetwork/QUdpSocket>
#include <iostream>
#include <qmessagebox.h>
#include <qstringlist.h>
#include <QtNetwork>
#include <QUdpSocket>
#include <QSound>
#include <QMap>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/soundcard.h>
#include "sys/select.h"
#include "termios.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
};
//端口信息定义
typedef struct _Port_Info
{
int baud_rate;
int port_fd;
char parity;
char stop_bit;
char flow_ctrl;
char data_bits;
}*Port_Info;
//打开串口
int open_port(char *port);
//关闭串口
void close_port(int fd);
//根据波特率获得波特率设置参数
int get_baud_rate(unsigned long baud_rate);
//设置端口参数
int set_port(Port_Info p_info);
//通过串口发送数据,只能写COMPRESS_BYTE长度数据,发送时加文件头"JDH"
int send_data(int fd,char *data,int data_len);
#endif // WIDGET_H
widget.c:
#include "widget.h"
#include "ui_widget.h"
int Fd_Com;
#define COM "/dev/ttySAC1"
char buffer_com[1024 + 10];
char buffer_read_com[1024];
int send_index;
//打开串口
int open_port(char *port)
{
int fd;
if ((fd = open(port,O_RDWR | O_NOCTTY |O_NONBLOCK)) == -1)
{
perror("can not open com port!");
return -1;
}
}
//关闭指定串口
void close_port(int fd)
{
close(fd);
}
//根据波特率获得响应的波特率设置参数
int get_baud_rate(unsigned long baud_rate)
{
switch (baud_rate)
{
case 2400:
return B2400;
case 4800:
return B4800;
case 9600:
return B9600;
case 19200:
return B19200;
case 38400:
return B38400;
case 57600:
return B57600;
case 115200:
return B115200;
case 230400:
return B230400;
default:
return -1;
}
}
//设置端口
int set_port(Port_Info p_info)
{
struct termios old_opt,new_opt;
int baud_rate,parity;
memset(&old_opt,0,sizeof(old_opt));
memset(&new_opt,0,sizeof(new_opt));
cfmakeraw(&new_opt);
tcgetattr(p_info->port_fd,&old_opt);
//设置串口波特率
baud_rate = get_baud_rate(p_info->baud_rate);
//修改new_opt结构中的串口输入/输出波特率槽参数
cfsetispeed(&new_opt,baud_rate);
cfsetospeed(&new_opt,baud_rate);
//修改控制模式,保证程序不会占用串口
new_opt.c_cflag |= CLOCAL;
//修改控制模式,使得能够从串口读取输入数据
new_opt.c_cflag |= CREAD;
//设置数据流控制
switch (p_info->flow_ctrl)
{
case '0':
{
//不使用流控制
new_opt.c_cflag &= ~CRTSCTS;
break;
}
case '1':
{
//使用硬件进行流控制
new_opt.c_cflag |= CRTSCTS;
break;
}
case '2':
{
new_opt.c_cflag |= IXON | IXOFF | IXANY;
break;
}
}
//设置数据位
new_opt.c_cflag &= ~CSIZE;
switch (p_info->data_bits)
{
case '5':
{
new_opt.c_cflag |= CS5;
break;
}
case '6':
{
new_opt.c_cflag |= CS6;
break;
}
case '7':
{
new_opt.c_cflag |= CS7;
break;
}
case '8':
{
new_opt.c_cflag |= CS8;
break;
}
default:
{
new_opt.c_cflag |= CS8;
break;
}
}
//设置奇偶校验位
switch (p_info->parity)
{
case '0':
{
//不使用奇偶校验
new_opt.c_cflag &= ~PARENB;
break;
}
case '1':
{
//使用偶校验
new_opt.c_cflag |= PARENB;
new_opt.c_cflag &= ~PARODD;
break;
}
case '2':
{
//使用奇校验
new_opt.c_cflag |= PARENB;
new_opt.c_cflag |= PARODD;
break;
}
}
//设置停止位
if (p_info->stop_bit == '2')
{
new_opt.c_cflag |= CSTOPB;
}
else
{
new_opt.c_cflag &= ~CSTOPB;
}
//修改输出模式,原始数据输出
new_opt.c_oflag *= ~OPOST;
//修改控制字符,读取字符最小个数为1
new_opt.c_cc[VMIN] = 1;
//修改控制字符,读取第一个字符等待等待1 *(1/10)s
new_opt.c_cc[VTIME] = 1;
//如果发生数据溢出,接收数据,但是不再读取
tcflush(p_info->port_fd,TCIFLUSH);
int result;
result = tcsetattr(p_info->port_fd,TCSANOW,&new_opt);
if (result == -1)
{
perror("cannot set the serial port parameters");
return -1;
}
tcgetattr(p_info->port_fd,&old_opt);
return result;
}
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//串口初始化
//打开串口
Fd_Com = open_port(COM);
//设置串口通信参数
struct _Port_Info info;
info.baud_rate = 115200;
info.data_bits = 8;
info.flow_ctrl = 0;
info.port_fd = Fd_Com;
info.stop_bit = 1;
info.parity = 0;
if (set_port(&info) == -1)
{
printf("set com para wrong!!!!!!!!!!!!!");
}
int err = 0;
struct timeval wait_time;
fd_set read_fds;
int len_com = 0;
char *data = "jdh";
int len = write(Fd_Com,data,3);
if (len != 3)
{
//如果出现溢出情况
qDebug() << "yi chu";
tcflush(Fd_Com,TCOFLUSH);
}
while (1)
{
wait_time.tv_sec = 0;
wait_time.tv_usec = 20000;
FD_ZERO(&read_fds);
FD_SET(Fd_Com,&read_fds);
//err = select(Fd_Com + 1,&read_fds,NULL,NULL,&wait_time);
err = select(Fd_Com + 1,&read_fds,NULL,NULL,NULL);
if (err < 0)
{
perror("select fail");
continue;
}
else
{
if (err == 0)
{
//超时返回
//qDebug() << "chao shi";
continue;
}
}
//读取串口声卡
//判断声卡是否允许读,不允许读退出
if (FD_ISSET(Fd_Com,&read_fds))
{
qDebug() << "du qu sheng ka";
//读取串口缓存所有数据
len_com = read(Fd_Com,buffer_read_com,1024);
qDebug() << "read com byte = " << len_com;
QByteArray temp;
temp.append(buffer_read_com,len_com);
qDebug() << temp;
}
}
qDebug() << "end";
}
Widget::~Widget()
{
delete ui;
}
说明:
串口在驱动中有一个缓存区,收到的数据会存放在里面,如果一次发送数据很多,而读取间隔很短,则每次读取都是整个数据包的片段.
分享到:
相关推荐
QT串口通信程序测试通过,可以放心使用。
Qt没有自带的串口编程类,一般我们都使用这了第三方编写的类qextserialport 已经测试,可以使用。
蓝牙模块服务多种多样,这个小demo实现了linux下建立蓝牙服务端的demo,并带了一个客户端测试。 使用时,可通过两台设备,分别作为服务端可客户端,连接时填入对方地址即可开启测试。服务端建立后,客户端可通过...
10.5.5 添加一个Qt/Embedded应用到QPE 第11章 Java虚拟机的移植 11.1 Java虚拟机概述 11.1.1 Java虚拟机的概念 11.1.2 J2ME 11.1.3 KVM 11.2 Java虚拟机的移植 11.2.1 获得源码 11.2.2 编译环境的建立 ...
6.3 基于Qt技术的Qtopia157 6.3.1 Qtopia简介157 6.3.2 Qtopia的功能157 6.3.3 Qtopia编程157 实验6.2 Qtopia的移植以及编程158 综合实验五电子点菜系统165 第7章 嵌入式Linux下的通信应用167 7.1 嵌入式...
接着系统地讲解了嵌入式Linux的环境搭建,以及嵌入式Linux的I/O与文件系统的开发、进程控制开发、进程间通信开发、网络应用开发、基于中断的开发、设备驱动程序的开发以及嵌入式图形界面的开发等,并且还安排了丰富...
6.3 基于Qt技术的Qtopia157 6.3.1 Qtopia简介157 6.3.2 Qtopia的功能157 6.3.3 Qtopia编程157 实验6.2 Qtopia的移植以及编程158 综合实验五电子点菜系统165 第7章 嵌入式Linux下的通信应用167 7.1 ...
6.3 基于Qt技术的Qtopia157 6.3.1 Qtopia简介157 6.3.2 Qtopia的功能157 6.3.3 Qtopia编程157 实验6.2 Qtopia的移植以及编程158 综合实验五电子点菜系统165 第7章 嵌入式Linux下的通信应用167 7.1 嵌入式...
6.3 基于Qt技术的Qtopia157 6.3.1 Qtopia简介157 6.3.2 Qtopia的功能157 6.3.3 Qtopia编程157 实验6.2 Qtopia的移植以及编程158 综合实验五电子点菜系统165 第7章 嵌入式Linux下的通信应用167 7.1 嵌入式...
第3 章 Linux 编程环境................................................................................................................ 28 ║2 嵌入式系统开发技术详解——基于ARM 3.1 Linux 常用工具..........
以电机、数码管、串口和mini键盘的驱动设计为例,详细阐述了嵌入式linux下字符设备驱动设计中的关键技术,包括设备的设备号、设备的操作及设备的注册和卸载等。通过编写相应硬件设备的应用程序,测试设备驱动的正确...