Linux下基于QT串口编程测试一

               

Linux下基于QT串口编程测试一


本文博客链接:http://blog.youkuaiyun.com/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_OBJECTpublic:    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;}

说明:

串口在驱动中有一个缓存区,收到的数据会存放在里面,如果一次发送数据很多,而读取间隔很短,则每次读取都是整个数据包的片段.


           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.youkuaiyun.com/jiangjunshow

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值