博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux下基于QT串口编程测试一
阅读量:3946 次
发布时间:2019-05-24

本文共 6290 字,大约阅读时间需要 20 分钟。

               

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

本文博客链接:,作者:jdh,转载请注明.

环境:

主机:Fedora12

开发软件:QT

目标板:MINI6410

实现功能:

目标板接收PC串口传过来的信息并在终端输出,目标板串口接收信息用SELECT机制

源代码:

widget.h:

#ifndef WIDGET_H#define WIDGET_H#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "QThread"#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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;}

说明:

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

           

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

你可能感兴趣的文章
Enhancing Security with Device Management Policies 加强安全与设备管理策略 Developing for Enterprise
查看>>
Advertising without Compromising User Experience 不降低用户体验的广告
查看>>
Planning Screens and Their Relationships 规划屏幕和它们的关系
查看>>
Planning for Multiple Touchscreen Sizes 规划多个触摸屏尺寸
查看>>
Providing Descendant and Lateral Navigation 提供下一代和横向导航
查看>>
GPS 0183协议GGA、GLL、GSA、GSV、RMC、VTG解释 + 数据解析
查看>>
android如何使得电阻屏在第一次开机时自动叫起屏幕校准程序
查看>>
android如何实现:当开启图案解锁时,取消滑动解锁
查看>>
Providing Ancestral and Temporal Navigation 设计高效的应用导航
查看>>
Putting it All Together: Wireframing the Example App 把APP例子用线框图圈起来
查看>>
Implementing Lateral Navigation 实现横向导航
查看>>
Implementing Ancestral Navigation 实现原始导航
查看>>
Implementing Temporal Navigation 实现时间导航
查看>>
Responding to Touch Events 响应触摸事件
查看>>
Defining and Launching the Query 定义和启动查询
查看>>
Handling the Results 处理结果
查看>>
如何内置iperf到手机中
查看>>
如何adb shell进入ctia模式
查看>>
Contacts Provider 联系人存储
查看>>
android 图库播放幻灯片时灭屏再亮屏显示keyguard
查看>>