Linux下实现串口读写操作 您所在的位置:网站首页 linux串口io操作 Linux下实现串口读写操作

Linux下实现串口读写操作

2023-08-31 20:19| 来源: 网络整理| 查看: 265

  这里只贴串口读写操作部分代码,供大家参考学习用,该部分代码主要实现打开串口,配置串口参数波特率为115200、停止位1、数据位8、无校验位,发送2个数据,等待接收24个数据。代码是在QT窗体程序里实现,界面添加了了一个按钮,3个文本框,按下去发送2个数据,等待接收到下位机发送上来的24个数据后,把接收到的数据通过调试信息打印出来,然后再等待接收一次4个数据,再把接收到的数据通过调试信息打印出来,最后把发送数据长度、接收数据长度、串口句柄在文本框显示出来。

#include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include "stdio.h" #include "termios.h" #include "unistd.h" #include "limits.h" #include #include "time.h" //=================== #include #include //=================== #define UART_DEV "/dev/ttyS0" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_2_clicked() { int fd =0; int RxLen=0; int flag =0; uint8_t RxBuff[100]; uint8_t SenBuff[2]={0xaa,0xbb}; //==========串口打开============// fd = open(UART_DEV ,O_RDWR|O_NOCTTY); if(fd 0) ) { for(int i=0;i 0) ) { for(int i=0;itextA->setText(QString::number(fd)); ui->textB->setText(QString::number(RxLen)); ui->textC->setText(QString::number(TxLen)); ::close(fd); } 运行结果如下:

 注意:使用串口需要在sudo环境下运行程序,否则要把用户组添加到串口的组

===========================================================================================

为了便于使用,下面的代码是我把上面的串口操作进行了整理封装的,供大家参考学习使用,实测可用,转载请标明出处

  头文件

#ifndef MYUART_H #define MYUART_H #include #include "stdio.h" #include "termios.h" #include "unistd.h" #include "limits.h" #include #include "time.h" #include //#define UART_DEV "/dev/ttyS0" /* 要操作的串口号 */ int OpenUart(char* UART_DEV); int UartSend(int fd, uint8_t *SenBuff, long len); int UartRead(int fd, uint8_t *RxBuff, long RxLen); void UartClose(int fd); #endif // MYUART_H

  串口操作文件

/* *File:实现串口的基本操作 */ #include "MyUart.h" /* * 函数名 : SetOpt * 函数功能: 设置串口的相关基本参数,这里固定了波特率为115200,数据位8,校验位无,停止位1 * 传入参数: fd 设备描述符 * 返回值 : 无 */ void SetOpt(int fd) { static struct termios termold, termnew; tcgetattr(fd, &termold) ; bzero(&termnew, sizeof(termnew)); termnew.c_iflag &= ~(ICRNL | IGNCR) ; termnew.c_cflag |= CLOCAL | CREAD; //CLOCAL:忽略modem控制线 CREAD:打开接受者 termnew.c_cflag &= ~CSIZE; termnew.c_cflag |= CS8; termnew.c_cflag &= ~PARENB; cfsetispeed(&termnew, B115200); cfsetospeed(&termnew, B115200); termnew.c_cflag &= ~CSTOPB; termnew.c_cc[VTIME] = 1; //VTIME:非cannoical模式读时的延时,以十分之一秒位单位,設置超時時間 ms 單位,設置阻塞后要關閉這裏,設0 termnew.c_cc[VMIN] = 0; //VMIN:非canonical模式读到最小字符数,阻塞讀取的字節數 tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW,&termnew); } /* * 函数名 : OpenUart * 函数功能: 串口打开,如果打开成功,会返回一个设备描述符,失败返回-1 * 传入参数: UART_DEV 要操作的串口号 * 返回值 : fd 设备描述符 */ int OpenUart(char* UART_DEV) { int fd=0; /*第1个参数:想要打开的文件路径名,或者文件名 *第2个参数:open_Status:文件打开方式,可采用下面的文件打开模式: O_RDONLY:以只读方式打开文件 O_WRONLY:以只写方式打开文件 O_RDWR:以读写方式打开文件 O_APPEND:写入数据时添加到文件末尾 O_CREATE:如果文件不存在则产生该文件,使用该标志需要设置访问权限位mode_t O_EXCL:指定该标志,并且指定了O_CREATE标志,如果打开的文件存在则会产生一个错误 O_TRUNC:如果文件存在并且成功以写或者只写方式打开,则清除文件所有内容,使得文件长度变为0 O_NOCTTY:如果打开的是一个终端设备,这个程序不会成为对应这个端口的控制终端,如果没有该标志,任何一个输入,例如键盘中止信号等,都将影响进程。 O_NONBLOCK:该标志与早期使用的O_NDELAY标志作用差不多。程序不关心DCD信号线的状态,如果指定该标志,进程将一直在休眠状态,直到DCD信号线为0。 O_NONBLOCK和O_NDELAY所产生的结果都是使I/O变成非搁置模式(non-blocking),在读取不到数据或是写入缓冲区已满会马上return,而不会搁置程序动作,直到有数据或写入完成; 它们的差别在于设立O_NDELAY会使I/O函式马上回传0,但是又衍生出一个问题,因为读取到档案结尾时所回传的也是0,这样无法得知是哪中情况;因此,O_NONBLOCK就产生出来,它在读取不到数据时会回传-1,并且设置errno为EAGAIN。 第3个参数:设置文件访问权限的初始值 */ fd = open(UART_DEV , O_RDWR|O_NOCTTY); if (fd < 0) { return -1; } SetOpt(fd); return fd; } /* * 函数名 : UartSend * 函数功能: 串口发送数据 * 传入参数: fd 设备描述符, *SenBuff 传输数据首地址, len 要发送字符大小 * 返回值 : 发送字符大小 */ int UartSend(int fd, uint8_t *SenBuff, long len) { int TxLen; TxLen = write(fd,SenBuff,len); return TxLen; } /* * 函数名 : UartRead * 函数功能: 串口接收数据 * 传入参数: fd 设备描述符, *RxBuff 接收传输数据Buff首地址, Rxlen 要接收字符大小 * 返回值 : 接收字符大小 */ int UartRead(int fd, uint8_t *RxBuff, long RxLen) { int GetRxLen=0; while(RxLen){ GetRxLen += read(fd, RxBuff+GetRxLen, 1); RxLen--; } //GetRxLen = read(fd, RxBuff, RxLen); //把参数fd所指的文件传送sizeof (RxBuff)个字节到RxBuff指针所指的内存中 return GetRxLen ; } /* * 函数名 : UartClose * 函数功能: 关闭串口 * 传入参数: fd 设备描述符 * 返回值 : 无 */ void UartClose(int fd) { close(fd); } /*END*/

注意:使用串口读写时,要注意下位机的时序,不然可能会出现下位机还没发送数据上来,你就进行读取,导致读取失败的情况,时序调整可以用延时调整

本文来自博客园,作者:白菜没我白,转载请注明原文链接:https://www.cnblogs.com/xingboy/p/14416196.html



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有