NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » make: *** [portplay.hex] Error 1

February 10, 2013
by Nichben
Nichben's Avatar

I get this when I try to compile this program. When I remove the while loop or substitute a literal for the second variable it compiles and runs fine. I've installed WinAVR on my PC with Windows Vista. Here's my program:

#define F_CPU 14745600

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/io_328p.h"
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"

//PORTS
//PB1, pin 15: OUtput for led blink.

int main() {
    lcd_init();
    DDRB |= (1<<PB1);                                   // Input from shift register
    uint8_t idx, tik, itr, pr=0;
    lcd_write_string(PSTR("Test ripple and ring"));
    //delay_ms(5000);
    itr = 0;
    while (1){
        tik = 0;
        while(tik<itr){
            for(idx=0; idx<2; idx++){                               // 10 to get all the way to all the col high
                PORTB |= (1<<PB1);
                delay_ms(2);
                PORTB &= ~(1<<PB1);
                delay_ms(2);
            }
            tik++;
        }
        for(idx=0; idx<2; idx++){                               // 10 to get all the way to all the col high
            PORTB |= (1<<PB1);
            delay_ms(500);
            PORTB &= ~(1<<PB1);
            delay_ms(500);
        }
    delay_ms(3000);
    itr = pow(2,pr);
    pr += 2;
    }
    return 0;                                                                                                                                                                                                                                         
}

and the error when I attempt to compile:

C:\328ATMega_Projects\ripple>make
make -C ../libnerdkits
make[1]: Entering directory `C:/328ATMega_Projects/libnerdkits'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `C:/328ATMega_Projects/libnerdkits'
avr-gcc -g -Os -Wall -mmcu=atmega328p  -Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfsca
nf -lscanf_flt -lm -o portplay.o portplay.c ../libnerdkits/delay.o ../libnerdkit
s/lcd.o ../libnerdkits/uart.o ../libnerdkits/delayns.o
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr5\libc.a(modf
.o): In function `modf':
(.text.fplib+0x3e): relocation truncated to fit: R_AVR_13_PCREL against symbol `
__subsf3' defined in .text section in c:/winavr-20090313/bin/../lib/gcc/avr/4.3.
2/avr5\libgcc.a(_addsub_sf.o)
make: *** [portplay.hex] Error 1

All the .c and .h files are in libnerdkits folder. This has only started this evening after almost a year of trouble free programming. Thanks.

February 11, 2013
by Noter
Noter's Avatar

You have the -lm in your make file but it needs to follow your source/object references as shown here:

avr-gcc -g -Os -Wall -mmcu=atmega328p -mcall-prologues -std=c99\
        -I/home/paul/AVR \
        -Wl,-Map=Test_AVR.o.map \
        Test_AVR.c -o Test_AVR.o \
        -lm  -Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt

Also, as a matter of practice, the return 0 at the end of your source is useless. It follows an endless loop so will never be executed and even if it was, there is nothing to return to.

February 12, 2013
by Nichben
Nichben's Avatar

Hi, I've tried your suggestions but still get the same problem. In my program, portplay, if I change line 42 to itr = idx; it works but not as it's given here even with the changes to the makefile. I've also tried the original makefile from nerdkits that was included in the libnerdkits folder that i downloaded from nerdkits when I first bought my nerdkit with the ATMega168 mpu. I made the necessary changes in my program before doing so. Next I changed that original makefile for the 168 according to your suggestion and this too didn't work. I've even tried changes to the arguments in pow(2, pr) from integer to double types and this didn't have an effect either. Here is the makefile for the ATMega328 with your advised changes.

GCCFLAGS=-g -Os -Wall -mmcu=atmega328p 
LINKFLAGS=-lm -Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt
AVRDUDEFLAGS=-c avr109 -p m328p -b 115200 -P COM4
LINKOBJECTS=../libnerdkits/delay.o ../libnerdkits/lcd.o ../libnerdkits/uart.o ../libnerdkits/delayns.o

all:    portplay-upload

portplay.hex:   portplay.c
    make -C ../libnerdkits
    avr-gcc ${GCCFLAGS} ${LINKFLAGS} -o portplay.o portplay.c ${LINKOBJECTS}
    avr-objcopy -j .text -j .data -O ihex portplay.o portplay.hex

portplay.ass:   portplay.hex
    avr-objdump -S -d portplay.o > portplay.ass

portplay-upload:    portplay.hex
    avrdude ${AVRDUDEFLAGS} -U flash:w:portplay.hex:a

Please let me know if I can fix this. I've had similar problems in other programs that involved the use of pow(x,y) function. When I assign it to a variable and try to pass the value to another function or to a loop I get the same Error 1. I've even tried to pass the reference to a function or loop to no avail.

February 12, 2013
by Noter
Noter's Avatar

I'm not sure what you've tried but you want to use pow() like you are then you have to move the linkflags to follow the .c and .o in your make file - like this:

avr-gcc ${GCCFLAGS} -o portplay.o portplay.c ${LINKFLAGS} ${LINKOBJECTS}
February 12, 2013
by Nichben
Nichben's Avatar

Working now. many thanks.

Post a Reply

Please log in to post a reply.

Did you know that two resistors plus a transistor can be used to make a better voltage supply? Learn more...