2015-03-02 28 views
1

我想使用Atxmega-μC的USART功能。因此,我首先考察了美國的例子。它旨在獲得一個字符,然後將其發回。在全雙工功能中使用usart

while (true) { 
     received_byte = usart_getchar(USART_SERIAL_EXAMPLE); 
     if (received_byte == '\r') { 
      for (i = 0; i < tx_length; i++) { 
       usart_putchar(USART_SERIAL_EXAMPLE, tx_buf[i]); 
      } 
     } else 
      usart_putchar(USART_SERIAL_EXAMPLE, received_byte); 
    } 

我想知道如果這是一個平行處理(appearently沒有),並且如果我想發送和並聯真正接收數據,而不是如圖中序列上面的例子代碼我應該如何重構這個代碼。理論上(直到現在還沒有測試過),在μC僅僅是「單核」之後,將它分成幾個線程並不能改善這種情況。有另一種通過USART並行發送和接收數據的方式嗎?

回答

1

你不能達到真正的平行度。我使用Atmel UC3做了類似的設計,但是我從隨機的XMega數據表中取出來確認它們至少看起來很相似,但沒有詳細說明。沒有單獨的緩衝區用於讀取和寫入。看寄存器說明:

USART Register Description

數據寄存器用於發射共享和接收。話雖如此,仍然有可能設計爲使用中斷和FIFO來進行「接近」並行的全雙工。請參閱下面的代碼:

static void usart_int_handler(void) 
{ 
    int result; 
    while (PS_USART->csr & RX_READY) 
    { 
     result = fifo_push_byte(&PS_FIFO, PS_USART->rhr); 
     if (result == FIFO_ERROR_OVERFLOW) 
     { 
      fifo_flush(&PS_FIFO); 
      break; 
     } 
    } 
    int parity_error = usart_parity_error(PS_USART); 
    int framing_error = usart_framing_error(PS_USART); 
    int overrun_error = usart_overrun_error(PS_USART); 
    if (parity_error || framing_error || overrun_error) 
    { 
     // Clear out FIFO and reset errors. 
     // Then exit out and let calling object 
     // timeout. 
     while (PS_USART->csr & RX_READY) 
     { 
      result = PS_USART->rhr; 
     } 
     fifo_flush(&PS_FIFO); 
     usart_reset_status(PS_USART); 
     return; 
    } 
} 

FIFO可以被輪詢,或者您可以設置一箇中斷,它已達到數據閾值。我以這種方式處理傳輸:

void write_ps_serial (volatile avr32_usart_t *usart, const unsigned char *string, int size) 
{ 
    // When using this - we needed a software workaround 
    // to set and reset RTS pin. Operation of RTS is not 
    // correct. 
    Disable_global_interrupt(); 
    gpio_set_pin_high(PS_RTS_PIN); 
    for (int index = 0 ; index < size ; index++) 
    { 
     usart_putchar(usart, string[index]); 
    } 
    while ((PS_USART->csr & TX_EMPTY) == 0) 
    { 
     // Sit here waiting for the channel 
     // status register to indicate TX_EMPTY 
     // has gone high which means we can shut 
     // off RTS. 
    } 
    gpio_clr_gpio_pin(PS_RTS_PIN); 
    Enable_global_interrupt(); 
} 

我仍然認爲硬件中有防止碰撞的東西。儘管我檢查了錯誤,但我仍在使用模擬器連續3天,同時以不斷的通信衝擊總線,並且從未收到錯誤。但是你肯定需要編碼你自己的協議來處理丟包或使用更嚴格的RS232控制(這個代碼是全雙工485)。如果你願意,我有更多的代碼。我希望這有幫助。