6.18.1.2 Customizing Helper Functions for XC8 AVR
When using the MPLAB XC8 Compiler for AVR MCUs, helper functions that can read and/or write one
byte of data need to be written to define the source and destination respectively of the
stdin and stdout streams used by IO functions like
scanf() and printf(). In addition, objects of type
FILE need to be defined and associated with each streams.
The FDEV_SETUP_STREAM() macro can assist with stream configuration. It
expands to an initializer that can be used with the definition of a user-supplied buffer of
type FILE, setting up that buffer so that it can be used with a stream that
is valid for stdio operations. Streams can be read-only, write-only, or read-write, based on
one of this macro's flag values _FDEV_SETUP_READ,
_FDEV_SETUP_WRITE, or _FDEV_SETUP_RW.
The following example is applicable to the AVR128DA48 Curiosity Nano board and has writable
FILE buffer assigned to stdout, which maps to USART1 via
the uart_putchar() function.
#include <xc.h>
#define F_CPU (4000000UL) /* using default clock 4MHz*/
#define USART1_BAUD_RATE(BAUD_RATE) ((float)(64 * 4000000 / (16 * (float)BAUD_RATE)) + 0.5)
#include <util/delay.h>
#include <stdio.h>
void USART1_init(void)
{
PORTC.DIRSET = PIN0_bm; /* set pin 0 of PORT C (TXd) as output*/
PORTC.DIRCLR = PIN1_bm; /* set pin 1 of PORT C (RXd) as input*/
USART1.BAUD = (uint16_t)(USART1_BAUD_RATE(9600)); /* set the baud rate*/
USART1.CTRLC = USART_CHSIZE0_bm| USART_CHSIZE1_bm; /* set the data format to 8-bit*/
USART1.CTRLB |= USART_TXEN_bm; /* enable transmitter*/
}
static int uart_putchar(char c, FILE * stream);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
static int
uart_putchar(char c, FILE *stream)
{
if (c == '\n')
uart_putchar('\r', stream);
while(!(USART1.STATUS & USART_DREIF_bm))
{
;
}
USART1.TXDATAL = c;
return 0;
}
int main()
{
USART1_init();
stdout = &mystdout;
int i = 0;
while (1) {
printf ("Hello world %d\n", i++);
}
_delay_ms(1000);
}
