今天下午写了个串口传文件的程序,发现每次接收时读串口得到的大小都是8个字节左右,不知道什么原因?
以下程序演示了怎样通过串口传文件
编译后先执行./receive
在另一个终端./send tt.txt(单机测试连串口2,3脚,tt.txt是我当前目录下的一个文件)
这样会在当前目录下生成副本serialdata文件
两个程序的源代码如下:
/*------------------------ send.c -----------------------------------*/
/*
dong? possible problems
1: if the sending file is very big, the program will work?
2: if there are some binary files with da ta '\0' in the 100B buffer edge, perhaps the program won't work!
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#define max_buffer_size 100 /*定义缓冲区最大宽度*/
/*******************************************/
int serial_fd; /*定义设备文件描述符*/
int open_serial(int k)
{
if(k==0) /*串口选择*/
{
serial_fd = open("/dev/ttyS0",O_RDWR|O_NOCTTY); /*读写方式打开串口, O_NOCTTY 表如果路径名指向终端设备,不要把这个设备用作控制终端*/
perror("open /dev/ttyS0");
}
else
{
serial_fd = open("/dev/ttyS1",O_RDWR|O_NOCTTY);
perror("open /dev/ttyS1");
}
if(serial_fd == -1) /*打开失败*/
return -1;
else
return 0;
}
/********************************************************************/
int main(int argc, char *argv[] )
{
char sbuf[max_buffer_size];/*待发送的内容*/
int retv;
FILE* filep;
size_t rsize;
struct termios opt;
if(argc!=2)
{ perror("usage: send <filename>\n");
exit(EXIT_FAILURE);
}
if((filep=fopen(argv[1],"r+b"))==NULL)
{ perror("open file error!\n");
exit(EXIT_FAILURE);
}
/*******************************************************************/
if(open_serial(0)<0)/*打开串口1*/
{ perror("cannot open ttyS0!");
exit(EXIT_FAILURE);
}
/*******************************************************************/
printf("ready for sending da ta...\n"); /*准备开始发送数据*/
tcgetattr(serial_fd,&opt);/*把serial_fd的属性保存到opt中,下面稍作修改*/
cfmakeraw(&opt);/*设置某些默认属性,这些默认设置见本文最后的NB注释*/
/*****************************************************************/
cfsetispeed(&opt,B9600); /*波特率输出设置为9600bps*/
cfsetospeed(&opt,B9600);/*波特率输入设置*/
/*******************************************************************/
tcsetattr(serial_fd,TCSANOW,&opt);/*马上改变设置*/
while(!feof(filep))
{ rsize=fread(sbuf,1,max_buffer_size,filep);
if(rsize>0)
{
retv=write(serial_fd,sbuf,rsize); /*发数据*/
if(retv!=rsize)
{
perror("write");
}
printf("the number of charater sent is %d\n",retv);
}
}
//当文件发完,发一个终止信号
sbuf[0]='\0';
retv=write(serial_fd,sbuf,1);
if(retv!=1)
perror("sending stop error!");
if(close(serial_fd)==-1) /*判断是否成功关闭文件*/
perror("Close the Device failur!\n");
if(fclose(filep)<0)
perror("cann't close the sending file!\n");
exit(EXIT_SUCCESS);
}
/*--------------------------receive.c-----------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#define max_buffer_size 100 /*定义缓冲区最大宽度*/
/*********************************************************/
int fd;
int open_serial(int k)
{
if(k==0) /*串口选择*/
{ fd = open("/dev/ttyS0",O_RDWR|O_NOCTTY); /*读写方式打开串口*/
perror("open /dev/ttyS0");
}
else
{ fd = open("/dev/ttyS1",O_RDWR|O_NOCTTY);
perror("open /dev/ttyS1");
}
if(fd == -1) /*打开失败*/
return -1;
else
return 0;
}
/********************************************************************/
int main()
{
char hd[max_buffer_size]; /*定义接收缓冲区*/
int retv,ncount=0;
struct termios opt;
FILE* fp;
/*接收到的数据保存在serialdata文件中*/
if((fp=fopen("serialdata","wb"))==NULL)
{ perror("can not open/create file serialdata.");
exit(EXIT_FAILURE);
}
if(open_serial(0)<0) /*打开串口1*/
{ perror("open serial port0 fail!");
exit(EXIT_FAILURE);
}
tcgetattr(fd,&opt);
cfmakeraw(&opt);
cfsetispeed(&opt,B9600);
cfsetospeed(&opt,B9600);
tcsetattr(fd,TCSANOW,&opt);
printf("ready for receiving da ta...\n");
retv=read(fd,hd,max_buffer_size); /*接收数据*/
/*************************开始接收数据******************************/
while(retv>0) /*判断数据是否接收到*/
{
printf("receive da ta size=%d\n",retv);
ncount+=retv;
if(retv>1 && hd[retv-1]!='\0')
fwrite(hd,retv,1,fp);//write to the file serialdata
else if(retv>1 && hd[retv-1]=='\0')
{ fwrite(hd,retv-1,1,fp);//da ta end with stop sending signal
break;
}
//单独收到终止信号
else if(retv==1 && hd[retv-1]=='\0')
break;
retv=read(fd,hd,max_buffer_size);
}
/*******************************************************************/
printf("The received da ta size is:%d\n",ncount); /*print da ta size*/
printf("\n");
flag_close =close(fd);
if(flag_close== -1) /*判断是否成功关闭文件*/
printf("close the Device failur!\n");
if(fclose(fp)<0)
perror("closing file serialdata fail!");
exit(EXIT_SUCCESS);
}
/*------------------------------------------------------------------------*/
NB:
cfmakeraw() 设置终端属性如下:
termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
termios_p->c_cflag &= ~(CSIZE|PARENB);
termios_p->c_cflag |= CS8;
以下程序演示了怎样通过串口传文件
编译后先执行./receive
在另一个终端./send tt.txt(单机测试连串口2,3脚,tt.txt是我当前目录下的一个文件)
这样会在当前目录下生成副本serialdata文件
两个程序的源代码如下:
/*------------------------ send.c -----------------------------------*/
/*
dong? possible problems
1: if the sending file is very big, the program will work?
2: if there are some binary files with da
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#define max_buffer_size 100 /*定义缓冲区最大宽度*/
/*******************************************/
int serial_fd; /*定义设备文件描述符*/
int open_serial(int k)
{
if(k==0) /*串口选择*/
{
serial_fd = open("/dev/ttyS0",O_RDWR|O_NOCTTY); /*读写方式打开串口, O_NOCTTY 表如果路径名指向终端设备,不要把这个设备用作控制终端*/
perror("open /dev/ttyS0");
}
else
{
serial_fd = open("/dev/ttyS1",O_RDWR|O_NOCTTY);
perror("open /dev/ttyS1");
}
if(serial_fd == -1) /*打开失败*/
return -1;
else
return 0;
}
/********************************************************************/
int main(int argc, char *argv[] )
{
char sbuf[max_buffer_size];/*待发送的内容*/
int retv;
FILE* filep;
size_t rsize;
struct termios opt;
if(argc!=2)
{ perror("usage: send <filename>\n");
exit(EXIT_FAILURE);
}
if((filep=fopen(argv[1],"r+b"))==NULL)
{ perror("open file error!\n");
exit(EXIT_FAILURE);
}
/*******************************************************************/
if(open_serial(0)<0)/*打开串口1*/
{ perror("cannot open ttyS0!");
exit(EXIT_FAILURE);
}
/*******************************************************************/
printf("ready for sending da
tcgetattr(serial_fd,&opt);/*把serial_fd的属性保存到opt中,下面稍作修改*/
cfmakeraw(&opt);/*设置某些默认属性,这些默认设置见本文最后的NB注释*/
/*****************************************************************/
cfsetispeed(&opt,B9600); /*波特率输出设置为9600bps*/
cfsetospeed(&opt,B9600);/*波特率输入设置*/
/*******************************************************************/
tcsetattr(serial_fd,TCSANOW,&opt);/*马上改变设置*/
while(!feof(filep))
{ rsize=fread(sbuf,1,max_buffer_size,filep);
if(rsize>0)
{
retv=write(serial_fd,sbuf,rsize); /*发数据*/
if(retv!=rsize)
{
perror("write");
}
printf("the number of charater sent is %d\n",retv);
}
}
//当文件发完,发一个终止信号
sbuf[0]='\0';
retv=write(serial_fd,sbuf,1);
if(retv!=1)
perror("sending stop error!");
if(close(serial_fd)==-1) /*判断是否成功关闭文件*/
perror("Close the Device failur!\n");
if(fclose(filep)<0)
perror("cann't close the sending file!\n");
exit(EXIT_SUCCESS);
}
/*--------------------------receive.c-----------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#define max_buffer_size 100 /*定义缓冲区最大宽度*/
/*********************************************************/
int fd;
int open_serial(int k)
{
if(k==0) /*串口选择*/
{ fd = open("/dev/ttyS0",O_RDWR|O_NOCTTY); /*读写方式打开串口*/
perror("open /dev/ttyS0");
}
else
{ fd = open("/dev/ttyS1",O_RDWR|O_NOCTTY);
perror("open /dev/ttyS1");
}
if(fd == -1) /*打开失败*/
return -1;
else
return 0;
}
/********************************************************************/
int main()
{
char hd[max_buffer_size]; /*定义接收缓冲区*/
int retv,ncount=0;
struct termios opt;
FILE* fp;
/*接收到的数据保存在serialdata文件中*/
if((fp=fopen("serialdata","wb"))==NULL)
{ perror("can not open/create file serialdata.");
exit(EXIT_FAILURE);
}
if(open_serial(0)<0) /*打开串口1*/
{ perror("open serial port0 fail!");
exit(EXIT_FAILURE);
}
tcgetattr(fd,&opt);
cfmakeraw(&opt);
cfsetispeed(&opt,B9600);
cfsetospeed(&opt,B9600);
tcsetattr(fd,TCSANOW,&opt);
printf("ready for receiving da
retv=read(fd,hd,max_buffer_size); /*接收数据*/
/*************************开始接收数据******************************/
while(retv>0) /*判断数据是否接收到*/
{
printf("receive da
ncount+=retv;
if(retv>1 && hd[retv-1]!='\0')
fwrite(hd,retv,1,fp);//write to the file serialdata
else if(retv>1 && hd[retv-1]=='\0')
{ fwrite(hd,retv-1,1,fp);//da
break;
}
//单独收到终止信号
else if(retv==1 && hd[retv-1]=='\0')
break;
retv=read(fd,hd,max_buffer_size);
}
/*******************************************************************/
printf("The received da
printf("\n");
flag_close =close(fd);
if(flag_close== -1) /*判断是否成功关闭文件*/
printf("close the Device failur!\n");
if(fclose(fp)<0)
perror("closing file serialdata fail!");
exit(EXIT_SUCCESS);
}
/*------------------------------------------------------------------------*/
NB:
cfmakeraw() 设置终端属性如下:
termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
termios_p->c_cflag &= ~(CSIZE|PARENB);
termios_p->c_cflag |= CS8;