2015-06-27 1 views
1

после долгой паузы я снова начал программировать AVR. Мне удалось настроить связь UART между моим компьютером Linux и Atmega8. К сожалению, Atmega8, кажется, получает неправильные байты, когда я отправляю байты больше 0x1f. 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 Я посылаю следующую последовательность байт: 0x01, 0x02, 0x03, 0x1d, 0x1e, 0x1f, 0x20 и прерывания обслуживания процедура ISR отвечает следующей последовательности.

enter image description here

Однако, я должен получить received=00100000 для 0x20
Что не так?

+1

Возможно, скорость передачи отключена из-за использования медленной тактовой частоты/внутреннего RC-осциллятора? Вы должны «проверить» еще несколько значений и посмотреть, есть ли шаблон. Из информации, которую вы предоставили, трудно сузить ее. –

+0

Спасибо. На самом деле это была медленная частота (1 МГц), которая вызвала поврежденные данные. Я переключился на 8 МГц и скорость передачи в 19200 году. – konze

+0

А хорошо, я ударил ноготь по голове там :) Вы должны отметить этот вопрос. Затем его список открытых вопросов. –

ответ

1

Из моего комментария:

Может быть, скорость передачи данных отключен из-за использования медленной скорости часы/внутренний RC oszillator? Чем медленнее скорость передачи данных, тем больше смещение от «среднего» каждого бита. Это может привести к пропуску битов или контроллеру, которые видят бит в два раза.

 Смежные вопросы

  • Нет связанных вопросов^_^