linux串口类

来源:互联网 发布:mysql show errors 编辑:程序博客网 时间:2024/06/06 07:35

近几天需要用linux的串口,在网上找了一些例子,随后又自己改成了一个类

可以发送,接收未测试。

头文件:

#ifndef MYSERIAL_H#define MYSERIAL_Hclass MySerial{public:MySerial(){};int UART_open(const char *portName);int UART_open(int uartNum);int UART_set(int baud = 115200,int flow_ctrl = 0,int databits = 8,int stopbits = 1,int parity = 0);int UART_init(int baud = 115200,int flow_ctrl = 0,int databits = 8,int stopbits = 1,int parity = 0);int UART_recv(unsigned char *rcv_buf,int data_len);int UART_send(unsigned char *send_buf,int data_len);~MySerial();private:int fd;  //串口设备描述符};#endif
cpp:

/***************************************************************** FileName:            mySerial.cpp* Author:              sfy* Description:         linux串口类  ****************************************************************/#include <iostream>#include <unistd.h> //Unix 标准函数定义#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <termios.h>#include <string>#include <vector>#include <utility>#include <sstream>#include "mySerial.h"using namespace std;/************************************************************************ 名称:         UART_open* 功能:         打开指定串口并返回状态* 入口参数:     portName:串口号(ttyUSB0,ttyUSB1,ttyUSB2)* 返回值:       正确打开返回0  错误返回-1************************************************************************/int MySerial::UART_open(const char *portName){fd = open(portName,O_RDWR|O_NOCTTY|O_NDELAY);//非阻塞模式打开if(fd == -1){cout << "Can't open serial port" << *portName << endl;return -1;}//判断串口的状态是否为阻塞状态int BOOL = fcntl(fd,F_SETFL,0);if(BOOL < 0){cout << "fcntl failed" << endl;return -1;}else{printf("fcntl=%d\n",BOOL);}//测试是否为终端设备if(!isatty(STDIN_FILENO)){cout << "standard input is not a terminal device" << endl;return -1;}else{cout << "isatty success!" << endl;}//cout << "fd->open" << fd << endl;return 0;}/************************************************************************ 名称:         UART_open* 功能:         打开串口并返回状态* 入口参数:     uartNum:串口号 自动打开0-uartNum之间的一个串口号* 返回值:       正确返回0  错误返回-1************************************************************************/int MySerial::UART_open(int uartNum){stringstream stream;    string uartName = "/dev/ttyUSB";string str;bool BOOL;for(int i = 0;i <= uartNum; ++i){stream.clear();stream << i;stream >> str;str = uartName + str;fd = open(str.c_str(),O_RDWR|O_NOCTTY|O_NDELAY);//非阻塞模式打开if(fd != -1){cout << "open serial port " << str << " successed" << endl;break;}cout << "open serial port " << str << "  failed" << endl;if(i == uartNum){return -1;}}//判断串口的状态是否为阻塞状态BOOL = fcntl(fd,F_SETFL,0);if(BOOL < 0){cout << "fcntl failed" << endl;return -1;}else{printf("fcntl=%d\n",BOOL);}//测试是否为终端设备if(!isatty(STDIN_FILENO)){cout << "standard input is not a terminal device" << endl;return -1;}else{cout << "isatty success!" << endl;}//cout << "fd->open" << fd << endl;return 0;}/**************************************************************************** 名称:                       UART_set* 功能:                       设置串口数据位,停止位,校验位* 入口参数:                   baud               波特率 2400 4800 9600 115200*                             flow_ctrl          数据流控制 0 1 2*                             databits           数据位  7或8*                             stopbits           停止位  1或2*                             parity             校验类型  0 1 2* 返回值:                    正确返回0        错误返回-1*****************************************************************************/int MySerial::UART_set(int baud ,int flow_ctrl ,int databits ,int stopbits ,int parity ){ typedef std::pair< int,int> Baud;vector<Baud> baud_list;baud_list.push_back(Baud(2400,B2400));baud_list.push_back(Baud(4800,B4800));baud_list.push_back(Baud(9600,B9600));baud_list.push_back(Baud(115200,B115200));struct termios options;/*tcgetattr(fd,&options)得到与fd指向对象的相关参数,并将他们保存与options,该函数还可以测试配置是否正确,  该串口是否可用等,若调用成功,函数返回0,若调用失败,返回-1    */if(tcgetattr(fd,&options) !=0){cout << "设置串口失败" <<endl;return -1;}for(vector< Baud >::iterator iter=baud_list.begin();iter!=baud_list.end();++iter){if(iter->first == baud){cfsetispeed(&options,iter->second);cfsetospeed(&options,iter->second);}}//修改控制模式 保证程序不会占用串口options.c_cflag |= CLOCAL;//修改控制模式 使得能够从串口中读输入数据options.c_cflag |= CREAD;//设置数据流控制switch (flow_ctrl){case 0 : //不使用流控制options.c_cflag &= ~CRTSCTS;break;case 1 : //使用硬件流控制options.c_cflag |= CRTSCTS;break;case 2 : //使用软件流控制options.c_cflag |= IXON |IXOFF |IXANY;break;default :cout << "数据流参数错误" << endl;return -1;}//设置数据位options.c_cflag &= ~CSIZE;   //屏蔽其他标志位switch(databits){case 5 :options.c_cflag |= CS5;break;case 6 :options.c_cflag |= CS6;break;case 7 :options.c_cflag |= CS7;break;case 8 :options.c_cflag |= CS8;break;default :cout << "数据位参数错误" << endl;return -1;}//设置校验位switch(parity){case 0 : //无奇偶校验位options.c_cflag &= ~PARENB;//options.c_iflag &= ~INPCK;break;case 1 : //奇校验options.c_cflag |= (PARODD | PARENB);//options.c_iflag |= INPCK;break;case 2 : //偶校验options.c_cflag &= ~PARENB;options.c_cflag &= ~PARODD;//options.c_iflag |= INPCK;break;case 3 : //设置为空格options.c_cflag &= ~PARENB;options.c_cflag &= ~CSTOPB;break;default :cout << "校验位参数错误" << endl;return -1;}//设置停止位switch(stopbits){case 1 :options.c_cflag &= ~CSTOPB;break;case 2 :options.c_cflag |= CSTOPB;break;default :cout << "停止位参数错误" << endl;return -1;}//修改输出模式 原始数据输出options.c_oflag &= ~OPOST;//设置等待时间和最小接受字符options.c_cc[VTIME] = 1; // 读取一个字符等待1*(1/10)s options.c_cc[VMIN ] = 1; // 读取字符的最小个数为1//如果发生数据溢出,接受数据,但是不再读取tcflush(fd,TCIFLUSH);//将修改后的数据设置写入串口if(tcsetattr(fd,TCSANOW,&options) != 0)  //立即生效{cout << "com set error" << endl;return -1;}return 0;}/*********************************************************** 名称:                     USRT_init()* 功能:                     串口初始化* 入口参数:                 fd         文件描述符*                           baud       串口波特率*                           flow_ctrl  数据流控制*                           databits   数据位   7或8*                           stopbits   停止位   1或2*                           parity     检验类型  N E O S* 返回值:                  正确返回0 ,错误返回-1*************************************************************/int MySerial::UART_init(int baud ,int flow_ctrl ,int databits ,int stopbits ,int parity ){//设置串口数据帧格式if(UART_set(baud,flow_ctrl,databits,stopbits,parity) != 0){cout << "set uart error" << endl;return -1;}return 0;}/*********************************************************************** 名称:                                        UART_recv* 功能:                                        接受串口数据* 入口参数:                                     rcv_buf    数据缓存区*                                               data_len   一帧数据的长度* 返回值:                                       正确返回实际接受字符数   错误返回-1*************************************************************************/int MySerial::UART_recv(unsigned char *rcv_buf,int data_len){int len,fs_sel;fd_set fs_read;struct timeval time;FD_ZERO(&fs_read);FD_SET(fd,&fs_read);time.tv_sec = 10;time.tv_usec = 0;//使用select实现串口的多路通信fs_sel = select(fd+1,&fs_read,NULL,NULL,&time);if(fs_sel){len = read(fd,rcv_buf,data_len);return len;}return -1;}/******************************************************************************* 名称:                      UART_send* 功能:                      发送数据* 入口参数:                  send_buf 发送缓存区*                            data_len 一帧数据个数* 返回值:                   正确返回实际发送字符数   错误返回-1*******************************************************************************/int MySerial::UART_send(unsigned char *send_buf, int data_len){int len = 0;len = write(fd,send_buf,data_len);  //返回实际串口发送字符数if(len == data_len){return len;}tcflush(fd,TCOFLUSH);return -1;}/********************************************************************************* 名称:                    ~MySerial* 功能:                    析构函数  关闭串口* 入口参数:                void* 返回值:                  void*********************************************************************************/MySerial::~MySerial(){close(fd);}

使用例子:

#include "mySerial.h"#include <iostream>#include <unistd.h>using namespace std;int main(){unsigned char send_buf[20] = "1234567891";MySerial serial;bool BOOL =serial.UART_open(5);if(BOOL !=0){return -1;}serial.UART_init(115200,0,8,1,0);while(1){int len = serial.UART_send(send_buf,20);if(len > 0)cout << "send data successful" << endl;elsecout << "send datafailed" << endl;sleep(1);}    return 0;}



0 0
原创粉丝点击