【问题标题】:Looking for test program for linux serial port寻找linux串口的测试程序
【发布时间】:2011-10-17 09:13:03
【问题描述】:

我正在尝试将程序从 Windows 移植到 linux。

问题是我无法成功设置波特率(代码如下)

我已经在连接到串行端口的电缆上设置了一个示波器。在 windows 版本中,我可以在 25 微秒时看到一个模式,但在 linux 版本中,我可以在 250 微秒时看到相同的模式,告诉我信息是正确的,但它发送的速度很慢。

我尝试将波特率设置为几个不同的值,但在示波器上仍然得到相同的结果。

我正在寻找的是一个程序,它将串行端口设置为 115200 波特、标记奇偶校验、1 个停止位和 8 个数据位并通过线路发送一些东西,以便我可以在超级终端上看到它。 c++ 中的程序会很棒,因为如果它有效,我可以将它与我的程序进行比较。

我认为有些东西以某种方式将波特率设置在某个值,如果我从其他人那里得到一个确认可以工作的程序,我可以说它是 linux 的设置。我在不同的计算机上尝试过,但它们都是由我们的系统管理员以相同的方式配置的

我已经尝试了 3 周,并且已经完成了数百个串口教程,作为一个 linux 菜鸟,我现在不知道该怎么做。

    idComDev[i] = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
    if (idComDev[i] == -1)
    {
    perror("open_port: Unable to open /dev/ttyS0 - ");
    ret = false;
    }
    else
    {
    fcntl(idComDev[i], F_SETFL, 0);

    struct termios options;

    tcgetattr(idComDev[i], &options); // get current settings

    cfsetspeed(&options, B9600); // set baud rate

    test = tcsetattr(idComDev[i], TCSANOW, &options);// save the settings

    options.c_cflag &= ~CSIZE; // Mask the character size bits 
    options.c_cflag |= CS8; // 8 bit data           
    options.c_cflag &= ~PARENB; // set parity to no 
    options.c_cflag &= ~PARODD; // set parity to no 
    options.c_cflag |= CSTOPB; //set one stop bit

    options.c_cflag |= (CLOCAL | CREAD);

    options.c_oflag &= ~OPOST;

    options.c_lflag &= 0;
    options.c_iflag &= 0; //disable software flow controll
    options.c_oflag &= 0;

    tcsetattr(idComDev[i], TCSANOW, &options);// save the settings

    printw("Seg %d = COM%hd",i,CommNo[i]);
    if(test!= -1)
    printw("test success");

【问题讨论】:

  • 运行程序后,您可以运行stty -F /dev/ttyS0 -a 并检查设置吗?这应该会告诉您哪些设置没有被采用。
  • @Adrian Cox 该命令获得“没有这样的文件或目录”可能是因为我在根目录中并且似乎无法向上移动一个:(
  • 我不确定根目录中的存在与它有什么关系。你的代码引用了/dev/ttyS0,所以我很困惑为什么你不能从命令行访问/dev/ttyS0。您使用的是什么 Linux 发行版?
  • @Adrian Cox centos,并且因为 linux 是区分大小写的,这仍然让我在这里和那里感到抱歉。它说波特设置为 115200,这是我想要的,但我将其设置为 9600 atm 以进行测试,或者尽管 termios 声称成功,但没有发生任何事情
  • 我的想法已经不多了。最后要尝试的事情:在您的最终 tcsetattr 之后调用 tcgetattr 并与预期值进行比较。尝试使用stty 更改波特率。查看stty 源(在 coreutils 中)进行比较。

标签: c++ linux serial-port


【解决方案1】:

如果你想将windows串口程序移植到linux,我建议你先移植到Boost.Asio库——这包括一个跨平台的串口到你的串口。你可以让它在 Windows 下运行,然后知道代码可以在 Linux 上运行。

原因是当从 windows 移动到 linux 串口时,除了软件问题之外,还可能存在其他问题。例如,握手协议(RTS/CTS、DTE/DSE)可以在两者之间有所不同。

首先,看看我的回答here。如果您想要完整的源代码,请查看github

此外,这个question 目录包含各种串行嗅探器,可以帮助确定到底发生了什么。

【讨论】:

    【解决方案2】:

    所以,我知道这个问题是很久以前发布的,但我认为你的停止位倒退了。如果你想设置一个停止位,你必须这样做:

    options.c_cflag &= ~CSTOPB; //set one stop bit

    不是这个(你拥有的):

    options.c_cflag |= CSTOPB; //This sets stop bits to 2, since 1 is the default.

    我的来源: http://www.easysw.com/~mike/serial/serial.html

    【讨论】:

    • 项目被废弃,找到了另一种方法,但很感谢答案。
    • gitarooLegend:您的链接现在指向电子烟经销商。 @Skeith:将答案标记为“已接受”可能仍然值得。
    【解决方案3】:

    标准工具setserial怎么样。您可以使用它设置设备参数(然后可以通过设备文件完成输入/输出)。源代码是可用的,所以你可以看看它是如何实现的。

    【讨论】:

    • 我尝试了这个并在我的程序中注释掉了波特率代码,这样它就不会干扰并得到同样的东西:(
    • @Skeith:我看到的一件事是,您没有检查 tcsetattr 的返回码。也许您应该检查一下,看看是否/出了什么问题(注意:(我引用了 tcsetattr 的手册页):` 请注意,如果可以成功执行任何请求的更改,则 tcsetattr() 将返回成功。因此,在进行多次更改可能需要在此调用之后进一步调用 tcgetattr() 以检查所有更改是否已成功执行`)。
    • 将代码修改为我的帖子中显示的内容,如您所说,它声称成功但仍然无法正常工作?
    【解决方案4】:

    你可以试试:

    getty ttyS0 115200 vt100
    

    并查看您的 Windows 上是否出现登录提示。 一旦你为默认波特率工作,请尝试更改波特率。

    getty ttyS0 9600 vt100
    

    然后看看它是否仍然有效。 但是,您可能需要成为 root 才能执行此操作。 你也可以删除 fcntl 调用吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-16
      • 2015-07-28
      • 1970-01-01
      相关资源
      最近更新 更多