2017-11-29 17 views
1

usartに9bitメッセージを出力するコードを書きました。次のようにAtmega 9Bit UARTの変数が遅すぎる

コードは次のとおりです。

bool_t SERIAL__TX_SEND_NINE(U8_t ch, bool_t nine)   // send a character 
{ 

    bool_t result = SE_TRUE;    // assume OK 

    // transceiver is on so send as soon as the buffer is ready 
    while(SERIAL__TX_READY() == SE_FALSE) 
    {          // make sure the Tx buffer is ready for another character 
    } 
    if (nine == TRUE) 
    { 
    //SERIAL_USART_B |= 0x01; 
    UCSR0B &= ~(1<<TXB80); 
    UCSR0B |= (1<<TXB80); 
    } 
    else 
    {  
    //SERIAL_USART_B &= 0xFE; 
    UCSR0B &= ~(1<<TXB80); 
    } 

    SERIAL_UDR = ch;      // then send the next character 
    SERIAL_USART_A |= SERIAL_TX_DONE;  // clear the done flag 
    return result;      // OK 
} 

//! \brief send a byte on the serial communications bus if ready - return TRUE if successful 
//! 
//! \param ch the byte to transmit 
//! \return SE_TRUE if the byte was sent, SE_FALSE can't happen for this device 
bool_t serial_0_tx_send_if_ready_nine(U8_t ch, bool_t nine)   // send a character if able to 
{ 
    // if buffer ready? 
    if(SERIAL__TX_READY() == FALSE) 
    { 
     return FALSE; 
    } 

return SERIAL__TX_SEND_NINE(ch, nine);   // send the next character 
} 

SERIAL_UDR = UDR0

SERIAL_USART_A私はそれが開始であるかどうか、コードが実行されるたびのためのブレークポイントに入れ= UCSR0A

関数または関数の終わりに、期待どおりに動作します。 9番目のビットは、各データパケットのオンとオフを切り替えます。 (合計5データパケット)

ブレークポイントがない場合、9番目のビットが完全にランダムに表示されます。 ifステートメント内に1つのブレークポイントしかない場合は、1回だけヒットします。 私は 'nine'の値がフルスピードでトグルを実行するのに十分速く設定していないと推測しています。

トグルビットが手前の機能に設定されています。

// outgoing state machine 
// only process it if the function pointer isn't NULL 
if(handle->send != NULL) 
{ 
    // try and get a byte to send 
    if(RingBuffer_GetByte(&handle->out_rb, &data) == RINGBUFFER_OK) 
    { 
    // we got something to send 
     if (nine_toggle == TRUE) 
     { 
      nine_toggle = FALSE; 
     } 
     else 
     { 
      nine_toggle = TRUE; 
     } 

    if(serial_0_tx_send_if_ready_nine(data, nine_toggle) == SE_FALSE) 
    { 
    // but couldn't send it so put it back 
    RingBuffer_PutBackByte(&handle->out_rb, data); 
    } 
    // otherwise we sent another one. ringbuffer does all the data handling so nothing else to do 
} 
} 

しかし、なぜそれが起こるのかわかりません。

は、任意のアイデアが高く評価されるだろう、符号なし文字(のbool_t)

を格納する際atemga324pは、タイミングの遅れを持っています。

追加詳細。 MCU:Atmega324p。 OS:Windows 10.コンパイラ:Atmel Studio 7.0。最適化:なし。

+1

あなたは、あなたのコードの一部を掲載し、それが何が起こっているかを知るのは難しいので、間接の多くがあります。私は可能な限り単純化し、[mcve]を投稿することをお勧めします。 –

+0

コメントありがとうございます。私は次の投稿であなたのアドバイスを心に留めておきます。私は問題を理解した。コミュニケーションは準備ができていなかったので、serial_0_tx_send_if_ready_nine()はfalseを返していました。しかし、ループが同じバイトで再び実行されたとき、私はトグルを逆にしませんでした。 – Daniel

答えて

1

それを実演しました。

通信ポートがデータを送信する準備ができていないため、serial_0_tx_send_if_ready_nine(...)はフルスピードで実行しているときにfalseを返していました。

したがって、それはそのバイトを保持していましたが、send関数を再実行しましたが、トグルはすでに変更されていました。トグルを逆転しませんでした。

私は、次のようにコードの一部を変更:

if(serial_0_tx_send_if_ready_nine(data, nine_toggle) == SE_FALSE) 
    { 
    // but couldn't send it so put it back 
    RingBuffer8_PutBackByte(&handle->out_rb, data); 
    nine_toggle ^= 1; //<== Added this line 
    }