2017-05-05 2 views
0

아래 코드는 ATmega328P에서 실행되는 코드입니다. 매초마다 내 컴퓨터에 "abcdef"를 보내야합니다. 그러나, 그것은 매초 "ab"만 보냈습니다. 여기서 뭐가 잘못 됐니? AVR USART는 2 문자 만 전송합니다

가 (CHAR로 변환 할 +48) USART_transmit(n + 48);- USART_transmit(*buffer++);에서 변경 ...

ababababababababababab 결과 :

#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)); 
} 

코드는 결과

5454545454545454545454545454 ...

그래서 루프가 멈추지 않아야한다고 생각하십니까?

답변

2

"데이터 레지스터 비어 있음"검사가 잘못되었습니다. 버퍼가 비워 질 때까지

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

는 경우

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

해야한다, 검사가 차단되지 않습니다. 1 바이트는 USART 출력 버퍼에 버퍼링되고 1 바이트는 UDR에 보류 중이라고 생각합니다. 추가 바이트가 모두 버려 지므로 "ab"만 표시됩니다.

관련 문제