通过串口读写二进制数据 [英] Reading and writing binary data over serial port

查看:129
本文介绍了通过串口读写二进制数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我四处搜寻,却找不到我需要的东西.我需要通过串行端口读写二进制数据的帮助,希望您能提供任何建议.请注意,当我处于该项目的不同阶段时,我曾问过类似的问题.

So I searched around, and couldn't exactly find what I needed. I need help reading and writing binary data over a serial port, and would appreciate any advice you may have. Please note, I asked a question similar to this earlier when I was at a different stage of this project.

下面是程序.第一个程序打开一个文件"test.jpg",以二进制模式读取它,并将结果存储在缓冲区中.然后关闭文件,并应该通过串行端口发送该文件.

Below are programs. The first program opens a file "test.jpg", reads it in binary mode and stores the result in a buffer. It then closes the file, and is supposed to send that file over a serial port.

第二个程序创建一个名为"testout.jpg"的文件,并应读取上一个程序发送的数据.

The second program creates a file called "testout.jpg", and is supposed to read in the data sent from the previous program.

我预感代码中的问题出在第二个程序中.也许我也需要使用fread吗?我尝试过,但是由于对编程还比较陌生,所以我不知道如何在串行端口上实现它.

I have a hunch that the problem in my code lies in the second program. Perhaps I need to use fread for that too? I tried, but I cannot figure out how to implement it for a serial port as I am relatively new to programming.

非常感谢您的宝贵时间.

Many thanks for your time.

串行写入:

    #include <stdio.h>   /* Standard input/output definitions */
    #include <string.h>  /* String function definitions */
    #include <unistd.h>  /* UNIX standard function definitions */
    #include <fcntl.h>   /* File control definitions */
    #include <errno.h>   /* Error number definitions */
    #include <termios.h> /* POSIX terminal control definitions */
    #include <stdlib.h>

    int main()
        {
                //writing
                int writeport = open_port("/dev/ttyUSB0");

                //open file

                FILE *file;
                char *buffer;
                int fileLen;

                file = fopen("test.jpg", "rb");

                //get file size

                fseek(file, 0, SEEK_END);
                fileLen = ftell(file);
                fseek(file, 0, SEEK_SET);

                buffer = (char *)malloc(fileLen + 1);

                //read file contents

                fread(buffer, fileLen, 1, file);
                fclose(file);

                int n = write(writeport, buffer, fileLen + 1);
                if (n < 0)
                        fputs("write() of bytes failed!\n", stderr);

                //closing ports
                close(writeport);
        }

        int open_port(char str[])
    {
        int fd = open(str, O_RDWR | O_NOCTTY | O_NONBLOCK); // ?? NDELAY or NONBLOCK?

      if (fd == -1)
      {
                        perror("open_port: Unable to open /dev/ttyS0 - ");
      }
      else
                        fcntl(fd, F_SETFL, 0);

          struct termios options;
          tcgetattr(fd, &options); //this gets the current options set for the port

          // setting the options

          cfsetispeed(&options, B9600); //input baudrate
          cfsetospeed(&options, B9600); // output baudrate
          options.c_cflag |= (CLOCAL | CREAD); // ?? enable receicer and set local mode
          //options.c_cflag &= ~CSIZE; /* mask the character size bits */
          options.c_cflag |= CS8;    /* select 8 data bits */
          options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // choosing raw input
          options.c_iflag &= ~INPCK; // disable parity check
          options.c_iflag &= ~(IXON | IXOFF | IXANY); // disable software flow control
          options.c_oflag |= OPOST; // ?? choosing processed output
          options.c_cc[VMIN] = 0; // Wait until x bytes read (blocks!)
          options.c_cc[VTIME] = 0; // Wait x * 0.1s for input (unblocks!)

          // settings for no parity bit
          options.c_cflag &= ~PARENB;
          options.c_cflag &= ~CSTOPB;
          options.c_cflag &= ~CSIZE;
          options.c_cflag |= CS8;

          tcsetattr(fd, TCSANOW, &options); //set the new options ... TCSANOW specifies all option changes to occur immediately

      return (fd);
    }

序列读取:

    #include <stdio.h>   /* Standard input/output definitions */
    #include <string.h>  /* String function definitions */
    #include <unistd.h>  /* UNIX standard function definitions */
    #include <fcntl.h>   /* File control definitions */
    #include <errno.h>   /* Error number definitions */
    #include <termios.h> /* POSIX terminal control definitions */

    int main()
        {
                //reading      
                int readport = open_port("/dev/ttyUSB1");

        //open resultant file

        FILE *file;
        //system("rm testout.jpg");
        file = fopen("testout.jpg", "wb");

                //trying to read one character at a time
                char buff;
                int n = 1;

           while (n > 0)
           {
                n = read(readport, &buff, 1);
                //printf("%c", buff, buff);

                **//I tried these three methods, with little success**

                //fprintf(file, "%c", buff);
                //fwrite(&buff, 1, 1, file);
                //write(file, &buff, 1);
           }

                //closing ports
                close(readport);
                fclose(file);
        }

        int open_port(char str[])
    {
        int fd = open(str, O_RDWR | O_NOCTTY | O_NONBLOCK); // ?? NDELAY or NONBLOCK?

      if (fd == -1)
      {
                        perror("open_port: Unable to open /dev/ttyS0 - ");
      }
      else
                        fcntl(fd, F_SETFL, 0);

          struct termios options;
          tcgetattr(fd, &options); //this gets the current options set for the port

          // setting the options

          cfsetispeed(&options, B9600); //input baudrate
          cfsetospeed(&options, B9600); // output baudrate
          options.c_cflag |= (CLOCAL | CREAD); // ?? enable receicer and set local mode
          //options.c_cflag &= ~CSIZE; /* mask the character size bits */
          options.c_cflag |= CS8;    /* select 8 data bits */
          options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // choosing raw input
          options.c_iflag &= ~INPCK; // disable parity check
          options.c_iflag &= ~(IXON | IXOFF | IXANY); // disable software flow control
          options.c_oflag |= OPOST; // ?? choosing processed output
          options.c_cc[VMIN] = 0; // Wait until x bytes read (blocks!)
          options.c_cc[VTIME] = 0; // Wait x * 0.1s for input (unblocks!)

          // settings for no parity bit
          options.c_cflag &= ~PARENB;
          options.c_cflag &= ~CSTOPB;
          options.c_cflag &= ~CSIZE;
          options.c_cflag |= CS8;

          tcsetattr(fd, TCSANOW, &options); //set the new options ... TCSANOW specifies all option changes to occur immediately

      return (fd);
    }

推荐答案

file = fopen( "zname.jpg", "wb" );
while (1) { 
  n = read(readport, &buff, 1);
  if (n == -1) switch(errno) {
         case EAGAIN: /* sleep() */ 
            continue;
          ...
         default: goto quit;
         }
  if (n ==0) break;
  fputc(buff, file);
  }
quit:
   fclose (file);
...

使用select/poll甚至比sleep()和loop更好. (您仍然需要检查EAGAIN)

Even better than sleep() and loop, would be to use select/poll. (You'd still have to check for EAGAIN)

这篇关于通过串口读写二进制数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