sesc360
sesc360

Reputation: 3255

AVR USART file not recognized in C

I have the following test setup below. When I compile the code, I get the following error: The initUSART is not recognized, but I have included the file in the appropriate places. Did I miss out on anything?

AVR Development Stack
Get input main.c file...
Compile code and return elf file...
main.o: In function `main':
/Users/sebastianscharf/Documents/Hardware/AVR/main.c:14: undefined reference to `initUSART'
collect2: error: ld returned 1 exit status
avr-objcopy: 'main.elf': No such file

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: Expected signature for ATmega328 is 1E 95 14
         Double check chip, or use -F to override this check.

avrdude done.  Thank you.

main file

#include "config.h"
#include <avr/io.h>
#include <util/delay.h>
#include "USART.h"

int main(void) {

  char serialCharacter;

  // --- INITS --- //
  DDRB = 0xff;

  // Set up LED for output
  initUSART();
  return 0;
}

USART.h

/* These are defined for convenience */
#define   USART_HAS_DATA   bit_is_set(UCSR0A, RXC0)
#define   USART_READY      bit_is_set(UCSR0A, UDRE0)

uint8_t receiveByte(void);

/* Takes the defined BAUD and F_CPU, calculates the bit-clock multiplier, and configures the hardware USART*/
void initUSART(void);

USART.c

#include "config.h"
#include <avr/io.h>
#include <util/setbaud.h>
#include "USART.h"

void initUSART(void) {
    // Requires BAUD
    UBRR0H = UBRRH_VALUE;
    UBRR0L = UBRRL_VALUE;

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

    // Enable USART
    UCSR0B = (1 << TXEN0) | (1 << RXEN0);
    UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8 data bits, 1 stop bit
}

bash file

#!/bin/bash

source bashColors.sh

echo -e "${IGreen}AVR Development Stack${Reset}"

echo -e "${BIBlue}Get input main.c file...${Reset}"
avr-gcc -g -Os -mmcu=atmega328p -c main.c USART.c &&

echo -e "${BIBlue}Compile code and return elf file...${Reset}"
avr-gcc -g -mmcu=atmega328p -o main.elf main.o &&

echo -e "${BIBlue}Convert elf file to hex...${Reset}"
# avr-objcopy converts into hex file. -j indicates that we want the information from the .text and .data segment extracted.
avr-objcopy -j .text -j .data -O ihex main.elf out.hex &&

echo -e "${BIBlue}Uploading data to microcontroller...${Reset}"
avrdude -c usbtiny -p m328

Upvotes: 1

Views: 460

Answers (1)

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140276

You compiled both source files properly to .o with:

avr-gcc -g -Os -mmcu=atmega328p -c main.c USART.c

Now the main.o file contains an external reference to initUSART (partly thanks to the #include "USART.h" directive which provides the proper prototype)

but this link line:

avr-gcc -g -mmcu=atmega328p -o main.elf main.o &&

only references main.o. You need to add USART.o so the symbol is resolved by the linker (the linker doesn't care about .h include files), like this:

avr-gcc -g -mmcu=atmega328p -o main.elf main.o USART.o &&

Upvotes: 3

Related Questions