Chinaunix首页 | 论坛 | 博客
  • 博客访问: 255914
  • 博文数量: 108
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 314
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-29 10:58
文章分类

全部博文(108)

文章存档

2015年(20)

2014年(88)

我的朋友

分类: 嵌入式

2014-04-03 14:06:42

////SeriaPort.h
#ifndef _SERIAL_PORT_H_
#define _SERIAL_PORT_H_


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include


typedef enum _FlowType {
FLOW_OFF,
FLOW_HARDWARE,
FLOW_XONXOFF
} FlowType;


typedef enum _ParityType {
PAR_NONE,
PAR_ODD,
PAR_EVEN,
PAR_SPACE
} ParityType;


typedef enum _DataBitsType {
DATA_5,
DATA_6,
DATA_7,
DATA_8
} DataBitsType;


typedef enum _StopBitsType {
STOP_1,
STOP_2
} StopBitsType;


typedef enum _BaudRateType {
BAUD300,
BAUD600,
BAUD1200,
BAUD2400,
BAUD4800,
BAUD9600,
BAUD19200,
BAUD38400,
BAUD57600,
BAUD115200,
} BaudRateType;


/*structure to contain port settings*/
typedef struct _PortSettings 
{
FlowType FlowControl;
ParityType Parity;
DataBitsType DataBits;
StopBitsType StopBits;
BaudRateType BaudRate;
unsigned long Timeout_Sec;
unsigned long Timeout_Millisec;
} PortSettings;


class CSerialPort
{
public:
static CSerialPort *getSerialPort();
int Read(char *buffer, int size);
int Write(char *buffer, int size);
protected:
int  Serial_Fd;
bool portOpen;
char *tty_name;
PortSettings  Settings;
struct termios Posix_CommConfig;
struct timeval Posix_Timeout;
struct timeval Posix_Copy_Timeout;
void construct(void);
private:
CSerialPort();
~CSerialPort();
static CSerialPort *serialPort;
bool serialOpen();
void setFlowControl(FlowType);
void setParity(ParityType);
void setDataBits(DataBitsType);
void setStopBits(StopBitsType);
void setBaudRate(BaudRateType);
};


#endif

////SeriaPort.cpp
#include "SerialPort.h"
#include


CSerialPort::CSerialPort() //构建端口
{
tty_name = "/dev/ttyS3";
construct();
serialOpen();
}


void CSerialPort::construct(void)    //端口构建
{
Serial_Fd = open(tty_name,O_RDWR| O_NOCTTY | O_NDELAY);
if(Serial_Fd == -1)
{
perror("serial_fd:");
}
portOpen = true;
setBaudRate(BAUD115200);
setDataBits(DATA_8);
setStopBits(STOP_1);
setParity(PAR_NONE);
setFlowControl(FLOW_OFF);
}


void  CSerialPort::setBaudRate(BaudRateType baudRate)    //设置波特率
{
if (portOpen)
{
switch (baudRate)
{


case BAUD300:
#ifdef CBAUD
Posix_CommConfig.c_cflag&=(~CBAUD);
Posix_CommConfig.c_cflag|=B300;
#else
cfsetispeed(&Posix_CommConfig, B300);
cfsetospeed(&Posix_CommConfig, B300);
#endif
break;




case BAUD600:
#ifdef CBAUD
Posix_CommConfig.c_cflag&=(~CBAUD);
Posix_CommConfig.c_cflag|=B600;
#else
cfsetispeed(&Posix_CommConfig, B600);
cfsetospeed(&Posix_CommConfig, B600);
#endif
break;




case BAUD1200:
#ifdef CBAUD
Posix_CommConfig.c_cflag&=(~CBAUD);
Posix_CommConfig.c_cflag|=B1200;
#else
cfsetispeed(&Posix_CommConfig, B1200);
cfsetospeed(&Posix_CommConfig, B1200);
#endif
break;




case BAUD2400:
#ifdef CBAUD
Posix_CommConfig.c_cflag&=(~CBAUD);
Posix_CommConfig.c_cflag|=B2400;
#else
cfsetispeed(&Posix_CommConfig, B2400);
cfsetospeed(&Posix_CommConfig, B2400);
#endif
break;




case BAUD4800:
#ifdef CBAUD
Posix_CommConfig.c_cflag&=(~CBAUD);
Posix_CommConfig.c_cflag|=B4800;
#else
cfsetispeed(&Posix_CommConfig, B4800);
cfsetospeed(&Posix_CommConfig, B4800);
#endif
break;




case BAUD9600:
#ifdef CBAUD
Posix_CommConfig.c_cflag&=(~CBAUD);
Posix_CommConfig.c_cflag|=B9600;
#else
cfsetispeed(&Posix_CommConfig, B9600);
cfsetospeed(&Posix_CommConfig, B9600);
#endif
break;




case BAUD19200:
#ifdef CBAUD
Posix_CommConfig.c_cflag&=(~CBAUD);
Posix_CommConfig.c_cflag|=B19200;
#else
cfsetispeed(&Posix_CommConfig, B19200);
cfsetospeed(&Posix_CommConfig, B19200);
#endif
break;




case BAUD38400:
#ifdef CBAUD
Posix_CommConfig.c_cflag&=(~CBAUD);
Posix_CommConfig.c_cflag|=B38400;
#else
cfsetispeed(&Posix_CommConfig, B38400);
cfsetospeed(&Posix_CommConfig, B38400);
#endif
break;




case BAUD57600:
#ifdef CBAUD
Posix_CommConfig.c_cflag&=(~CBAUD);
Posix_CommConfig.c_cflag|=B57600;
#else
cfsetispeed(&Posix_CommConfig, B57600);
cfsetospeed(&Posix_CommConfig, B57600);
#endif
break;


case BAUD115200:
#ifdef CBAUD
Posix_CommConfig.c_cflag&=(~CBAUD);
Posix_CommConfig.c_cflag|=B115200;
#else
cfsetispeed(&Posix_CommConfig, B115200);
cfsetospeed(&Posix_CommConfig, B115200);
#endif
break;


tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
}
}


}


