linux串口类
2016-01-29 15:42
519 查看
近几天需要用linux的串口,在网上找了一些例子,随后又自己改成了一个类
可以发送,接收未测试。
头文件:
使用例子:
可以发送,接收未测试。
头文件:
#ifndef MYSERIAL_H #define MYSERIAL_H class 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; //串口设备描述符 }; #endifcpp:
/**************************************************************** * 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; else cout << "send datafailed" << endl; sleep(1); } return 0; }
相关文章推荐
- ARM Linux 更新启动画面
- linux命令-rm
- Linux之dd命令详解
- LINUX0.11内核阅读笔记
- linux下onvif协议gsoap实现的源码(测试编译成功版)
- linux 压缩以及归档
- linux进程间通信的几种机制的比较及适用场合
- Linux后门入侵检测工具
- VMware虚拟机克隆CentOS后网卡修改方法
- linux命令-file
- centos磁盘挂载
- linux信号------探步
- Linux基本命令
- 在CentOS服务器上安装配置LEMP的详细教程
- linux系统硬件配置查看方法
- linux select函数详解
- CentOS访问Windows共享文件夹的两种方法
- linux命令(1):scp命令
- 如何学习Linux
- linux下trash替换掉rm