2

興味深いことに、私は完全には理解していません。UART は 9600 ボーで初期化されています。ロジック アナライザーを介して回線上の TX を確認しましたが、送信したバイトの遅延は最小限です。1 バイトあたり 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

チェックする3つのポイント:

  • 十分な速さでバッファを供給していますか? そうでない場合、ギャップの増加は、プロセッサの内部動作によるものではなく、データ提供コードによるものです。(トグルピンを使用して確認してください)

  • 速度が向上したため、コードがデータを送信するたびにデータレジスタの空の割り込みをオフにする可能性はありますか? put_char を使用してリングバッファを埋める代わりに、put_string(array, length) を使用して一度に複数の文字で埋めることができます (たとえば、memcopy を使用して、データをラップする必要がある場合に 2 つの mwmcopy 操作に分割することを考えてください)。バッファーの最後)。(再度、トグル ピンを使用して調べます)。

  • cli() と sei() にラップされるコードを最小限に減らします。フラグ チェックでバッファをいっぱいに切り替えて、この部分を cli-sei 部分から除外します

幸運を!

于 2013-09-11T12:36:42.253 に答える
2

uart2_putchar() を十分に頻繁に呼び出す限り、循環バッファーが空になることはなく、測定するギャップは割り込み応答時間によって決まります。

ただし、ボーレートを上げると、そのバッファがより速く空になります。割り込みハンドラーがバッファーが空であることを検出し、バイトを送信できない臨界点まで。測定するギャップは、uart2_putchar() を呼び出すレートによって決定されます。

于 2013-09-11T12:51:33.527 に答える