c - C 中串行输出错误

标签 c serial-port posix

我正在尝试通过 C 语言的串行线路发送数据。我怀疑我的问题出在我设置的选项上,但我无法弄清楚。

在下面的程序中,我发送字节 0x79、0x80、0x81,但在另一端,我接收 0x86、0x06、0x00

#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 */

/*
 * 'open_port()' - Open serial port 1.
 *
 * Returns the file descriptor on success or -1 on error.
 */
char SERIAL_DEVICE[] = {"/dev/ttyUSB0"};
struct termios options;

void open_port(int* fd)
{
    *fd = open(SERIAL_DEVICE, O_RDWR | O_NOCTTY | O_NDELAY);

    if (*fd == -1){
        /* Could not open the port. */
        perror("open_port: Unable to open serial port - ");

    } else 
        fcntl(*fd, F_SETFL, 0);

}

void send(int message[], size_t bytes_to_send, int* fd){
    int n,i;

    for(i=0;i<bytes_to_send;i++){
        printf("%x", message[i]);
    }
    n = write(*fd, message, bytes_to_send);
    if (n < 0)
      fputs("write() failed!\n", stderr);
}

int main(){

    int fd; /* File descriptor for the port */

    int message[] = {0x79, 0x80, 0x81};

    // load the options structure with the cuurent port options
    tcgetattr(fd, &options);        
    cfsetispeed(&options, B19200); // set in baudrate
    cfsetospeed(&options, B19200); // set out baudrate
    options.c_cflag |= (CLOCAL | CREAD);

    // No Parity 8N1
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    options.c_iflag &= ~(IXON | IXOFF | IXANY);
    options.c_iflag |= (IGNPAR | ISTRIP);

    //raw input and output
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_oflag &= ~OPOST;

    // Flush buffers and set new options
    tcsetattr(fd, TCSAFLUSH, &options);

    open_port(&fd);

    int array_length = sizeof(message) / sizeof(message[0]);    
    int i;
    for(i=0;i<array_length;i++){
        printf("%x", message[i]);
    }

    send(message, array_length, &fd);

    close(fd);
    return 0;
}

最佳答案

你所有的 termios 东西都无效。您正在更改随机文件描述符的终端特征(fd 未初始化),因为您在执行 tcsetattr 之后打开串行端口。如果您检查 tcgetattrtcsetattr 调用上的错误,您就会发现这一点。另外,如果您注意编译器发出的警告,您就会发现它。

然后,您的 send 函数存在两个问题:

  • 它与send系统调用同名。这在技术上是可以的,因为您的 send 覆盖了 libc 中的 send 并且一切正常,但它很令人困惑(当我第一次阅读代码时,我以为您正在使用 send 系统调用)并且危险(如果您在程序的其他地方使用 send 系统调用)。
  • 它将一个 int 数组传递给 write,但 write 需要一个字节数组。因此,当您尝试写入 0x79 时,最终会写入 4 个字节 0x00 0x00 0x00 0x79(对于大端 32 位平台)或 0x79 0x00 0x00 0x00(对于小端 32 位平台)。

关于c - C 中串行输出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13939544/

相关文章:

html - 使用 Apache 上传文件

c - 从 C api 附加一个命名的内存数据库

c - c中的read()是否读取空字符

c - 上下文切换场景下clock_gettime()的准确性

c++ - 将 POSIX::open 函数关联到命名空间

c - 文件路径数组中只有一个元素有效 - C

混淆使用strtok

android - 如何访问Android开发包中的串口?

c++ - 通过以太网电缆 (tcp) 的 rs-232 串行连接

c++ - 两个进程之间的 Ubuntu 共享内存,代码不工作