2017-05-05 58 views
0

下面是一個代碼運行在一個ATMEGA328P。它應該每秒發送一次「abcdef」到我的電腦。但是,它每秒只給我發「ab」。這裏有什麼問題?AVR USART僅發送2字符

#include <avr/io.h> 
#include <util/delay.h> 

void USART_transmit(unsigned char data); 
void print(const unsigned char *buffer, size_t n); 
void print(const char* str); 

int main(void) { 
    // Serial.begin(115200) 
    UCSR0B |= (1<<TXEN0); 
    UBRR0L = 8; 

    while(1){ 
     // Serial.write(i) 
     print("abcdef"); 

     _delay_ms(1000); 
    } 
} 

void USART_transmit(const uint8_t data) { 
    /* wait for empty transmit buffer */ 
    while (!UCSR0A & (1<<UDRE0)); 
    UDR0 = data; 
} 

void print(const uint8_t *buffer, size_t n) { 
    while(n--){ 
     USART_transmit(*buffer++); //** 
    } 
} 

void print(const char *str) { 
    if(strlen(str) != 0) print((const uint8_t *) str, strlen(str)); 
} 

的代碼導致:

ababababababababababab ...

USART_transmit(*buffer++);USART_transmit(n + 48);更改(+48轉換爲字符)導致:

5454545454545454545454545454 ...

所以我猜這個循環不應該被阻止?

回答

2

「數據寄存器空」檢查是錯誤的。

while (!UCSR0A & (1<<UDRE0)); 

應該

while (!(UCSR0A & (1 << UDRE0))); 

在你的情況,檢查沒有阻止,直到緩衝區爲空。我認爲一個字節在USART輸出緩衝區中被緩衝,一個字節在UDR中處於待處理狀態。然後丟棄每個額外的字節,這就是爲什麼你只看到「ab」。