简单的串口通讯程序

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

代码如下:

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

简单的串口通讯程序的相关文章

HALCON串口通讯程序

串口通讯程序 * Note: This example is meant to demonstrate the use of the serial interface * of HALCON.  On Unix machines, the output and input is from /dev/tty, i.e., the * window from which you have started HDevelop.  On Windows NT machines, * this progra

JAVA串口通讯程序

package com.jetf.serialport; import gnu.io.CommPortIdentifier; import gnu.io.NoSuchPortException; import gnu.io.PortInUseException; import gnu.io.SerialPort; import gnu.io.SerialPortEvent; import gnu.io.SerialPortEventListener; import gnu.io.Unsuppor

转:Qt编写串口通信程序全程图文讲解

转载:http://blog.csdn.net/yafeilinux/article/details/4717706  作者:yafeilinux (说明:我们的编程环境是windows xp下,在Qt Creator中进行,如果在Linux下或直接用源码编写,程序稍有不同,请自己改动.) 在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们可以去 http://sourceforge.net/projects/qextser

Qt编写串口通信程序

首先说明我们的编程环境是windows xp下,在Qt Creator中进行,如果在Linux下或直接用源码编写,程序稍有不同,请自己改动. 在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们可以去 http://sourceforge.net/projects/qextserialport/files/ 进行下载,也可以去下载论坛上的 http://www.qtcn.org/bbs/read.php?tid=22847 下

Qt编写串口通信程序全程图文解说

(说明:我们的编程环境是windows xp下,在Qt Creator中进行,假设在Linux下或直接用源代码编写,程序稍有不同,请自己修改.) 在Qt中并没有特定的串口控制类,如今大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们能够去 http://sourceforge.net/projects/qextserialport/files/ 进行下载,也能够去下载我上传到网上的: http://download.csdn.net/source/176278

Java程序与RSR232串口通讯小练手(转载)

一直以来都是在学习J2EE方面的应用系统开发,从未想过用JAVA来编写硬件交互程序,不过自己就是喜欢尝试一些未曾接触的新东西.在网上搜索了些资源,了解到JAVA写串口通讯的还是蛮多的,那么便着手准备开发调试环境.软件程序开发环境搭建不成问题,可这硬件环境就有点犯难啦.更何况自己用的是笔记本哪来的串口呀,再说要是真拿这串口硬件来自己也不会弄,随即想到了虚拟机,觉得这东西应该也有虚拟的吧,果真跟自己的猜测一样还真有这东西,顺便也下载了个串口小助手做为调试之用.下面就先看看软件环境的搭建: 1.下载c

多机串口通讯

★使用器件 使用了3块80c51的单片机,其中U1为主机控制其他两个从机U2,U3.每个单片机上都有一个数码管用来显示数据.主机上有两个按键KEY_1,KEY_2,分别用来控制不同的从机. ★实现目标 主要实现的目标就是通过写多机通讯来了解他们其中的协议,以及简单协议的写法!本程序主要达到了一下效果,主机可以通过发送命令来控制从机:发送数据给从机.接收从机的数据.然后将从机或者主机显示的数据显示在数码管上. ★协议要求 1.地址:主机的地址设置为0x01,从机1(U3)的地址为0x03,从机2(

【转载】使用Win32API实现Windows下异步串口通讯

一,异步非阻塞串口通讯的优点 读写串行口时,既可以同步执行,也可以重叠(异步)执行.在同步执行时,函数直到操作完成后才返回.这意味着在同步执行时线程会被阻塞,从而导致效率下降.在重叠执行时,即使操作还未完成,调用的函数也会立即返回.费时的I/O操作在后台进行,这样线程就可以干别的事情.例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作."重叠"一词的含义就在于此. 二,异步非阻塞串口通讯的基本原理首先,确定要打开的串口名.波特率.奇偶校验方式.数据位.

C#用SerialPort实现串口通讯

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Text.RegularExpressions; using System.IO.Ports; names