简单的串口通讯程序

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

代码如下:

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



串口监控器是一个免费的多功能串口通讯监控软件,它能够多种方式显示,接收,分析通讯数据;能够以多种灵活方式发送数据;功能强大,操作简便,在串口通讯监控,设备通讯测试中,能够有效提高工作效率。 主要功能如下: 接收数据: 1. 以十六进制方式显示接收到的数据。 2. 以字符方式显示接收到的数据。 3. 数据帧自动识别,分行显示。 4. 接收数据自动换行设置。 5. 显示或隐藏数据帧的接收时间。 6. 自动清除,自动保存接收到的数据。 7. 接收数据个数计数。 发送数据: 1. 十六进制方式发送数据。 2. 字符串方式发送数据。 3. 发送“发报窗口”当前光标行的数据帧。 4. 循环发送“发报窗口”当前光标行的数据帧。 5. 循环发送“发报窗口”固定行的数据帧。 6. 循环依次发送“发报窗口”的多行数据帧。(设置起始行,行数) 7. 触发发送,接收到“发报窗口”某一行数据,触发发送“发报窗口”另一行数据。 8. 发送数据个数计数。 实用增强功能: 1. 强大易用的进制转换功能。 2. 智能识别当前光标处数据帧的行号,“字符”或“十六进制数”的个数。 3. 智能计算当前选择的“字符”或“十六进制数”的个数。 4. 强大的数据查找功能。 5. 定时保存,定时清除数据。 6. 根据自己的喜好,灵活变换操作界面。 应用场合: 1. 截取和分析设备之间通讯数据流。 2. 串行外围设备硬件开发。 3. 串行设备驱动程序开发。 4. 调试和测试设备和设备之间的串行通讯过程。 5. 记录和分析RS232/422/485通信过程。 6. 模拟某设备通讯过程,对另外设备进行通讯测试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值