2

一些有趣的事情要注意,我不完全理解。我的 UART 初始化为 9600 波特。我通过逻辑分析仪查看了线上的 TX,我发送的字节延迟最小。它是每字节 36µs,这是预期的。

现在,如果我用不同的波特率初始化 UART,比如 115,200,发送的每个字节之间的延迟会显着增加。它跳到每字节 125µs。

这导致了一个问题,因为我必须在某个时候提高我的波特率,但我的响应有时间限制。

字节之间的延迟不应该减少吗,因为它应该以相同的频率发送更多位?

此阻塞方法用于写入 UART。

static inline void uart2_putchar(uint8_t data)
{
    // Disable interrupts to get exclusive access to ring_buffer_out.
    cli();
    if (ring_buffer_is_empty(&ring_buffer_out2)) {
        // First data in buffer, enable data ready interrupt
        UCSR2B |=  (1 << UDRIE2);
    }
    // Put data in buffer
    ring_buffer_put(&ring_buffer_out2, data);

    // Re-enable interrupts
    sei();
}

这是基于中断触发的。

ISR(USART2_UDRE_vect)
{
    // if there is data in the ring buffer, fetch it and send it
    if (!ring_buffer_is_empty(&ring_buffer_out2)) {
        UDR2 = ring_buffer_get(&ring_buffer_out2);
    }
    else {
        // no more data to send, turn off data ready interrupt
        UCSR2B &= ~(1 << UDRIE2);
    }
}

时序图如下:

~9600 波特率 -- 在此处输入图像描述 在此处输入图像描述

~115,200 波特率 -- 在此处输入图像描述

4

2 回答 2

5

三点检查:

  • 您是否足够快地喂入缓冲区?如果不是,则增加的差距是由于您的数据提供了代码,而不是由于处理器的内部行为。(使用拨动销找出)

  • 是否有可能由于速度的提高,您的代码每次传输数据时都会关闭数据寄存器空中断?您可以使用 put_string(array, length) 一次填充多个字符,而不是使用 put_char 来填充环形缓冲区(例如,使用 memcopy,考虑在数据必须包装时将其拆分为两个 mwmcopy 操作在缓冲区的末尾)。(再次,使用拨动销找出)。

  • 将包装在 cli() 和 sei() 中的代码减少到最少。使用标志检查切换填充缓冲区,并将此部分从 cli-sei 部分中排除

祝你好运!

于 2013-09-11T12:36:42.253 回答
2

只要您经常调用 uart2_putchar() ,您的循环缓冲区就永远不会为空,并且您测量的间隙由中断响应时间决定。

但是,当您增加波特率时,您会更快地清空该缓冲区。直到中断处理程序发现缓冲区为空且无法传输字节的临界点。您测量的差距现在由您调用 uart2_putchar() 的速率决定。

于 2013-09-11T12:51:33.527 回答