void CSerialPort::setFlowControl(FlowType flow) //设置流控制
{
if (Settings.FlowControl!=flow)
{
Settings.FlowControl=flow;
}
if (portOpen)
{
switch(flow)
{




case FLOW_OFF: //不采用流控制
Posix_CommConfig.c_cflag&=(~CRTSCTS);
Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY));
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
break;


case FLOW_XONXOFF: //软件流控制
Posix_CommConfig.c_cflag&=(~CRTSCTS);
Posix_CommConfig.c_iflag|=(IXON|IXOFF|IXANY);
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
break;


case FLOW_HARDWARE: //硬件流控制
Posix_CommConfig.c_cflag|=CRTSCTS;
Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY));
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
break;
}
}


}




void CSerialPort::setDataBits(DataBitsType dataBits)  //设置数据位
{
if (Settings.DataBits!=dataBits)
{
Settings.DataBits=dataBits;
}
if (portOpen)
{
switch(dataBits)
{


case DATA_5:
Settings.DataBits=dataBits;
Posix_CommConfig.c_cflag&=(~CSIZE);
Posix_CommConfig.c_cflag|=CS5;
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
break;




case DATA_6:
Settings.DataBits=dataBits;
Posix_CommConfig.c_cflag&=(~CSIZE);
Posix_CommConfig.c_cflag|=CS6;
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
break;


case DATA_7:
Settings.DataBits=dataBits;
Posix_CommConfig.c_cflag&=(~CSIZE);
Posix_CommConfig.c_cflag|=CS7;
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
break;


case DATA_8:
Settings.DataBits=dataBits;
Posix_CommConfig.c_cflag&=(~CSIZE);
Posix_CommConfig.c_cflag|=CS8;
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
break;
}
}


}


void CSerialPort::setStopBits(StopBitsType stopBits) //设置停止位
{
if (Settings.StopBits!=stopBits)
{
Settings.StopBits=stopBits;
}
if (portOpen)
{
switch (stopBits) {




case STOP_1:
Settings.StopBits=stopBits;
Posix_CommConfig.c_cflag&=(~CSTOPB);
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
break;


case STOP_2:
if (Settings.DataBits==DATA_5) {
printf("Posix_QextSerialPort: 2 stop bits cannot be used with 5 data bits");
}
else {
Settings.StopBits=stopBits;
Posix_CommConfig.c_cflag|=CSTOPB;
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
}
break;
}
}


}


