【问题标题】:C program setting port parameters before opening port failsC程序在打开端口前设置端口参数失败
【发布时间】:2014-08-11 00:55:32
【问题描述】:

我正在尝试在Linux系统上编写c代码,在那里我设置了串口参数然后打开串口,然后我发现即使代码编译并运行,我也无法从该串口读取和写入端口(所以串口没有打开成功)!

有效的代码(不需要):

int fd;
char *portname;
portname = "/dev/ttyUSB0";
struct termios tty;

fd = open(portname, O_RDWR | O_NOCTYY | O_SYNC );

memset(&tty,0,sizeof tty);
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOP;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS;
tcsetattr(fd,TCSANOW,&tty);

不起作用的代码(需要)

int fd;
char *portname;
portname = "/dev/ttyUSB0";
struct termios tty;

memset(&tty,0,sizeof tty);
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOP;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS;
tcsetattr(fd,TCSANOW,&tty);

fd = open(portname, O_RDWR | O_NOCTYY | O_SYNC );

固体问题:我的应用程序序列要求我设置串口参数然后打开串口。有没有办法做到这一点?如果是,怎么做?

感谢您的帮助。

【问题讨论】:

  • 你的程序是否允许打开串口?
  • 由于您还没有文件描述符,因此您无法为连接设置任何选项。 为什么您的应用需要这样的设计?
  • -alk:是的,我只是把我的代码的sn-ps。 -meaning-matters:是的,我将自己加入了拨出组。 -Lukasz:我的应用程序需要这种设计,因为该程序是从 Windows 移植的,并且必须保持相同的结构。谢谢大家的cmets。我现在明白了这个问题。

标签: c linux serial-port


【解决方案1】:

更新:删除了 @Alter Mann 注意到的 C++ 代码。
更新:删除了 @sawdust 注意到的 termios 结构的归零。

在第一种情况下,您会得到实际的文件描述符fd 并在使用它之后。在第二种情况下,您尝试设置 未初始化的文件描述符 fd(如果在全局范围内声明,则可能是 0)并在获得它的实际值之后。

以下是适合我的解决方法:

#include <fcntl.h>
#include <termios.h>
#include <strings.h>
#include <stdlib.h>

int main (int argc, char * argv [])
{
    struct termios tty;
    const char * portname = "/dev/ttyUSB0";
    const int fd = open (portname, O_RDONLY);
    if (-1 == fd) {
        // Problem...
        return EXIT_FAILURE;
    }

    if (tcgetattr (fd, &tty) < 0) {
        // Problem...
        return EXIT_FAILURE;
    }

    cfsetospeed (&tty, (speed_t) B9600);
    cfsetispeed (&tty, (speed_t) B9600);

    tty.c_cflag |= B9600;
    tty.c_cflag |= (tty.c_cflag & ~CSIZE) | CS8;
    tty.c_cflag |= (CLOCAL | CREAD);
    tty.c_cflag &= ~(PARENB | PARODD);
    tty.c_cflag |= IGNPAR;
    tty.c_cflag &= ~(CRTSCTS);
    tty.c_cflag &= ~(CSTOPB);
    tty.c_iflag |= IGNBRK;
    tty.c_iflag &= ~(IXON | IXOFF | IXANY);
    tty.c_lflag  = 0;
    tty.c_oflag  = 0;

    tcflush (fd, TCIFLUSH);
    if (tcsetattr (fd, TCSANOW, &tty) ) {
        // Problem...
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

【讨论】:

  • 将 termios 结构归零是不好的编码习惯。首选/正确的方法是使用 tcgetattr() 系统调用。见Setting Terminal Modes Properly
  • @sawdust,感谢您提供有用的建议!我已经确定了答案。
猜你喜欢
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
  • 2016-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-30
  • 2021-12-19
相关资源
最近更新 更多