2015-06-27 88 views
1

我開始再次編程AVR。我能夠在我的Linux計算機和Atmega8之間建立UART通信。不幸的是,當我發送大於0x1f的字節時,Atmega8似乎收到錯誤的字節。 UART使用9600 BAUD和數據格式8N1運行。AVR UART在長時間暫停後收到錯誤的字節

// clock frequency 1Mhz 
#define F_CPU 1000000UL 

// baud rate 
#define BAUD 9600 
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1) 

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


void uart_init (void); 
void uart_putc (unsigned char data); 
void uart_puts (unsigned char * str, uint8_t size); 

// interrupt service routine for UART receiver interupt 
ISR(USART_RXC_vect) { 

    // get received char 
    unsigned char received_char = UDR; 

    uart_puts("received=", 9); 

    if((received_char & (1<<7)) == (1<<7)) { 
     uart_putc('1'); 
    } else { 
     uart_putc('0'); 
    } 

    if((received_char & (1<<6)) == (1<<6)) { 
     uart_putc('1'); 
    } else { 
     uart_putc('0'); 
    } 

    if((received_char & (1<<5)) == (1<<5)) { 
     uart_putc('1'); 
    } else { 
     uart_putc('0'); 
    } 

    if((received_char & (1<<4)) == (1<<4)) { 
     uart_putc('1'); 
    } else { 
     uart_putc('0'); 
    } 

    if((received_char & (1<<3)) == (1<<3)) { 
     uart_putc('1'); 
    } else { 
     uart_putc('0'); 
    } 

    if((received_char & (1<<2)) == (1<<2)) { 
     uart_putc('1'); 
    } else { 
     uart_putc('0'); 
    } 

    if((received_char & (1<<1)) == (1<<1)) { 
     uart_putc('1'); 
    } else { 
     uart_putc('0'); 
    } 

    if((received_char & (1<<0)) == (1<<0)) { 
     uart_putc('1'); 
    } else { 
     uart_putc('0'); 
    } 

    uart_puts("\n\r",2); 
} 


// function to initialize UART 
// dataformat 8N1 
void uart_init (void) { 

    // shift the register right by 8 bits 
    UBRRH = (BAUDRATE>>8); 

    // set baud rate 
    UBRRL = BAUDRATE;    

    // enable receiver, transmitter and receiver interrupt 
    UCSRB|= (1<<TXEN)|(1<<RXEN)|(1<<RXCIE); 

    // 8bit data format 
    UCSRC|= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); 

} 

// sends a single char over the UART 
void uart_putc (unsigned char data) { 

    // wait while register is free 
    while (!(UCSRA & (1<<UDRE))); 
    // load data in the register 
    UDR = data; 
} 

// sends a string over the UART 
void uart_puts (unsigned char * str, uint8_t size) { 

    uint8_t i; 

    for(i = 0; i < size; i++) { 
     uart_putc(str[i]); 
    } 
} 

// receives a single char over the UART 
unsigned char uart_getc (void) { 

    // wait while data is being received 
    while(!(UCSRA) & (1<<RXC)); 
    // return 8-bit data 
    return UDR; 
} 


uint8_t main (void) { 

    // enable interrupts 
    sei(); 

    // enable uart 
    uart_init(); 

    uart_puts("ready\n\r", 7); 

    while(1) { 
    } 

    return 0; 
} 

在GtkTerm我發送以下字節序列:0x010x020x030x1d0x1e0x1f0x20和中斷服務程序ISR具有下列順序進行響應。

enter image description here

不過,我應該得到received=00100000爲0x20的
哪些錯誤?

+1

由於使用慢速時鐘/內部RC振盪器,波特率可能會關閉?你應該「測試」一些更多的值,看看是否有一個模式。根據您提供的信息很難將其縮小。 –

+0

謝謝。實際上,這是導致數據損壞的頻率較低(1MHz)。我切換到8MHz和19200的波特率。 – konze

+0

好啊,我碰到了那裏的頭部:)你應該標記這個問題然後。然後關閉開放式問題列表。 –

回答

1

從我的評論:

也許波特率爲關閉,由於使用較慢的時鐘速率/內部RC oszillator?波特率越慢,每個位的「中間」偏移越大。這會導致跳過位或控制器看到兩次。