/*----------------------------------------
==========================================
Linux操作系统下串口编程
===========================================
--------------------------------------------*/



#include <stdio.h> /*标准输入输出定义*/
#include <stdlib.h> /*标准函数库定义*/
#include <unistd.h> /*Unix 标准函数定义*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> /*文件控制定义*/
#include <termios.h> /*PPSIX 终端控制定义*/
#include <errno.h> /*错误号定义*/



#define COM1 1 //"/dev/ttyS0" //串口一
#define COM2 2 //"/dev/ttyS1" //串口二



#define TURE 0
#define FALSE -1



class Ctermios
{
public: 
Ctermios(); //构造函数
~Ctermios(); //析构函数
void OpenSerialPort(int); //打开串口
void CloseSerialPort(); //关闭串口
void ReadSerialPort(); //从串口中读取数据
void WriteSerialPort(); //向串口写入数据
void SetSerialPort();

private:
struct termios opt;
int fd;
char buffR[512];
char buffW[512];
int LenR;
int LenW;


int OpenDev(char *Dev);
void set_speed(int fd,int speed);
int set_Parity(int fd,int databits,int stopbits,int parity);


};
/*--------------------------------------------------
构造函数
---------------------------------------------------*/
Ctermios::Ctermios()
{
struct termios opt;
LenR = 512;
LenW = 512;
}



/*--------------------------------------------------
析构函数
----------------------------------------------------*/
Ctermios::~Ctermios()
{
tcflush(fd,TCIOFLUSH); //清数据机线并启动序列阜的设定
if(close(fd)==0)
exit(0);
}




/*==================================================================
私有函数 初始化串口
===================================================================*/


int Ctermios::OpenDev(char *Dev)
{
int fd = open( Dev, O_RDWR );
//| O_NOCTTY | O_NDELAY
if (fd == -1)
{
perror("Can't Open Serial Port"); //打开串口文件时发生错误
return -1;
}
else
return fd; //返回文件ID
}




/*=========================================================================
设置串口通信速率

fd 类型 int 打开串口的文件句柄
speed 类型 int 串口速度
return void
==========================================================================*/
void Ctermios::set_speed(int fd,int speed)
{
int i;
int status;
int name_arr[]={38400,19200,9600,4800,2400,1200,300, 38400,19200,9600,4800,2400,1200,300 ,};
int speed_arr[]={B38400,B19200,B9600,B4800,B2400,B1200,B300, B38400,B19200,B9600,B4800,B2400,B1200,B300 ,};
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 Ctermios::set_Parity(int fd,int databits,int stopbits,int 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,"Unsuipported data size\n");


return(FALSE);
}
switch(parity)
{
case'n':
case'N':
options.c_cflag&=~PARENB;
options.c_iflag&=~INPCK;
break;
case'o':
case'O':
options.c_cflag|=(PARODD|PARENB);
options.c_iflag|=INPCK;
break;
case'e':
case'E':
options.c_cflag|=PARENB;
options.c_cflag&=~PARODD;
options.c_iflag|=INPCK;
break;
case's':
case'S':
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);
}
if (parity!='n')
options.c_iflag|=INPCK;
options.c_cc[VTIME]=150;
options.c_cc[VMIN]=0;

tcflush(fd,TCIFLUSH);
if(tcsetattr(fd,TCSANOW,&options)!=0)
{

perror("SetupSerial 3");
return(FALSE);
}
return(TURE);
}

/*=========================================================================*/




/*---------------------------------------------------------
公有函数 打开串口
-------------------------------------------------------*/
void Ctermios::OpenSerialPort(int com)
{
char *dev ;
switch(com)
{
case COM1:
dev = "/dev/ttyS0"; break;
case COM2:
dev = "/dev/ttyS1"; break;
default:
exit(-1);
}
fd=OpenDev(dev);
set_speed(fd,B9600);

//@@@@@
if(set_Parity(fd,8,1,'N') == -1)
{
printf("Set Parity Error\n");
exit(-1);
}


}



/*---------------------------------------------------------
==========================================================
公有函数 设置串口属性
===========================================================
-------------------------------------------------------*/
void Ctermios::SetSerialPort()
{
int sp;
printf("please input baute rate\n");
printf("default rate please input 9600");
scanf("%d",&sp);
set_speed(fd,sp);
int dt,st;
printf("please input databits stopbits \n");
printf("default rate please input 8 1 ");
scanf("%d %d",&dt,&st);
if(set_Parity(fd,dt,st,'N')==FALSE)
{
printf("Set Parity Error\n");
exit(0);
}

}



/*---------------------------------------------------------
==========================================================
公有函数 读取串口信息
===========================================================
-------------------------------------------------------*/
void Ctermios::ReadSerialPort()
{
int nread;
while(nread!=0)
{
while((nread=read(fd,buffR,511)>0))
{
printf("\nLen %d\n",nread);
buffR[nread+1]='\0';
printf("\n%s",buffR);
}
if (nread==-1)
{
printf("read error!\n");
exit(-1);
}
}


}



/*---------------------------------------------------------
==========================================================
公有函数 发送串口信息
===========================================================
-------------------------------------------------------*/
void Ctermios::WriteSerialPort()
{
int nwrite;
char bb;
int i;
while(nwrite!=-1)
{
for(i=0;i<512;i++)
{
bb=getchar();
buffW[i]=bb;
}
nwrite=write(fd,buffW,512);
}
}



/*---------------------------------------------------------
==========================================================
公有函数 关闭串口
===========================================================
-------------------------------------------------------*/

void Ctermios::CloseSerialPort()
{
close(fd);
}



/*---------------------------------------------------------
==========================================================
main函数 联调测试用
===========================================================
-------------------------------------------------------*/


◎◎◎◎◎◎



这边的测试联调函数没有写,有谁有环境的帮忙写个函数测试一下,谢谢!主要就是测试能不能收到信息!麻烦再把联调的函数发上来


ps:这段代码是再网上找的,自己认真的看了一下,还是有点问题,所以向大家请教