在7688上写了个串口接受并把接收的数据发回,在这个过程中一直有回传,就是电脑串口发送给7688一次数据,7688把这些数据接收到,然后再发送回电脑。遇到问题:每次电脑发送一次,然而接收框里接收两次数据。解决是在配置里添加GNBRK;仔细研究可以查看termios 详解。一下是修改后程序。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define serial_device "/dev/ttyS1"
//打开串口
int open_port(void)
{
int fd; //串口的标识符
//O_NOCTTY用来告诉Linux这个程序不会成为“控制终端”
//O_NDELAY用来告诉Linux这个程序不关心DCD信号
fd=open(serial_device,O_RDWR|O_NOCTTY);
if(fd == -1)
{
//不能打开串口
perror("open_port: Unable to open /dev/ttyS0 -");
return(fd);
}
else
{
fcntl(fd, F_SETFL, 0);
printf("open ttys1 .....\n");
return(fd);
}
}
//设置波特率
void set_speed_and_parity(int fd, int speed)
{
struct termios Opt; //定义termios结构
if(tcgetattr(fd,&Opt)!=0)
{
perror("tcgetattr fd");
return;
}
tcflush(fd, TCIOFLUSH);//清空缓存
cfsetispeed(&Opt, B115200);//设置波特率
cfsetospeed(&Opt, B115200);
//tcflush(fd, TCIOFLUSH);
//设置奇偶校验——默认8个数据位、没有校验位
Opt.c_cflag &= ~PARENB;
Opt.c_cflag &= ~CSTOPB;
Opt.c_cflag &= ~CSIZE;
Opt.c_cflag |= CS8;
Opt.c_cflag &= ~(CLOCAL);
Opt.c_cflag |= CREAD;
Opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
//软件流控制无效,因为硬件没有硬件流控制,所以就不需要管了
Opt.c_iflag &= ~(IXON | IXOFF | IXANY);
Opt.c_iflag |= IGNBRK;
//原始输出方式可以通过在c_oflag中重置OPOST选项来选择:
Opt.c_oflag &= ~OPOST;
//VMIN可以指定读取的最小字符数。如果它被设置为0,那么VTIME值则会指定每个字符读取的等待时间。
Opt.c_cc[VTIME] = 0;
Opt.c_cc[VMIN] = 0;
/*tcsetattr函数标志:
TCSANOW:立即执行而不等待数据发送或者接受完成。
TCSADRAIN:等待所有数据传递完成后执行。
TCSAFLUSH:Flush input and output buffers and make the change
*/
if(tcsetattr(fd, TCSANOW, &Opt) != 0)
{
perror("tcsetattr fd");
return;
}
tcflush(fd, TCIOFLUSH);
}
int serial_write(int fd ,char *data, int datalen)
{
int len=0;
//获取实际传输数据的长度
len=write(fd,data,datalen);
printf("send data OK! datalen=%d\n",len);
return len;
}
int serial_read(int fd,char buff[],int datalen)
{
int nread=0;
//printf("Ready for receiving data...");
nread=read(fd,buff,datalen);
if(nread>0)
{
printf("readlength=%d\n",nread);
buff[nread]='\0';
//printf("%s\n",buff);
}
return nread;
}
int serialport()
{
int fd;
//打开串口
if((fd=open_port())<0)
{
perror("open_port error");
return 0;
}
//设置波特率和校验位
set_speed_and_parity(fd,115200);
return (fd);
}
int main(void)
{
int fd;
int nread,i,n =0,datalen=0, len = 0;
char test[8]="Hello\r\n";
char writebuf[100];
char readbuff[100];
fd=serialport();
printf("fd=%d\n",fd);
//尝试先写内容
//循环读取串口并输出
printf("enter the while loop\n");
//这个是重点,当时我就是这个问题出错了,每次读之前必须清空一次。
bzero(readbuff, sizeof(readbuff));
bzero(writebuf, sizeof(writebuf));
//writebuf = "a1a2a3a4";
serial_write(fd,test,8);
sleep(1);
while(1)
{
// printf("enter the while loop\n");
//serial_write(fd,test,8);
bzero(readbuff, sizeof(readbuff));
sleep(1);
datalen=serial_read(fd,readbuff,512);
if(datalen > 0)
{
if(readbuff[0]=='O'&&readbuff[1]=='F'&&readbuff[2]=='F')
{
break;
}
serial_write(fd,readbuff,datalen);
}
}
}
下面这句
if(tcsetattr(fd, TCSANOW, &Opt) != 0)
{
perror("tcsetattr fd");
return;
}
把串口设置完参数后,使用这句生效。
在linux中sleep()是挂起1s,用usleep()是挂起微秒。