有些值得注意的事情,我并不完全理解。我的UART初始化为9600波特。我通过逻辑分析仪查看了线路上的TX,我发送的字节延迟最小。它是每字节36μs,这是预期的。
现在,如果我使用不同的波特率(例如115,200)初始化该UART,则发送的每个字节之间的延迟会显着增加。它每字节跳到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波特率 -
答案 0 :(得分:5)
要检查三点:
您是否足够快地喂入缓冲区?如果不是,增加的差距是由于您的数据提供代码,而不是由于处理器的内部行为。 (使用切换针找出)
是否有可能因为速度提高,您的代码每次传输数据时都会关闭数据寄存器空中断? 您可以使用put_string(数组,长度)来一次填充多个字符(例如,使用memcopy,考虑将数据拆分为两个mwmcopy操作,而不是使用put_char来填充您的ringbuffer在缓冲区的末尾)。 (再次使用切换销找出)。
将包含在cli()和sei()中的代码减少到最少。用标志检查切换填充缓冲区,并从cli-sei部分中排除该部分
答案 1 :(得分:2)
只要你经常调用uart2_putchar(),你的循环缓冲区永远不会为空,你测量的间隙由中断响应时间决定。
但是,当你增加波特率时,你会更快地清空缓冲区。直到临界点,中断处理程序将找到缓冲区为空且无法传输字节。您测量的差距现在由您调用uart2_putchar()的速率决定。