UART identifier "UBRR0H" is undefined (ATmega 8)

Hello everyone, I am learning how to use header files with UART on ATmega8. I have two problems: First one for some reason the registers like identifier “UBRR0L” is undefined and the rest of them. And the second one is it does not include the header file. I dont know if these two problem are related. I have tried my best to resolve using examples but to no end.

Here are the screenshots. Any help would be much appreciated. Cheers!

And here is the code to the project.

For the stdio_setup.c:

#define F_CPU 8000000UL
#define BAUD 9600
#define BAUD_TOL 2

#include <avr/io.h>
#include <stdio.h>
#include <util/setbaud.h>

void UartPutchar(char data);
int UartGetchar(void);

static FILE the_stdio = FDEV_SETUP_STREAM(UartPutchar, UartGetchar, _FDEV_SETUP_RW);

void UartInit(void)
{
	stdout = &the_stdio;
	stdin = &the_stdio;
	
	UBRR0H = UBRRH_VALUE;
	UBRR0L = UBRRL_VALUE;

	#if USE_2X
	UCSR0A |= (1 << U2X0);
	#endif

	UCSR0B = (1 << RXEN0) | (1 << TXEN0);

	// 8-bit, 1 stop bit, no pariAty, asynchronous UART
	UCSR0C = (1 << UCSZ01) | (1 << UCSZ00) | (0 << USBS0) |
	(0 << UPM01) | (0 << UPM00) | (0 << UMSEL01) |
	(0 << UMSEL00);
}

void UartPutchar(char data)
{
	while(!(UCSR0A & (1 << UDRE0)));
	UDR0 = data;
}

int UartGetchar(void)
{
	char data;
	
	while (!(UCSR0A & (1 << RXC0)));
	
	data = UDR0;
	
	if (data == '\n') {
		return -1;
	}
	UartPutchar(data);

	return data;
}

For the stdio_setup.h

#ifndef STDIO_SETUP_H_
#define STDIO_SETUP_H_

void UartInit(void);

#endif /* STDIO_SETUP_H_ */ 

And for the main.c :

#include <avr/io.h>
#include <stdio.h>
#include "stdio_setup.h"

int main(void)
{
	unsigned char rx_byte;
	
	DDRC = 0x01;					// LED on PC0
	
	UartInit();

	while(1) {
		if (UCSR0A & 0x80) {		// data received?
			rx_byte = UDR0;			// get the byte
			switch (rx_byte) {
				case 'a':
					PORTC = 0x01;	// switch LED on
				break;

				case 'b':
					PORTC = 0x00;	// switch LED off
				break;
			}
		}
	}
}

I am really trying mu best to resolve this but simply could not find the solutions or similar problems on the internet.

Wrong library structure, see the README in lib.lib must be a collection of folders where the library is stored. Do a “Build” after that and it should compile, and then the IntelliSense should update.

Thank you for the reply @maxgerhardt , but can you be more specific? I’ve tried moving them in the same directory but the problem is the same. I’ve tried with #include “…/lib/stdio_setup.h” and some other forms but still didnt fix the problem.

You should create a new folder in lib, e.g. stdio, and in that folder, the two stdio_setup.* should be. In your main.c program, refer to them then as just #include <stdio_setup.h>, and PlatformIO’s library dependency finder should then kick in and recognize that as a library dependency to the folder you’ve created and add that to the include path – no need to refer to those via relative paths then.

That did resolve the library problem, but I still have undefined registers?

Your topic title says ATmega8, but per https://sites.google.com/site/qeewiki/books/avr-guide/usart

the register only exists for the devices that have multiple UART ports. Your ATmega8 only has a UCSRA register, not UCSR0A. The compiler is correct.

Thank you @maxgerhardt for clearing up my mistakes. As far as the topic goes the problem was I didn’t know how to include libraries and did not check if the fuses of an ATmega8 and ATmega328P are the same (they are not).

Here is the code alternated from the site that you provided to turn a LED ON and OFF using UART on ATmega8.

// This code waits for a character and transmits the character back (with interrupts)
 

#include <avr/io.h>
#include <stdint.h>                     // needed for uint8_t

#include <avr/interrupt.h>


#define FOSC 8000000                       // Clock Speed
#define BAUD 9600                
#define MYUBRR FOSC/16/BAUD -1


volatile char ReceivedChar;
volatile char rx_byte;

int main( void )
{
    /*Set baud rate */
    UBRRH = (MYUBRR >> 8);
    UBRRL = MYUBRR;
    
    UCSRB |= (1 << RXEN) | (1 << TXEN);      // Enable receiver and transmitter
    UCSRB |= (1 << RXCIE);                   // Enable the receiver interrupt
    UCSRC |= (1 << URSEL) |(1 << UCSZ1) | (1 << UCSZ0);    // Set frame: 8data, 1 stp
                
                
                DDRB = 0xff; 
    sei();

       
    while(1)
    {
     if (!(UCSRA & (1 << RXC))) {		// data received?
			rx_byte = UDR;			// get the byte
			switch (rx_byte) {
				case 'a':
					PORTB = 0xff;	// switch LED on
				break;

				case 'b':
					PORTB = 0x00;	// switch LED off
				break;
			}
        }
    } 
   
}


ISR (USART_RXC_vect)
{
    ReceivedChar = UDR;                     // Read data from the RX buffer
    UDR = ReceivedChar;                     // Write the data to the TX buffer
}

And pltaformio.ini file for usbtiny:

[env:ATmega8]
platform = atmelavr
board = ATmega8

board_build.f_cpu = 8000000L
upload_protocol  = custom
upload_speed = 9600

lib_extra_dirs =
    /home/pi/Documents/PlatformIO/Projects/UART_ATmega8/lib
   
upload_flags  =
    -C
    ; use "tool-avrdude-megaavr" for the atmelmegaavr platform
    $PROJECT_PACKAGES_DIR/tool-avrdude/avrdude.conf
    -p
    $BOARD_MCU
    -c
    usbtiny
   -Uhfuse:w:0xd9:m ;set fuses manually
   -Uefuse:w:0xff:m
   -Ulfuse:w:0xe4:m
    
upload_command = avrdude $UPLOAD_FLAGS -e -u -U flash:w:$SOURCE:i

Great that you figured it out, but technically

this shouldn’t be necessary if this is the lib folder of the project – it should be picked up autoatically :slight_smile:

Yes it is unnecessary, forgot to delete that line. :slight_smile: