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; //串口设备描述符};#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;elsecout << "send datafailed" << endl;sleep(1);} return 0;}
0 0
- linux串口类
- linux 串口
- linux 串口
- linux串口
- Linux串口
- linux串口
- linux串口
- Linux串口
- linux串口
- linux下的串口通信类
- Linux 串口编程
- Linux下串口编程
- Linux串口编程分析
- LINUX 串口通讯源码
- Linux串口编程
- Linux串口编程
- Linux串口编程
- Linux串口编程
- 网上商城SSH三者间的牵线
- Android 快速开发系列 打造万能的ListView GridView 适配器
- VideoView播放视频是出现黑边的问题
- 在Unity中StartCoroutine/yield return的原理和模式
- Json数据格式和XML数据格式的分析
- linux串口类
- 调用手机拍照后,图库不显示刚刚拍到的照片
- CADisplayLink与NSTimer
- grunt.initConfig配置学习
- 彻底弄懂css中单位px和em,rem的区别
- ubuntu HackRF One开发环境搭建
- smartSVN unable to connect to a respository at url
- Source Insight 集成 TortoiseSVN功能 以及 代码编译命令
- 三种方式注册一个字符设备