RS485串口驱动源代码
1、前言串口驱动是最简单的一种驱动了,在Linux下一切设备都认为是文件,打开设备就像打开文件一样简单,直接上代码2、RS485.c//--------------------------------------------------------------------------------------------------// Include head files//-----------
·
1、前言
串口驱动是最简单的一种驱动了,在Linux下一切设备都认为是文件,打开设备就像打开文件一样简单,直接上代码
2、RS485.c
//--------------------------------------------------------------------------------------------------
// Include head files
//--------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include "RS485.h"
//-------------------------------------------------------------------------------------------------
// Private Definitions
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
// Private Members
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
// Private Functions
//-------------------------------------------------------------------------------------------------
static int SetAttributes(int fd, RS485PARA Rs485Para)
{
struct termios newtio;
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);
break;
case B_19200:
cfsetispeed(&newtio, B19200);
break;
case B_38400:
cfsetispeed(&newtio, B38400);
break;
case B_57600:
cfsetispeed(&newtio, B57600);
break;
case B_115200:
cfsetispeed(&newtio, B115200);
break;
default:
cfsetispeed(&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, TCOFLUSH);
if ((tcsetattr(fd, TCSADRAIN, &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;
int nZero = 0;
if (NULL == pDevname)
{
printf("RS485 device name is null\n");
return -1;
}
fd = open(pDevname, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
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)
{
int nleft;
int nread;
char* ptr = NULL;
ptr = buf;
nleft = size;
while (nleft > 0)
{
nread = read(fd, ptr, nleft);
if (nread <= 0)
{
break;
}
nleft -= nread;
ptr += nread;
}
return (size - nleft);
}
int RS485Write(int fd, const void* buf, int size)
{
int nleft = 0;
int nwritten = 0;
const char* ptr = NULL;
struct termios option;
ptr = buf;
nleft = size;
while (nleft > 0)
{
nwritten = write(fd, ptr, nleft);
if (nwritten <= 0)
{
break;
}
nleft -= nwritten;
ptr += nwritten;
}
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读取数据就可以了
更多推荐
所有评论(0)