Arduino 可以用来“监视”两个设备之间的 UART 连接吗?

电器工程 Arduino UART 串行 数据
2022-01-10 21:15:39

我需要在现有硬件中安装 Arduino(实际上只是 IC)以增强功能。

我想做的是连接Arduino,以便它“监视”板上两个芯片之间的I/O线。如果 Arduino 在该 UART 连接上选择特定关键字,它将在一组单独的输出引脚上执行特定操作。

我不确定的是如何连接 Arduino,使其无需参与即可解码现有的 UART 连接?如果不可能,我对理论、想法等感兴趣。

3个回答

如果我理解正确,您有 2 个通过 UART 连接的设备。我假设设备之间只连接了 TX、RX 和 GND 线?(即,没有使用 DTS/CTS/DTR/RTS 控制线 - 这是典型的)。

在这种情况下,设备 1 的 TX(发送)连接到设备 2 的 RX(接收),反之亦然。它们的接地是相互连接的。因此,每个设备可以同时发送和接收(每个设备在单独的线路上发送,通信是全双工的)。

我之所以提到这一切,是因为很明显,要“嗅”或“听”,您实际上需要 2 个 UART 来监听对话的双方。

基本上,您要做的就是确保所有 3 个设备的 UART GND 都短路,并将设备 1 和设备 2 的 TX 线连接(实际上是“三通”,如 T 型接头,如管道)和 2 条 RX 线在 2 个 UART 上。确保所有波特率配置相同。

有很多 Arduino 板/设计。现在最常见的 Duemilanove 使用 ATMega328P,我认为它只有 1 个 UART(嗯,USART)。因此,您要么必须连接第二个 UART IC,要么在第二个接收器上使用“bit banging”。

异步 UART 通信定义明确,带有开始和停止位(有时还有奇偶校验位),因此如果您的处理器足够快,您可以简单地将设备的 UART TX 线之一连接到配置为输入的 GPIO,然后轮询该线足够快的过采样来检测 START & STOP 和采样位。Jack Ganssle的文章“Bit Banging”会给你很多东西。

关于 RS232 波形的详细描述可以在BeyondLogic中找到。

请注意,您还必须考虑其他问题,例如电压电平(0/+5、-10V/+10V 等)(请参阅“RS232 电平转换器”的超越逻辑部分)。除了上面讨论的“连接线路”方法之外,我没有关于您的系统的足够信息来讨论硬件接口。假设电压电平匹配,通常将 TX 线“三通”连接到第二个接收器(嗅探器)不是问题,但如果 TX 没有足够的驱动器,您可能需要插入一个缓冲器/驱动器以防止退化的信号。

如果一次只在一个方向进行通信(即半双工通信),您可以做一个巧妙的技巧。如果双方同时互相交谈(全双工),这将不起作用,但如果这是典型的“做这个”“好的,这是响应”“现在做这个”“好的,这是新的响应”类型的通信它工作得很好。

由于 UART 链路使用逻辑高 (1) 电平的发送器空闲条件,您将使用 2 输入与门并将 TX 从每一侧连接到与输入。与门的输出是嗅探器 UART(它是 RX 引脚)的输入。现在将设备 B 的 TX 线连接到嗅探器上的 I/O 端口。您将配置嗅探器以在该引脚从高电平变为低电平时产生中断。

回顾一下:设备 A UART TX -> AND 门输入。设备 B UART TX -> 其他与门输入和嗅探器 GPIO 引脚。与门的输出 -> 嗅探器 UART RX 线。

UART 通信由一个起始位、一些数据位、一个可选的奇偶校验位和一个或多个停止位组成。由于空闲状态是逻辑高 (1),每个字节的开始都是逻辑低 (0),嗅探器上的中断将触发。当您的嗅探器执行 I/O 中断时,UART 硬件将从与门收集位。当 UART 接收到停止位时,I/O 中断将长时间完成,并且 UART RX 中断将触发。

IO 更改中断例程将设置一个“方向”变量以指示通信处于“B->A”方向。嗅探器的 UART 接收中断会查看这个“方向”变量并将刚刚接收到的字节写入适当的缓冲区。然后,UART RX 中断会将“direction”变量设置回默认的“A->B”状态:

volatile int direction = 0;           /* 0 = A -> B */

void io_interrupt(void)
{
    direction = 1;                    /* switch direction, now B -> A */
}

void uart_interrupt(void)
{
    unsigned char b;

    b = UART_RX_REG;
    if(direction) {
        store_byte_to_device_b_sniff_buffer(b);
    } else {
        store_byte_to_device_a_sniff_buffer(b);
    }

    direction = 0;                   /* reset direction to default A -> B */
}

这段代码是为了清楚起见而编写的,不一定是您在现实世界中编写的代码。就我个人而言,我会将“方向”作为指向适当 FIFO 结构的指针,但这完全是另一个练习。:-)

当设备 A 正在通话时,I/O 线不移动(它保持逻辑“1”,因为设备 B 的 UART 发送器空闲),并且 UART RX 中断将接收一个字节,看到方向是 A->B ,并将数据存储到该缓冲区。当设备 B 正在讲话时,只要设备 B 开始将数据移出,I/O 线就会变为低电平,并且 I/O 中断例程将设置方向以指示设备 B 正在讲话。UART RX 中断最终将在所有位被收集后触发,并且由于 I/O 中断已经负责正确设置方向寄存器,接收到的字节将存储在正确的缓冲区中。

Presto:使用嗅探器上的单个 UART 和 I/O 线捕获的两个设备之间的半双工通信,没有 bit-banged UART 通信。

您不必将 AVR 的传输数据引脚连接到您的电路中。只需将接收线连接到您要窃听的现有链接的一半。如果您的特定 AVR 有两个串行端口,您应该能够同时监视现有链路的两半。您只需使端口设置与现有的波特率、停止位等相匹配。