首页 > 代码库 > 简单的串口通讯程序

简单的串口通讯程序

很早以前写过串口通讯的代码,今天又要用到,做了一个简单的类封装。

代码如下:

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;
}



简单的串口通讯程序