I'm trying to learn to use USART on an ATmega328P. I'm using this datasheet.
I'm using the following code to echo characters I type on my terminal:
#include <avr/io.h>
#define BAUD 9600
#define F_CPU 16000000UL
static void usart_init(void) {
unsigned int ubrr = F_CPU / 16 / BAUD - 1;
UBRR0H = (unsigned char) (ubrr >> 8);
UBRR0L = (unsigned char) ubrr;
UCSR0B = (1 << TXEN0) | (1 << RXEN0);
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
}
static void usart_transmit(unsigned char data) {
while (!(UCSR0A & (1 << UDRE0)))
;
UDR0 = data;
}
static unsigned char usart_receive(void) {
while (!(UCSR0A & (1 << RXC0)))
;
return UDR0;
}
int main(void) {
unsigned char c;
usart_init();
for (;;) {
c = usart_receive();
usart_transmit(c);
}
return 0;
}
Section 19.10 (pg 159) states that
The transmit buffer can only be written when the UDREn flag in the UCSRnA register is set. Data written to UDRn when the UDREn flag is not set, will be ignored by the USART transmitter. When data is written to the transmit buffer, and the transmitter is enabled, the transmitter will load the data into the transmit shift register when the shift register is empty. Then the data will be serially transmitted on the TxDn pin.
The only TXD
pin I see on page 3 of the datasheet (pinout diagram) is PD1
. How do I, for instance, use PD6
as as my transmitting pin? In the datasheet, I don't see anything like UDR6
?
I came across this project in which he seems to be using PD6
as his transmitter. But his USART code looks identical to mine:
void initUSART(void) { /* requires BAUD */
UBRR0H = UBRRH_VALUE; /* defined in setbaud.h */
UBRR0L = UBRRL_VALUE;
#if USE_2X
UCSR0A |= (1 << U2X0);
#else
UCSR0A &= ~(1 << U2X0);
#endif
/* Enable USART transmitter/receiver */
UCSR0B = (1 << TXEN0) | (1 << RXEN0);
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); /* 8 data bits, 1 stop bit */
}
void transmitByte(uint8_t data) {
/* Wait for empty transmit buffer */
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = data; /* send data */
}
uint8_t receiveByte(void) {
loop_until_bit_is_set(UCSR0A, RXC0); /* Wait for incoming data */
return UDR0; /* return register value */
}
How does USART know which pin to use as the transmitter (and receiver)?
#define SPEAKER PD6
, don't see anything about USARTs. \$\endgroup\$