2015-12-19 1 views
2

Я пытаюсь сделать очень простую программу USART, которая отправляет полученный символ обратно в передатчик и представляет эквивалентное двоичное число, сверкая 8 светодиодами на моем макете.USART с ATMEGA168A -

Вот код:

#define F_CPU 1000000UL     // set the CPU clock 
#define BAUD 9600       // define baud 
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1) // set baudrate value for UBRR 

#include <avr/io.h> 
#include <util/delay.h> 
#include <stdlib.h> 
#include <inttypes.h> 
#include "led.h" 

// function to initialize UART 
void uart_init (void) 
{ 
    UBRRH=(BAUDRATE>>8); 
    UBRRL=BAUDRATE;       //set baud rate 
    UCSRB|=(1<<TXEN)|(1<<RXEN);    //enable receiver and transmitter 
    UCSRC|=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);// 8bit data format 
} 

// function to send data 
void uart_transmit (unsigned char data) 
{ 
    while (!(UCSRA & (1<<UDRE)));   // wait while register is free 
    UDR = data;        // load data in the register 
} 

// function to receive data 
unsigned char uart_receive (void) 
{ 
    while(!(UCSRA) & (1<<RXC));   // wait while data is being received 
    return UDR;        // return 8-bit data 
} 

// main function: entry point of program 
int main (void) 
{ 
    unsigned char a = 0; 
    char buffer[10] = 0; 
    DDRB = 0xFF; 

    uart_init();       // initialize UART 

    while(1) 
    { 
     a=uart_receive();     // save the received data in a variable 
     uart_transmit(a);     // send it back 
     blink(a - 0);      // print in the led 
     _delay_ms(100);      // wait before next attempt 
    } 

    return 0; 
} 

Проблема я столкнулся в том, что ни один из регистров, связанных с USART, кажется, распознается компилятором. См. Пример ошибки компиляции, которую я получаю:

'UBRRH' undeclared (first use in this function) 

Я не могу включить сюда сюда?

Screeshot

ответ

3

кажется, что код у вас есть не для ATmega168, ошибки, котор вы получаете в связи с некоторыми регистрами то не существует в ATmega168. В ATMEGA168 существует более одного UART, поэтому имена регистров нумеруются. Например, вы можете использовать UBRR0H вместо UBRRH.

Попробуйте это:

#ifdef UDR0 
#define UBRRH UBRR0H 
#define UBRRL UBRR0L 
#define UDR UDR0 

#define UCSRA UCSR0A 
#define UDRE UDRE0 
#define RXC RXC0 

#define UCSRB UCSR0B 
#define RXEN RXEN0 
#define TXEN TXEN0 
#define RXCIE RXCIE0 

#define UCSRC UCSR0C 
#define URSEL 
#define UCSZ0 UCSZ00 
#define UCSZ1 UCSZ01 
#define UCSRC_SELECT 0 
#else 
#define UCSRC_SELECT (1 << URSEL) 
#endif 

#define BAUD 9600UL 
#define UBRRVAL (F_CPU/(BAUD*16)-1) 
#define USE_SLEEP 1 

void uart_init() { 
    /* set baud rate */ 
    UBRRH = UBRRVAL >> 8; 
    UBRRL = UBRRVAL & 0xff; 
    /* set frame format: 8 bit, no parity, 1 bit */ 
    UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0); 
    /* enable serial receiver and transmitter */ 
    #if !USE_SLEEP 
     UCSRB = (1 << RXEN) | (1 << TXEN); 
    #else 
     UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE); 
    #endif 
} 

void uart_putc(uint8_t c) { 
    if(c == '\n') 
     uart_putc('\r'); 

    /* wait until transmit buffer is empty */ 
    while(!(UCSRA & (1 << UDRE))); 

    /* send next byte */ 
    UDR = c; 
} 

uint8_t uart_getc() 
{ 
    /* wait until receive buffer is full */ 
    #if USE_SLEEP 
     uint8_t sreg = SREG; 
     sei(); 

     while(!(UCSRA & (1 << RXC))) 
      sleep_mode(); 

     SREG = sreg; 
    #else 
     while(!(UCSRA & (1 << RXC))); 
    #endif 

    uint8_t b = UDR; 
    if(b == '\r') 
     b = '\n'; 

    return b; 
} 

int main(){ 
    DDRB = 0xff; 

    uint8_t data = 0; 
    uart_init(); 

    while(1){ 
     data = uart_getc(); 
     uart_putc(data); 
     blink(a - 0); 
     _delay_ms(100); 
    } 

    return 0; 
} 
+0

Спасибо за подсказку Габриэля. Есть ли ссылка для проверки всех связанных имен регистра на другой UART? – Bob

+2

Несомненно, вот документация: http://www.atmel.com/images/doc2545.pdf –