IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> RS485串口驱动源代码 -> 正文阅读

[系统运维]RS485串口驱动源代码

1、前言

? ? ? ?串口驱动是最简单的一种驱动了,在Linux下一切设备都认为是文件,打开设备就像打开文件一样简单,直接上代码

2、RS485.c

//--------------------------------------------------------------------------------------------------
// Include head files
//--------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <fcntl.h> /* File control definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>

#include "RS485.h"

//-------------------------------------------------------------------------------------------------
// Private Definitions
//-------------------------------------------------------------------------------------------------
#define RETRY_TIMES         3

//-------------------------------------------------------------------------------------------------
// Private Members
//-------------------------------------------------------------------------------------------------


//-------------------------------------------------------------------------------------------------
// Private Functions
//-------------------------------------------------------------------------------------------------
static int SetAttributes(int fd, RS485PARA Rs485Para)
{
    struct termios newtio, oldtio;

    if (tcgetattr(fd, &oldtio) != 0)
    {
        printf("com error:%s\n", strerror(errno));
        return -1;
    }

    bzero(&newtio, sizeof(newtio));

    newtio.c_cflag |= CLOCAL | CREAD;
    newtio.c_cflag &= ~CSIZE;

    switch (Rs485Para.m_Bits)
    {
        case SEVEN:
            newtio.c_cflag |= CS7;
            break;
        case EIGHT:
            newtio.c_cflag |= CS8;
            break;
        default:
            newtio.c_cflag |= CS8;
    }

    switch (Rs485Para.m_Parity)
    {
        case O:
            newtio.c_cflag |= PARENB;
            newtio.c_cflag |= PARODD;
            newtio.c_iflag |= (INPCK);
            break;
        case E:
            newtio.c_iflag |= (INPCK);
            newtio.c_cflag |= PARENB;
            newtio.c_cflag &= ~PARODD;
            break;
        case N:
            newtio.c_cflag &= ~PARENB;
            break;
        default:
            newtio.c_cflag &= ~PARENB;
    }

    switch (Rs485Para.m_BaudRate)
    {
        case B_9600:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
        case B_19200:
            cfsetispeed(&newtio, B19200);
            cfsetospeed(&newtio, B19200);
            break;
        case B_38400:
            cfsetispeed(&newtio, B38400);
            cfsetospeed(&newtio, B38400);
            break;
        case B_57600:
            cfsetispeed(&newtio, B57600);
            cfsetospeed(&newtio, B57600);
            break;
        case B_115200:
            cfsetispeed(&newtio, B115200);
            cfsetospeed(&newtio, B115200);
            break;
        default:
            cfsetispeed(&newtio, B19200);
            cfsetospeed(&newtio, B19200);
    }

    if (Rs485Para.m_Stop == ONE)
    {
        newtio.c_cflag &= ~CSTOPB;
    }
    else if (Rs485Para.m_Stop == TWO)
    {
        newtio.c_cflag |= CSTOPB;
    }
    else
    {
        newtio.c_cflag &= ~CSTOPB;
    }

    newtio.c_cc[VTIME] = 5;
    newtio.c_cc[VMIN] = 0;
    tcflush(fd, TCIFLUSH);

    if ((tcsetattr(fd, TCSANOW, &newtio)) != 0)
    {
        printf("com set error:%s\n", strerror(errno));
        return -1;
    }

    return 0;
}

//-------------------------------------------------------------------------------------------------
// Public Functions
//-------------------------------------------------------------------------------------------------
int RS485Open(const char *pDevname, RS485PARA Rs485Para)
{
    int ret = 0;
	int fd = 0;

    if (NULL == pDevname)
    {
        printf("RS485 device name is null\n");
        return -1;
    }

    fd = open(pDevname, O_RDWR);
    if (fd > 0)
    {
        ret = SetAttributes(fd, Rs485Para);
        if (ret != 0)
        {
            printf("Set RS485 port failed, error=%s\n", strerror(errno));
            return -1;
        }
    }
    else
    {
        printf("Can't open the port %s,error=%s\n", pDevname, strerror(errno));
        return -1;
    }

    return fd;
}