void CSerialPort::setParity(ParityType parity) //设置校验位
{
if (Settings.Parity!=parity)
{
Settings.Parity=parity;
}
if (portOpen)
{
switch (parity) {




case PAR_SPACE:
if (Settings.DataBits==DATA_8) {
printf("QSerialComp:  Space parity is only supported in POSIX with 7 or fewer data bits");
}
else {




Posix_CommConfig.c_cflag&=~(PARENB|CSIZE);
switch(Settings.DataBits) {
case DATA_5:
Settings.DataBits=DATA_6;
Posix_CommConfig.c_cflag|=CS6;
break;


case DATA_6:
Settings.DataBits=DATA_7;
Posix_CommConfig.c_cflag|=CS7;
break;


case DATA_7:
Settings.DataBits=DATA_8;
Posix_CommConfig.c_cflag|=CS8;
break;


case DATA_8:
break;
}
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
}
break;


case PAR_NONE:
Posix_CommConfig.c_cflag&=(~PARENB);
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
break;




case PAR_EVEN:
Posix_CommConfig.c_cflag&=(~PARODD);
Posix_CommConfig.c_cflag|=PARENB;
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
break;




case PAR_ODD:
Posix_CommConfig.c_cflag|=(PARENB|PARODD);
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);
break;
}
}


}


bool  CSerialPort::serialOpen() //打开串口
{
tcgetattr(Serial_Fd, &Posix_CommConfig);
Posix_CommConfig.c_cflag|=CREAD|CLOCAL;
Posix_CommConfig.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG));
Posix_CommConfig.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY));
Posix_CommConfig.c_oflag&=(~OPOST);
Posix_CommConfig.c_cc[VMIN]=0;
Posix_CommConfig.c_cc[VTIME]=150;
Posix_CommConfig.c_cc[VINTR] = _POSIX_VDISABLE;
Posix_CommConfig.c_cc[VQUIT] = _POSIX_VDISABLE;
Posix_CommConfig.c_cc[VSTART] = _POSIX_VDISABLE;
Posix_CommConfig.c_cc[VSTOP] = _POSIX_VDISABLE;
Posix_CommConfig.c_cc[VSUSP] = _POSIX_VDISABLE;
setBaudRate(Settings.BaudRate);
setDataBits(Settings.DataBits);
setStopBits(Settings.StopBits);
setParity(Settings.Parity);
setFlowControl(Settings.FlowControl);
tcsetattr(Serial_Fd, TCSAFLUSH, &Posix_CommConfig);


fcntl(Serial_Fd, F_SETFL, 0);


return  portOpen;


}


int CSerialPort::Read(char *buffer, int size) //度数据
{
int rdsize = 0;
if(size <= 0)
return -1;
rdsize = read(Serial_Fd, buffer, size);
return rdsize;
}


int CSerialPort::Write(char *buffer, int size) //写数据
{
int wdsize = 0;
if(size <= 0)
return -1;
wdsize = write(Serial_Fd, buffer, size);
return wdsize;
}


CSerialPort::~CSerialPort()
{
close(Serial_Fd);
}


CSerialPort* CSerialPort::serialPort = new CSerialPort();




CSerialPort *CSerialPort::getSerialPort()
{
return serialPort;
}


//代码转换:从一种编码转为另一种编码 
int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen) 

iconv_t cd;
int rc;
char **pin = &inbuf;
char **pout = &outbuf;


cd = iconv_open(to_charset, from_charset);


if (cd == 0) 
return 1;


memset(outbuf, 0, outlen);


if (iconv(cd, pin, (size_t *)&inlen, pout, (size_t *)&outlen) == -1) 
return 1;


iconv_close(cd);
return 0;

//UNICODE码转为GB2312码 
int u2g(char *inbuf,int inlen,char *outbuf,int outlen) 

return code_convert((char *)("utf-8"),(char *)("gb2312"),inbuf,inlen,outbuf,outlen); 

//GB2312码转为UNICODE码 
int g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen) 

return code_convert((char *)("gb2312"),(char *)("utf-8"),inbuf,inlen,outbuf,outlen); 



int main()
{


char inbuf[BUFSIZ] = {0};
char outbuf[BUFSIZ] = {0};


CSerialPort *serialPort = CSerialPort::getSerialPort();
//serialPort->Write("hello", strlen("hello"));


int pid = fork();


while(1)
{
if (pid > 0)
{
// 发送
printf("you:\n");
memset(inbuf, 0, BUFSIZ);
scanf("%s", inbuf);
u2g(inbuf, strlen(inbuf), outbuf, BUFSIZ);
serialPort->Write(outbuf, strlen(outbuf));
}
else if(pid == 0)
{
sleep(5);
// 接收
memset(inbuf, 0, BUFSIZ);
serialPort->Read(inbuf, BUFSIZ);
g2u(inbuf, BUFSIZ, outbuf, BUFSIZ);
printf("he:%s\n", outbuf);
}
else
{
perror("fork error!");
}


}


return 0;
}

阅读(1188) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~