#ifndef CSERIAL_H_
#define CSERIAL_H_
#include <time.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> /*文件控制定义*/
#include <termios.h> /*PPSIX 终端控制定义*/
#include <errno.h> /*错误号定义*/
#include <sys/select.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include"ParseConfig.h"
#define BUFFER_LENGTH 512
void *ComThreadR(void *pPM);
void *ComThreadW(void *pPM);
class CSerial
{
public:
CSerial();
virtual ~CSerial();
int m_fd;
char *m_ReadBuffer;
int m_ReadSize;
int OnLine;
void StartMonitoring();
void ReceiveChar();
void WriteChar();
pthread_t m_Thread[2];
int InitPort(char* PortName = "3",int baudrate = 38400,int databits = 8,int stopbits = 1,char parity = 'E');
private:
void set_speed(int fd, int speed);
int set_Parity(int fd,int databits,int stopbits,char parity);
};
#endif /* CSERIAL_H_ */
#include "CSerial.h"
extern int g_event[2];
extern char TcpRecv[512];
extern char ComRecv[512];
extern int TcpRecvNum;
extern int ComRecvNum;
int speed_arr[] = {B115200,B57600,B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400,
B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {115200,57600,38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200,
9600, 4800, 2400, 1200, 300, };
CSerial::CSerial()
{
OnLine = 0;
m_ReadSize = 0;
m_ReadBuffer = new char[BUFFER_LENGTH];
}
CSerial::~CSerial()
{
if (m_ReadBuffer != NULL)
delete [] m_ReadBuffer;
close(m_fd);
}
int CSerial::InitPort(char* PortName, int baudrate, int databits,int stopbits, char parity)
{
char ComName[100]= {0};
char ComBaud[100] = {0};
ParseConfig("/root/Desktop/TCP/configure.txt","ComName",ComName);
ParseConfig("/root/Desktop/TCP/configure.txt","ComBaud",ComBaud);
printf("ComName = %s,ComBaud = %s\n",ComName,ComBaud);
while(1)
{
m_fd = open(ComName, O_RDWR|O_NDELAY|O_NOCTTY);
if (-1 == m_fd)
{
perror(" com open ..");
OnLine = 0;
sleep(2);
continue;
} else
{
set_speed(m_fd, atoi(ComBaud));
set_Parity(m_fd, databits, stopbits, parity);
OnLine = 1;
printf("com open ok m_fd = %d, ComName = %s,baud = %d\n",m_fd,ComName,atoi(ComBaud));
break;
}
}
return 0;
}
void CSerial::StartMonitoring()
{
int ret = pthread_create (&m_Thread[0], NULL, ComThreadR, this);
if (ret != 0)
{
perror ("com pthread_1_create");
}
ret = pthread_create (&m_Thread[1], NULL, ComThreadW, this);
if (ret != 0)
{
perror ("com pthread_2_create");
}
return;
}
void *ComThreadR(void *pPM)
{
//读线程
CSerial *p_Com = (CSerial*)pPM;
p_Com->InitPort();
p_Com->ReceiveChar();
return (void *) 0;
}
void *ComThreadW(void *pPM)
{
//写线程
CSerial *p_Com = (CSerial*)pPM;
p_Com->WriteChar();
return (void *) 0;
}
void CSerial::WriteChar()
{
int nRet = 0;
char SendStr[] = {0x01,0x05,0x08,0x03,0xff,0x00,0x7e,0x5a};
while(1)
{
if(OnLine == 0)
{
//the com off line
usleep(10000);
continue;
}
else
{
if(g_event[0] == 0)
{
//have nothing to send
usleep(10000);
continue;
}
else
{
nRet = write(m_fd, TcpRecv, TcpRecvNum);
if(nRet == -1)
{
printf("com off line now:WriteChar()\n");
continue;
}
else if(nRet != TcpRecvNum)
{
printf("com send less than nRet != TcpRecvNum\n");
nRet = write(m_fd, TcpRecv, TcpRecvNum);
if(nRet == TcpRecvNum)
{
printf("com send ok\n");
TcpRecvNum = 0;
g_event[0] = 0;
memset(ComRecv,0,sizeof(ComRecv));
}
continue;
}
else if(nRet == TcpRecvNum)
{
printf("com send ok\n");
TcpRecvNum = 0;
g_event[0] = 0;
#if 0
ComRecvNum = nRet;
for(int i = 0;i < nRet;i++)
ComRecv[i] = TcpRecv[i];
g_event[1] = 1;
#endif
memset(TcpRecv,0,sizeof(TcpRecv));
}
else if(nRet == 0)
{
printf("com 1 off line now:WriteChar()\n");
continue;
}
}
}
}
}
void CSerial::ReceiveChar()
{
printf("ReceiveChar,m_fd = %d\n",m_fd);
int nRet = 0;
fd_set set;
FD_ZERO(&set);
FD_SET(m_fd,&set);
int flag = 0;
while(1)
{
if(select(m_fd+1,&set,NULL,NULL,NULL)>0)
{
while(1)
{
memset(m_ReadBuffer,0,sizeof(m_ReadBuffer));
nRet=read(m_fd, m_ReadBuffer, 499);
if(nRet==-1)
{
//出错断开(例如客户端执行了超时操作导致自己断开)
printf("com nRet==-1\n");
OnLine = 0;
FD_CLR(m_fd,&set);
close(m_fd);
InitPort();
FD_SET(m_fd,&set);
break;
}
if(nRet>0)
{
flag++;
//收到新的数据
printf("nRet = %d,m_fd = %d,com recv is ",nRet,m_fd);
for(int i = 0;i<nRet;i++)
{
printf("%x ",m_ReadBuffer[i]&0xff);
}
printf("\n");
// ComRecvNum = nRet;
//strcpy(ComRecv,m_ReadBuffer);
for(int i = 0;i < nRet;i++)
ComRecv[ComRecvNum++] = m_ReadBuffer[i];
usleep(10000);
continue;
}
if(nRet == 0 && flag != 0)
{
g_event[1] = 1;
flag = 0;
printf("com read nRet == 0 && flag != 0\n");
break;
}
if(nRet==0 && flag == 0)
{
//客户断开
printf("TCP nRet==0 && flag == 0\n");
OnLine = 0;
FD_CLR(m_fd,&set);
close(m_fd);
InitPort();
FD_SET(m_fd,&set);
break;
}
}
}
}
}
/**
*@brief 设置串口通信速率
*@param fd 类型 int 打开串口的文件句柄
*@param speed 类型 int 串口速度
*@return void
*/
void CSerial::set_speed(int fd, int speed)
{
unsigned int i;
int status;
struct termios Opt;
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)
{
perror("tcsetattr fd1");
return;
}
tcflush(fd, TCIOFLUSH);
}
}
}
/**
*@brief 设置串口数据位,停止位和效验位
*@param fd 类型 int 打开的串口文件句柄
*@param databits 类型 int 数据位 取值 为 7 或者8
*@param stopbits 类型 int 停止位 取值为 1 或者2
*@param parity 类型 int 效验类型 取值为N,E,O,,S
*/
int CSerial::set_Parity(int fd, int databits, int stopbits, char parity) {
struct termios options;
if (tcgetattr(fd, &options) != 0) {
perror("SetupSerial 1");
return (false);
}
options.c_cflag &= ~CSIZE;
switch (databits) /*设置数据位数*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr, "Unsupported data size\n");
return (false);
}
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:
fprintf(stderr, "Unsupported parity\n");
return (false);
}
/* 设置停止位*/
switch (stopbits) {
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr, "Unsupported stop bits\n");
return (false);
}
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN); /*Input*/
options.c_iflag &= ~(IXON | IXOFF | IXANY);//关流控
options.c_iflag &= ~(INLCR | IGNCR | ICRNL | IUCLC | IGNBRK|BRKINT|PARMRK|ISTRIP);
options.c_oflag &= ~(ONLCR | OCRNL | ONLRET | ONOCR | OLCUC | OFILL | CRTSCTS);
options.c_oflag &= ~OPOST; /*Output*/
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
tcflush(fd, TCIFLUSH);
options.c_cc[VTIME] = 0; /* 设置超时15 seconds*/
options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
if (tcsetattr(fd, TCSANOW, &options) != 0) {
perror("SetupSerial 3");
return (false);
}
return (true);
}
=================================================================================================================
程序猿和程序媛必备的咖啡-OneDay咖啡生活-https://shop110384469.taobao.com/