我怎么能把.o文件转换成.elf文件?

时间:2016-11-23 17:00:09

标签: c macos avr avr-gcc avrdude

我有一个名为lab7.c的文件,当我编译成一个.o文件时,一切都很好。然而,然后我用

创建一个.elf文件
avr-gcc -mmcu=atmega324a -o lab7.elf lab7.o

我收到

的错误消息
    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

我到处寻找尝试解决这个问题但无法找到任何东西。我要做的就是将此代码上传到我的面包板。我正在使用COS上的macOS Sierra编写终端。

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由我的老师发给我,因此我没有名为lcd.c的文件

1 个答案:

答案 0 :(得分:1)

目标文件lab7.o仅包含其中一个c文件的代码。它只是整个可执行文件的一部分。

要创建可执行文件,您需要将所有部分链接在一起。从您显示的代码中,看起来您缺少具有LCD功能的部件。你有一个名为lcd.o的文件吗?尝试

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

也可能是LCD功能位于库或存档文件中。在这种情况下,您需要以其他方式链接它,但它仍然需要成为gcc命令的一部分。

如果您拥有所有源文件(.c和.h),则可以使用一个gcc命令从源一直编译到.elf。

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