通过串口读写二进制数据 [英] Reading and writing binary data over serial port
问题描述
所以我四处搜寻,却找不到我需要的东西.我需要通过串行端口读写二进制数据的帮助,希望您能提供任何建议.请注意,当我处于该项目的不同阶段时,我曾问过类似的问题.
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屋!