很早以前写过串口通讯的代码,今天又要用到,做了一个简单的类封装。
代码如下:
rs485Test.h
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <termios.h> #include <fcntl.h> #include <errno.h> #include <string.h> class RS485 { public: //////////////////////////////////////////////////////////// /// 创建串口的连接 /// @param name 设备名 /// @param speed 波特率 /// @param parity 奇偶校验 /// @param databits 数据位 /// @param stopbits 停止位 //////////////////////////////////////////////////////////// RS485(char *name,int speed,int parity,int databits,int stopbits); ~RS485(); //////////////////////////////////////////////////////////// /// 发送串口消息 /// @param fd 消息结构体 /// @param buf 消息结构体 /// @param length 消息结构体 /// @return -1:失败,0:成功 //////////////////////////////////////////////////////////// int sendMsg(unsigned char * buf, int length); //////////////////////////////////////////////////////////// /// 接收串口消息 /// @param fd 消息结构体 /// @param msg 消息结构体 /// @param length 消息结构体 /// @return -1:失败,0:成功 //////////////////////////////////////////////////////////// int recvMsg(unsigned char * msg, int length); private: //////////////////////////////////////////////////////////// /// 打开串口设备 /// @param dev 串口设备名 /// @return -1:失败,0:成功 //////////////////////////////////////////////////////////// int openTTY(const char *dev); //////////////////////////////////////////////////////////// /// 设置串口波特率 /// @param fd 串口设备文件描述符 /// @param speed 串口波特率 /// @return -1:失败,0:成功 //////////////////////////////////////////////////////////// void setTTYSpeed(int fd, int speed); //////////////////////////////////////////////////////////// /// 设置串口属性 /// @param fd 串口设备文件描述符 /// @param databits 串口数据位 /// @param stopbits 串口停止位 /// @param parity 串口奇偶校验 /// @return -1:失败,0:成功 //////////////////////////////////////////////////////////// int setTTYProperties(int fd,int databits,int stopbits,int parity); //////////////////////////////////////////////////////////// /// 打开串口设备 /// @param fd 串口设备文件描述符 /// @return -1:失败,0:成功 //////////////////////////////////////////////////////////// void closeTTY(int fd); int fd; };
rs485Test.cpp
#include "rs485Test.h" int speed_arr[] = { B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300 }; int name_arr[] = { 115200, 38400, 19200, 9600, 4800, 2400, 1200, 300 }; RS485::RS485(char *name,int speed,int parity,int databits,int stopbits) { fd = openTTY(name); if (0 > fd) { printf("tranConstructSerial(): Open the %s device fail\n", name); } else { setTTYSpeed(fd, speed); setTTYProperties(fd, databits, stopbits, parity); } } RS485::~RS485() { close(fd); } int RS485::openTTY(const char *dev) { int fd; if (NULL == dev || 0 == strlen(dev)) return -1; fd = open(dev, O_RDWR | O_NOCTTY); if (-1 == fd) { printf( "openTTY(): open then TTYdevice fail.\n"); return -2; } return fd; } void RS485::setTTYSpeed(int fd, int speed) { int i; int status; struct termios Opt; memset(&Opt, 0, sizeof(struct termios)); tcgetattr(fd, &Opt); for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++) { if (speed == name_arr[i]) { tcflush(fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr[i]); cfsetospeed(&Opt, speed_arr[i]); status = tcsetattr(fd, TCSANOW, &Opt); if (status != 0) { printf("setTTYSpeed(): tcsetattr fd fail\n"); return; } tcflush(fd, TCIOFLUSH); } } } int RS485::setTTYProperties(int fd, int databits, int stopbits, int parity) { struct termios options; memset(&options, 0, sizeof(struct termios)); if (tcgetattr(fd, &options) != 0) { printf("setTTYProperties(): Can't get attr when setup Serial\n"); return -1; } options.c_cflag &= ~CSIZE; switch (databits) { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: printf("setTTYProperties(): Unsupported data size\n"); return -2; } switch (parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; /* Clear parity enable */ options.c_iflag &= ~INPCK; /* Enable parity checking */ break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'e': case 'E': options.c_cflag |= PARENB; /* Enable parity */ options.c_cflag &= ~PARODD; options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'S': case 's': /*as no parity*/ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; break; default: printf("setTTYProperties(): Unsupported parity\n"); return -3; } switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: printf("setTTYProperties(): Unsupported stop bits\n"); return -4; } /* Set input parity option */ if (parity != 'n' && parity != 'N') options.c_iflag |= INPCK; tcflush(fd, TCIFLUSH); options.c_cc[VTIME] = 5; options.c_cc[VMIN] = 0; /* Update the options and do it NOW */ /*set serial mode */ options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN); /*Input*/ options.c_oflag &= ~OPOST; /*Output*/ options.c_iflag &= ~(ICRNL | IXON | BRKINT | ISTRIP); options.c_cflag |= (CLOCAL | CREAD); if (tcsetattr(fd, TCSANOW, &options) != 0) { printf("setTTYProperties(): Setup Serial fail\n"); return -5; } return 0; } void RS485::closeTTY(int fd) { close(fd); } int RS485::sendMsg(unsigned char * buf, int length) { int res; res = write(fd, buf, length); if (res != length) { printf("send_Msg(): Send buf fail!\n"); return -1; } printf("res = %d\n",res); return 0; } int RS485::recvMsg(unsigned char * msg, int length) { if (NULL == msg || 0 == length) return 0; printf( "recv_Msg(): the length of received buffer: %d\n", length); return read(fd, msg, length); } int main() { RS485 rs485Test("/dev/ttyUSB0", 115200, 'n', 8, 1); unsigned char buf[8]="lklk\n"; rs485Test.sendMsg(buf,8); return 0; }
时间: 2024-12-24 13:59:32