int RS485Read(int fd, void* buf, int size)
{
    char *pBuff = buf;
    int readLn = 0;

    if (fd < 0)
    {
        printf("RS485 Write Para error, fd = %d\n", fd);
        return -1;
    }

    if (NULL == pBuff)
    {
        printf("RS485 device read pointer %s is null\n", "buf");
        return -1;
    }

    auto int retry = RETRY_TIMES;
    do
    {
        readLn = read(fd, buf, size);
        if ((readLn < 0) && (errno ==  EINTR))
        {
            printf("RX has fatal fault, errno = %d!\n", EINTR);
        }
        else
        {
            break;
        }

        retry--;
    }while (retry);

    return readLn;
}

int RS485Write(int fd, const void *buf, int size)
{
    char *pBuff = (char *)buf;

    if (NULL == pBuff)
    {
        printf("RS485 Write Para error\n");
        return -1;
    }

    if (fd < 0)
    {
        printf("RS485 Write Para error\n");
        return -1;
    }

    auto int willSize = size;
    do
    {
        int rslt = write(fd, buf, willSize);

        if (rslt == -1) /EAGAIN
        {
            printf("write failed:%s\n", strerror(errno));

            switch (errno)
            {
                case EINTR:
                case EAGAIN:
                    break;
                default:
                    return -1;
            }
            return 0;
        }
        else
        {
            pBuff += rslt;
            willSize -= rslt;
        }
    }while (willSize > 0);

    return size;
}

int RS485Close(int fd)
{
    if (fd > 0)
    {
        close(fd);
    }
    else
    {
        return -1;
    }
    

    return 0;
}

3、RS485.h

#ifndef RS485_H
#define RS485_H

//-------------------------------------------------------------------------------------------------
// Public Includes
//-------------------------------------------------------------------------------------------------


//-------------------------------------------------------------------------------------------------
// Public Definitions
//-------------------------------------------------------------------------------------------------
enum BaudRate
{
    B_9600   = 0,
    B_19200  = 1,
    B_38400  = 2,
    B_57600  = 3,
    B_115200 = 4,
    B_40000  = 5,
    B_25000  = 6,
};

enum Bits
{
    SEVEN = 7,
    EIGHT = 8,
};

enum Parity
{
    O = 0,
    E = 1,
    N = 3,
};

enum Stop
{
    ONE = 1,
    TWO = 2,
};


//-------------------------------------------------------------------------------------------------
// Public Types
//-------------------------------------------------------------------------------------------------
typedef struct tag_RS485PARA
{
    unsigned char m_BaudRate;
    unsigned char m_Bits;
    unsigned char m_Parity;
    unsigned char m_Stop;
}RS485PARA;

//-------------------------------------------------------------------------------------------------
// Public Functions
//-------------------------------------------------------------------------------------------------

/**
 * Description: open a uart , rturn the fd
 *
 * @param pDevname          [in]  uart name with path
 * @param Rs485Para         [in]  uart parater which run correctly 
 * @return                  [out] fd value
 */
extern int RS485Open(const char *pDevname, RS485PARA Rs485Para);

/**
 * Description: read data to buf from fd
 *
 * @param fd                [in]  uart fd
 * @param buf               [in]  store data from uart 
 * @param size              [in]  data len from uart  
 * @return                  [out] data len to be read
 */
extern int RS485Read(int fd, void* buf, int size);

/**
 * Description: read data to buf from fd
 *
 * @param fd                [in]  uart fd
 * @param buf               [in]  store data from uart 
 * @param size              [in]  data len of buf  
 * @return                  [out] data len to be writen
 */
extern int RS485Write(int fd, const void *buf, const int size);

/**
 * Description: read data to buf from fd
 *
 * @param fd                [in]  uart fd
 * @return                  [out] RET_STATUS_OK if OK
 */
extern int RS485Close(int fd);
 
 
#endif 

4、总结

注意设置的方式是非阻塞,500毫秒等待时间,在外部程序中使用select/epool等方式去调用read读取数据就可以了

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 19:10:50  更:2022-03-30 19:11:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 23:43:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码