附录

附录

我有一个 USB 转串行适配器,基于CH340Gstty芯片。它连接到一个定期以 9600 波特率发送字符串的设备。但是,无论我如何配置 UART (版本 8.13),我似乎都能接收数据:

# stty -F /dev/ttyUSB0 9600  
# stty -F /dev/ttyUSB0     
speed 9600 baud; line = 0;
kill = ^H; min = 100; time = 2;
-icrnl -imaxbel
-opost -onlcr
-isig -icanon -echo
# stdbuf -i0 -o0 cat /dev/ttyUSB0
data data data
^C
# stty -F /dev/ttyUSB0 115200
# stty -F /dev/ttyUSB0       
speed 115200 baud; line = 0;
kill = ^H; min = 100; time = 2;
-icrnl -imaxbel
-opost -onlcr
-isig -icanon -echo
# stdbuf -i0 -o0 cat /dev/ttyUSB0         
data data data
^C

我认为这里有问题stty,因为screen它按预期工作。screen /dev/ttyUSB0 9600显示数据,但screen /dev/ttyUSB0 115200不产生任何输出。

我在尝试配置 U​​ART 波特率时遗漏了什么吗stty

答案1

stty我认为......有些地方出错了
......
我在尝试使用 stty 配置 UART 波特率时是否遗漏了什么?

是的,您的测试有缺陷,所以您没有检测到波特率已经改变。

一些(可能不太明显的)事实:

  • 当数据以相对于其配置来说非常慢的波特率发送时(例如,以 9600 波特发送并以 115200 波特接收),串行端口根本无法接收任何数据。
  • 命令有一个怪癖,它会导致它不刷新 stdio 缓冲区,除非它遇到行终止符。换句话说,连续命令可以在没有行终止的情况下显示相同的数据。这个问题暗指这个问题。

您的特定选择和 shell 命令序列共同导致您得出错误的结论。

# stty -F /dev/ttyUSB0 9600
# stty -F /dev/ttyUSB0
# cat /dev/ttyUSB0
数据 数据 数据
^C

因此,您可以使用适当的波特率配置串行终端,并接收一些数据。

# stty -F /dev/ttyUSB0 115200
# stty -F /dev/ttyUSB0
# cat /dev/ttyUSB0
数据 数据 数据
^C

重新配置波特率后,串口可能停止检测有效帧,并且不会收到任何新数据。
当您再次发出命令,您将看到显示之前收到的相同数据(即波特率改变之前)。


附录

你至少应该能够说服自己斯特蒂命令没有损坏,并且确实按预期更改了波特率。
要么:

A. 不要更改为非常快的波特率(无法检测到任何帧),而要更改为中等的 38400 波特率或较慢的 4800 波特率,这两种情况都会导致接收/显示垃圾字符(而不是有效数据或什么都没有)。

或者

B. 交换波特率的顺序。重置系统,然后使用斯特蒂最初配置快速、无效的波特率,导致接收/显示垃圾字符或不显示任何内容。
然后使用斯特蒂配置适当的波特率,并开始按预期接收数据。

答案2

是的,你说得对。我strace在屏幕上运行,并得出了以下结论:

#include <stdint.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <asm/termbits.h>

int main(int argc, char* argv[]) {

    if (argc != 3) {
        printf("%s device speed\n\nSet speed for a serial device.\nFor instance:\n    %s /dev/ttyUSB0 75000\n", argv[0], argv[0]);                   
        return -1;
    }

    int fd = open(argv[1], O_RDWR|O_NOCTTY|O_NONBLOCK);

    int speed = atoi(argv[2]);

    int tiocm; 
    struct termios2 tio;
    ioctl(fd, TCGETS2, &tio);
//    tio.c_cflag = CS8 | CREAD | CLOCAL | B2000000;
    tio.c_cflag &= ~CBAUD | CS8 | CREAD | CLOCAL | BOTHER;
    tio.c_ispeed = speed;
    tio.c_ospeed = speed;
    tio.c_cc[VMIN]=1;
    tio.c_cc[VTIME]=-1;
    int r = ioctl(fd, TCSETS2, &tio);

     printf("Set %s Baudrate to %s.\n",argv[1],argv[2]);
}
        
 

相关内容