带有 ATMEGA168A 的 USART -

USART with ATMEGA168A -

我正在尝试制作一个非常简单的 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;
}

我面临的问题是 none 与 USART 相关的寄存器似乎被编译器识别。查看我遇到的编译错误示例:

'UBRRH' undeclared (first use in this function)

我是不是遗漏了一个包含?

您的代码似乎不适用于 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;
}