我正在尝试制作一个非常简单的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)
我错过了包含在这里吗?
答案 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;
}