-2

I have a file named lab7.c and when I compile to make it a .o file everything is fine. However then I go to make it a .elf file with

avr-gcc -mmcu=atmega324a -o lab7.elf lab7.o

I get the error message of

    lab7.o:(.data+0x8): undefined reference to `lcd_putc'
    lab7.o: In function `main':
    lab7.c:(.text.startup+0x0): undefined reference to `lcd_init'
    collect2: error: ld returned 1 exit status

I have looked everywhere to try and fix this and cant find anything. all I am trying to do is upload this code to my breadboard. I am using terminal on macOS Sierra writing in C.

lab7.c

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

static FILE lcd_stdout=FDEV_SETUP_STREAM(lcd_putc,NULL,_FDEV_SETUP_WRITE);

#define PUSHED 1
#define RIGHT_BUTTON ((PINA&_BV(PIN3)) >> 3)
#define LEFT_BUTTON ((PINA&_BV(PIN0)) >> 0)

#define LEFTMOST 0b10000000
#define RIGHTMOST 0b00000001

int main(void) {
enum states { left_serve, right_serve, moving_left, moving_right};



// Include the following variable declarations here 
char state;     // This variable holds the current state 
char leds;      // Current "court" --- inverse of PORTC

lcd_init();     // If you want to write to the LCD
stdout=&lcd_stdout;

// Required setup for I/O pins  
DDRD = 0xFF;        // All PORTD pins are outputs
DDRA = 0x10;        // PORTA pin 4 is an output, rest inputs
PORTA |= 0x10;      // Only pin 4 is important - should be 1

// Initialize "state" to "left_serve" here  
state=left_serve;

if (LEFT_BUTTON == PUSHED) { 
    if (leds == LEFTMOST) {
        state = moving_right;
    }
    else 
    {
        state = right_serve;
    }
}
if (RIGHT_BUTTON == PUSHED){
    if (leds == RIGHTMOST) {
        state = moving_left;
    }
    else 
    {
        state = left_serve;
    }
}
if (RIGHT_BUTTON != PUSHED && LEFT_BUTTON != PUSHED && leds == 0x00) {
    if (state == moving_right) {
        state = left_serve;
    }
    else
    {
        state = right_serve;
    }
}
switch (state) {

    case moving_left:
    leds = leds << 1;
    break;

    case moving_right:
    leds = leds >> 1;
    break;

    case right_serve:
    leds = RIGHTMOST;
    break;

    case left_serve:
    leds = LEFTMOST;
    break;
}       
void setLEDs(int leds) {
PORTD= (leds ^ 0x00FF);
PORTC= (((~leds)>>8)&0x0003)+(PORTC&0xFFFC);
}

}       

lcd.h

#ifndef __LCD_H__
#define __LCD_H__

// A. Sheaff 1/10/2008
// 4 bit LCD interface.

// Define LCD type. Choose one.
// #define LCD_1LINE
// #define LCD_2LINE
 #define LCD_4LINE
// End choice.

// Set line length
#define LCD_LINELEN 16
// Set New line address
#define LCD_LINE2A 0x40

// Register select, Read/Write, Clock
#define LCD_RS PIN4
#define LCD_RW PIN6
#define LCD_E  PIN7
// Code assumes lower 4 bits are for data.
#define LCD_DATW PORTB
#define LCD_DATR PINB

// LCD commands
#define LCD_CLR     0x01    // LCD Clear
#define LCD_HOME    0x02    // LCD Home
#define LCD_SETDD   0x80    // LCD Set Data Address
#define LCD_SHIFT   0x10    // Shift
#define LCD_SCURS   0x00    // Shift Cursor
#define LCD_SDISP   0x08    // Shift Dislay
#define LCD_SRGHT   0x04    // Shift Right
#define LCD_SLEFT   0x00    // Shift Left

// LCD initialization
void lcd_init(void);

// Wait for LCD to finish current operation.  Returnds DD RAM address.
unsigned char lcd_busy_wait(void);

// Write character data to LCD
void lcd_dwrite(unsigned char d);
int lcd_putc(char c, struct __file * f);

// Write instruction data to LCD
void lcd_iwrite(unsigned char d);

// Read data memory
unsigned char lcd_dread(void);
#endif // __LCD_H__

lcd.h was given to me by my teacher, therefore I don't have a file named lcd.c

P. Blang
  • 1
  • 4

1 Answers1

2

The object file lab7.o only has the code from one of the c files. It is only part of the whole executable.

To create the executable, you need to link together all the parts. From the code you show, it looks like you are missing the parts with the LCD functions. Do you have a file called lcd.o? Try

avr-gcc -mmcu=atmega324a -o lab7.elf lab7.o lcd.o

It may also be that the LCD functions are in a library or archive file. In that case, you will need to link it in some other way, but it still needs to be part of the gcc command.

If you have all the source files (.c and .h), you could compile from source all the way to .elf with one gcc command.

avr-gcc -mmcu=atmega324a -o lab7.elf lab7.c lcd.c lcd.h
UncleO
  • 8,299
  • 21
  • 29