linux串口传文件程序

今天下午写了个串口传文件的程序,发现每次接收时读串口得到的大小都是8个字节左右,不知道什么原因?
以下程序演示了怎样通过串口传文件

编译后先执行./receive
在另一个终端./send tt.txt(单机测试连串口23脚,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 data '\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 data...\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 data...\n");

    retv=read(fd,hd,max_buffer_size);   /*接收数据*/
/*************************开始接收数据******************************/
    while(retv>0)       /*判断数据是否接收到*/
    {
       printf("receive data 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);//data 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 data size is:%d\n",ncount);  /*print data 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;
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值