带有ATMEGA168A的USART -

时间:2015-12-19 17:16:55

标签: c avr atmega

我正在尝试制作一个非常简单的USART程序,它将收到的字符发送回发送器,并通过在我的面包板中闪烁8个LED来表示等效的二进制数。

以下是代码:

#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

1 个答案:

答案 0 :(得分: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;
}