很早以前写过串口通讯的代码,今天又要用到,做了一个简单的类封装。
代码如下:
rs485Test.h
#include
#include
#include
#include
#include
#include
#include
#include
#include
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;
};
#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;
}