Blinking leds

Go To Last Post
41 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After playing around with avr's for quite some time (The first I bought was a at90s1200) I'm almost ashamed that I can't get my blinking led project working anymore.
The code should be pretty straight forward:


#define F_CPU 1000000UL

#include 
#include 

int main(void)
{
	_delay_ms(200);
	DDRB = 0xff;
	DDRD = 0xff;

	for(;;)
	{
		PORTB = 0xff;
		PORTD = 0xff;
		_delay_ms(200);
		PORTB = 0;
		PORTD = 0;
		_delay_ms(200);
	}
}

And most of the leds on ports B and D are blinking on the 5 different ATMEGA8's I've tried. (2 of them new out of the box). Different ATMEGA8's generate different led patterns. On one AVR PB1 was not blinking, on another PB2 was not blinking and on yet anoter PB1, 2, 3 and PB6 were not blinking. Same random patterns on PORTD. Each AVR seem to have a preference for a certain pattern, but sometimes the pattern changes (or temporarily dissapears) if the power is cycled.

After 3 whole days of breaking my head on this I have even eliminated most options from my makefile. Below is the complete output of a programming cycle after "make clean".

paul@dualcore ~/projects/avr/lib/main-wanhope-2013-02-21 $ avr-gcc --version
avr-gcc (GCC) 4.5.3
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

paul@dualcore ~/projects/avr/lib/main-wanhope-2013-02-21 $ make program
avr-gcc -c -mmcu=atmega8 -g -Os -Wall main.c
avr-gcc  main.o -o main.elf
avr-objdump -h -S main.elf > main.lst
avr-size main.elf
   text	   data	    bss	    dec	    hex	filename
     52	      0	      0	     52	     34	main.elf
avr-objcopy -j .text -j .data -j .bss -O ihex main.elf main.hex
avrdude -p atmega8 -c usbasp -ye -B20 -U flash:w:main.hex:i

avrdude: set SCK frequency to 32000 Hz
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9307
avrdude: erasing chip
avrdude: set SCK frequency to 32000 Hz
avrdude: erase-rewrite cycle count is now 14
avrdude: reading input file "main.hex"
avrdude: writing flash (52 bytes):

Writing | ################################################## | 100% 0.19s



avrdude: 52 bytes of flash written
avrdude: verifying flash memory against main.hex:
avrdude: load data flash data from input file main.hex:
avrdude: input file main.hex contains 52 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.12s



avrdude: verifying ...
avrdude: 52 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

I'm pretty convinced this problem has nothing to do with software, but a brand new ATMEGA8 which runs on the internal 1MHz clock also has the same problem. (With pullup on reset and decoupling caps etc.)

I've also tried 3 different programmers (2 USBasp's and one old STK500V2 based one) All programmers work, I can change the blink rate, but I can't get all leds to blink. Also tried different power supplies.

The only consistency I can find is that if a led is not blinking it's always on. It only goes off during reset.

Does anybody have any ideas about this? I'm empty.

main.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000034  00000000  00000000  00000054  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .stab         000003d8  00000000  00000000  00000088  2**2
                  CONTENTS, READONLY, DEBUGGING
  2 .stabstr      0000076f  00000000  00000000  00000460  2**0
                  CONTENTS, READONLY, DEBUGGING

Disassembly of section .text:

00000000 
: #else //round up by default __ticks_dc = (uint32_t)(ceil(fabs(__tmp))); #endif __builtin_avr_delay_cycles(__ticks_dc); 0: 8f e4 ldi r24, 0x4F ; 79 2: 93 ec ldi r25, 0xC3 ; 195 4: 01 97 sbiw r24, 0x01 ; 1 6: f1 f7 brne .-4 ; 0x4 <__zero_reg__+0x3> 8: 00 c0 rjmp .+0 ; 0xa <__zero_reg__+0x9> a: 00 00 nop int main(void) { _delay_ms(200); DDRB = 0xff; c: 8f ef ldi r24, 0xFF ; 255 e: 87 bb out 0x17, r24 ; 23 DDRD = 0xff; 10: 81 bb out 0x11, r24 ; 17 for(;;) { PORTB = 0xff; 12: 88 bb out 0x18, r24 ; 24 PORTD = 0xff; 14: 82 bb out 0x12, r24 ; 18 16: ef e4 ldi r30, 0x4F ; 79 18: f3 ec ldi r31, 0xC3 ; 195 1a: 31 97 sbiw r30, 0x01 ; 1 1c: f1 f7 brne .-4 ; 0x1a <__zero_reg__+0x19> 1e: 00 c0 rjmp .+0 ; 0x20 <__zero_reg__+0x1f> 20: 00 00 nop _delay_ms(200); PORTB = 0; 22: 18 ba out 0x18, r1 ; 24 PORTD = 0; 24: 12 ba out 0x12, r1 ; 18 26: ef e4 ldi r30, 0x4F ; 79 28: f3 ec ldi r31, 0xC3 ; 195 2a: 31 97 sbiw r30, 0x01 ; 1 2c: f1 f7 brne .-4 ; 0x2a <__zero_reg__+0x29> 2e: 00 c0 rjmp .+0 ; 0x30 <__zero_reg__+0x2f> 30: 00 00 nop 32: ef cf rjmp .-34 ; 0x12 <__zero_reg__+0x11>
This topic has a solution.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

Last Edited: Fri. Jan 18, 2019 - 02:06 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you compiling for the right chip ?
Are you uploading the correct executable to the chip ?

What does your circuit look like ?

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

With 40+ projects with AVRs under your belt I'm embarrassed to ask you if you have resistors in series with the LEDs but I'll ask anyway. :-)

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And to reedem myself for asking a stupid question I just ran your code on the STK500 with a M8 and all is well. :-)

The code size doesn't match yours, it's 102 bytes.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are ALL power supply pins (VCC, AVCC, GND) properly connected?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the help.
I rechecked all above, but I can't find the fault.
I suspect the error is not in the code.
Just to make sure I don't have a faulty batch of atmega8's I took a atmega328p, recompiled, and programmed it. All 11 connected leds were blinking, but after cycling the power a few times (plug with ground loop for scope etc. on the left) 7 of the leds stopped blinking and only turned of during a reset.

All leds are driven via 2 ULN2803 buffers and current limiting resistors. double checked all 4 power pins with a multimeter. There are also plenty of decoupling caps (also a few smd's on the little green adapter pcb's).

Difference in code size is remarkable. Recompile for atmega328p also is 52 bytes for me with avr-gcc4.5.3. Codesize will change with compiler options and the size of the 3 _delay_ms() macro's also change with F_CPU. According to my list file the whole stack is optimized away in my case.

Because the program in the atmega328p worked first time and only broke after the power was cycled a few times it does seem more like a hardware problem.
Powersupply has 5.05V when not connected and 4.98V when loaded by the breadboard. Because of the 470uF buffer cap I see a 7ms risetime on my scope without any overshoot.

I also believe ESD problems are unlikely. The atmega328p worked after first insertion and I didn't remove it from the breadboard afterwards.

Attachment(s): 

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's getting stranger all the time.
If I reprogram the atmega328p all connected leds are blinking again, and after plugging the 5V power connector a few times in and out some of the leds stop blinking.

The most logical conclusion would be that the flash got corrupted somehow, but a verify of the flash is ok.
I verified the flash at Vcc = 5V and at Vcc 3V1.

paul@dualcore ~/projects/avr/lib/main-wanhope-2013-02-21 $ make verify
avrdude -p atmega328p -c usbasp -B4 -U flash:v:main.hex:i

avrdude: set SCK frequency to 187500 Hz
avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e950f
avrdude: current erase-rewrite cycle count is 10 (if being tracked)
avrdude: verifying flash memory against main.hex:
avrdude: load data flash data from input file main.hex:
avrdude: input file main.hex contains 52 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.02s



avrdude: verifying ...
avrdude: 52 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

With the atmega328p all leds start blinking again after the chip is reprogrammed (Tried it 3 or 4 times). But this does not work with the atmega8.

The problem does seem to get worse If i remove the 470F elco from the breadboard.

I find it very hard to believe the problem is caused by the breadboard, epecially because the micro's are running from the internal oscillator and I use plenty of deoupling caps (including the smd on the pcb's).

I also had a deja-vu from my "fuses confusion" from october last year, which is also still unresolved.
https://www.avrfreaks.net/index.p...

Feels like I'm being haunted by ghosts and it's taking all of the fun out of playing with these little critters.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

-mmcu option is missing on the linking command line.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Stefan,

that did the trick. After almost a week of frustration I finally understand what happened.
Because of the missing initialisation code the zero register (r1) was not initialized. Most of the times it contained 0 anyway after startup, but apparently not always.

In trying to figure out what happened I even made a little video to show the problem:
http://www.hoevendesign.com/MVI_5167.AVI
At 20 seconds into the video the led's from PORTB are the mirror image of the leds on PORTD, they actually show the same nonzero "zero register".

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Recompile for atmega328p also is 52 bytes for me with avr-gcc4.5.3.
So it looks like you are not using Studio at all?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

So it looks like you are not using Studio at all?

John! This
Quote:

paul@dualcore ~/projects/avr/lib/main-wanhope-2013-02-21 $

is the giveaway that he is on some kind of Unix/Linux system. (user 'paul' on machine named 'dualcore', current directory is "home"/projects/avr/lib/main-wanhope-2013-02-21 .)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi John,
as Johan wrote before me, I've been working with some different flavors of linux almost exclusively for a few years now.

Sometimes Linux drives me insane, but still I don't want to go back to windows.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

 

I have the exact same issue. I cannot get my LEDs flashing. Paul's video link obviously expired, adding mmcu to the linker does not help, and setting register r1 to zero in assembly does not solve the problem either.

 

Here is my make file:

MCU   = atmega16
F_CPU = 16000000UL
BAUD  = 9600UL

LIBDIR = lib

 

PROGRAMMER_TYPE = avrispmkII

 

CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude

 

TARGET = blinkLED
SOURCES=$(wildcard *.c $(LIBDIR)/*.c)
OBJECTS=$(SOURCES:.c=.o)
HEADERS=$(SOURCES:.c=.h)

CPPFLAGS = -DF_CPU=$(F_CPU) -DBAUD=$(BAUD) -I. -I$(LIBDIR)
CFLAGS = -Os -g -std=gnu99 -Wall
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -ffunction-sections -fdata-sections
LDFLAGS = -Wl,-Map,$(TARGET).map
LDFLAGS += -Wl,--gc-sections
TARGET_ARCH = -mmcu=$(MCU)

%.o: %.c $(HEADERS) Makefile
     $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<;

$(TARGET).elf: $(OBJECTS)
    $(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@

%.hex: %.elf
     $(OBJCOPY) -j .text -j .data -O ihex $< $@

%.eeprom: %.elf
    $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@

%.lst: %.elf
    $(OBJDUMP) -S $< > $@

.PHONY: all disassemble disasm eeprom size clean squeaky_clean flash fuses

all: $(TARGET).hex

debug:
    @echo
    @echo "Source files:"   $(SOURCES)
    @echo "MCU, F_CPU, BAUD:"  $(MCU), $(F_CPU), $(BAUD)
    @echo

disassemble: $(TARGET).lst

disasm: disassemble

size:  $(TARGET).elf
    $(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf

clean:
    rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
    $(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
    $(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
    $(TARGET).eeprom

squeaky_clean:
    rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~ *.eeprom

flash: $(TARGET).hex

    $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<

program: flash

flash_eeprom: $(TARGET).eeprom
    $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<

avrdude_terminal:
    $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt

flash_usbtiny: PROGRAMMER_TYPE = usbtiny
flash_usbtiny: PROGRAMMER_ARGS =  # USBTiny works with no further arguments
flash_usbtiny: flash

flash_usbasp: PROGRAMMER_TYPE = usbasp
flash_usbasp: PROGRAMMER_ARGS =  # USBasp works with no further arguments
flash_usbasp: flash

flash_arduinoISP: PROGRAMMER_TYPE = avrisp
flash_arduinoISP: PROGRAMMER_ARGS = -b 19200 -P /dev/ttyACM0
## (for windows) flash_arduinoISP: PROGRAMMER_ARGS = -b 19200 -P com5
flash_arduinoISP: flash

flash_109: PROGRAMMER_TYPE = avr109
flash_109: PROGRAMMER_ARGS = -b 9600 -P /dev/ttyUSB0
flash_109: flash

LFUSE = 0x62

HFUSE = 0xdf
EFUSE = 0x00

FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m

fuses:
    $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
               $(PROGRAMMER_ARGS) $(FUSE_STRING)
show_fuses:
    $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv

set_default_fuses:  FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
set_default_fuses:  fuses

set_fast_fuse: LFUSE = 0xE2
set_fast_fuse: FUSE_STRING = -U lfuse:w:$(LFUSE):m
set_fast_fuse: fuses

set_eeprom_save_fuse: HFUSE = 0xD7
set_eeprom_save_fuse: FUSE_STRING = -U hfuse:w:$(HFUSE):m
set_eeprom_save_fuse: fuses

clear_eeprom_save_fuse: FUSE_STRING = -U hfuse:w:$(HFUSE):m
clear_eeprom_save_fuse: fuses

 

Here is my c-code:

#include <avr/io.h>                      

#include <util/delay.h>                   

__asm__("clr  r1   \n\t");

 

int main(void) {

  DDRB |= 0b00000001;     

  while (1) {

    PORTB = 0b00000001;   
    _delay_ms(1000);             

    PORTB = 0b00000000;     
    _delay_ms(1000);                                        

  }                                               
  return 0;                       
}

 

blinkLED.lst - this worries me the most:

blinkLED.elf:     file format elf32-avr

Disassembly of section .text:

00000000 <__vectors>:
   0:    0c 94 2a 00     jmp    0x54    ; 0x54 <__ctors_end>
   4:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
   8:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
   c:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  10:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  14:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  18:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  1c:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  20:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  24:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  28:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  2c:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  30:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  34:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  38:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  3c:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  40:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  44:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  48:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  4c:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
  50:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>

00000054 <__ctors_end>:
  54:    11 24           eor    r1, r1
  56:    1f be           out    0x3f, r1    ; 63
  58:    cf e5           ldi    r28, 0x5F    ; 95
  5a:    d4 e0           ldi    r29, 0x04    ; 4
  5c:    de bf           out    0x3e, r29    ; 62
  5e:    cd bf           out    0x3d, r28    ; 61
  60:    0e 94 36 00     call    0x6c    ; 0x6c <main>
  64:    0c 94 4d 00     jmp    0x9a    ; 0x9a <_exit>

00000068 <__bad_interrupt>:
  68:    0c 94 00 00     jmp    0    ; 0x0 <__vectors>

0000006c <main>:

__asm__("clr  r1   \n\t");

int main(void) {

  DDRB |= 0b00000001;
  6c:    b8 9a           sbi    0x17, 0    ; 23

  while (1) {

    PORTB = 0b00000001;
  6e:    81 e0           ldi    r24, 0x01    ; 1
  70:    88 bb           out    0x18, r24    ; 24
    #else
        //round up by default
        __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
    #endif

    __builtin_avr_delay_cycles(__ticks_dc);
  72:    2f ef           ldi    r18, 0xFF    ; 255
  74:    33 ed           ldi    r19, 0xD3    ; 211
  76:    90 e3           ldi    r25, 0x30    ; 48
  78:    21 50           subi    r18, 0x01    ; 1
  7a:    30 40           sbci    r19, 0x00    ; 0
  7c:    90 40           sbci    r25, 0x00    ; 0
  7e:    e1 f7           brne    .-8          ; 0x78 <main+0xc>
  80:    00 c0           rjmp    .+0          ; 0x82 <main+0x16>
  82:    00 00           nop
    _delay_ms(1000);

    PORTB = 0b00000000;
  84:    18 ba           out    0x18, r1    ; 24
  86:    2f ef           ldi    r18, 0xFF    ; 255
  88:    33 ed           ldi    r19, 0xD3    ; 211
  8a:    90 e3           ldi    r25, 0x30    ; 48
  8c:    21 50           subi    r18, 0x01    ; 1
  8e:    30 40           sbci    r19, 0x00    ; 0
  90:    90 40           sbci    r25, 0x00    ; 0
  92:    e1 f7           brne    .-8          ; 0x8c <main+0x20>
  94:    00 c0           rjmp    .+0          ; 0x96 <main+0x2a>
  96:    00 00           nop
  98:    eb cf           rjmp    .-42         ; 0x70 <main+0x4>

0000009a <_exit>:
  9a:    f8 94           cli

0000009c <__stop_program>:
  9c:    ff cf           rjmp    .-2          ; 0x9c <__stop_program>

 

 

I appreciate any help.

 

Thanks.

 

MPN

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That listing looks perfect to me, code that should work (as long as the LED is wired right on PORTB.0). What makes you think the code is wrong?
.
BTW what on earth is the asm("clr r1") supposed to achieve? It's ignored because it's outside the body of a function but what was the intention?

Last Edited: Fri. Aug 31, 2018 - 01:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi clawson. Thanks for your quick response.

 

Well, PB0 does not output a voltage, hence, the LED is switched off. That makes me think that the code must be wrong. Following this thread, Paul had similar issues.

 

I figured that initializing r0 might solve the problem; it sounded like this was Paul's problem anyway.

Last Edited: Fri. Aug 31, 2018 - 01:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How interesting. It seems to be the _delay_ function. If I comment that piece out, they light up. Not sure why the delay does not work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not sure why the delay does not work.

I bet it does.  Just wait 16 seconds.

 

Hint:  #defining F_CPU to be 16 MHz does not make your AVR run at 16 MHz.  It >>tells<< the compiler how fast the AVR is running at.  >>You<< have to make it do that, usually by connecting a crystal and changing the CKSEL/SUT fuses appropriately.  Have you done so?  Your post shows your fuses to be the factory default values, meaning that your AVR is running at 1 MHz from the internal RC oscillator.  The delays will be 16 times longer than you intend.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is becoming really entertaining ... look at this:

 

leds are on:

#include <avr/io.h>
#define F_CPU 1000000UL
#include <util/delay.h>

int main(void) {
    DDRC = 0xff;
    DDRA = 0xff;

    while (1) {
        PORTC = 0b10010011;
        //_delay_ms(1000);
        PORTA = 0b10010011;
    }
    return 1;
}

 

leds are off:

#include <avr/io.h>
#define F_CPU 1000000UL
#include <util/delay.h>

int main(void) {
    DDRC = 0xff;
    DDRA = 0xff;

    while (1) {
        PORTC = 0b10010011;
        _delay_ms(1000);
        PORTA = 0b10010011;
    }
    return 1;
}

 

Fun times :-)

Last Edited: Fri. Aug 31, 2018 - 03:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I see no difference between your two programs.

 

CAn you post a schematic as you say PORTB.0 in one post but PORTC and PORTA in your last post.

 

Before this turns into a 50+ post thread over something simple post a schematic of your circuit and lets move from there

 

JIm

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OP here...

My problem apperntly was that the --mmcu flag was needed both during compiling and linking, as sternst pointed out.

Without it the code was smaller (as JS noted in #4) but incomplete. Startup code was missing

You seem to use (TARGET_ARCH) for both compiling and linking, so that looks OK.

 

First, Joey migt be onto something. Your AVR might be running at a different fequency than your code think it should. Try shorter blink times.

 

What is the output if you do a "make all" or a "make flash" from the command line?

The lines for the compiler generated from the makefile tend to be quite long, but most of it are the path names to diffent parts and of course the command line options specified in the makefile. and these lines are not so hard to read.

Are there any error messages spit out on the command line during compiling or linking?

 

Could it be that any of the CPP_FLAGS are also needed for proper linking?

I am not an expert in makefiles  / linker scripts and such. If I was I wouln't have gotten myself into trouble in 2013.

 

Another possible cause might be in the objcopy part.

Are you sure that all the code in the .lst file ends up in your .hex file and gets programmed?

 

Often I see some loops for copying data from Flash to RAM to initialize data during initialisation, but it could be that those loops are not in the startup code because they are not needed.

 

Also: if you blink whole ports (as I did) instead of a single bit you rule out some hardware related problems.

Is this all done on a single uC, or have you tried multiple uC's?

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:
post a schematic of your circuit

+1

 

For instructions on how to do that, see Tip #1.

 

(Tip #1 also tells how to properly post source code).

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for your hints. I inserted the code as suggested. I boiled the problem down to: compiler optimization. If I compile my code with the -Os flag, the LED does not light up. If I compile my code with the -O0 flag, the LED does light up. Please find below the c-code:

#include <avr/io.h>
#define F_CPU 1000000UL
#include <util/delay.h>

int main(void) {
    __asm__(
        "    ldi  r18, 0xFF" "\n"
        "    out  0x14, r18" "\n"
        "    ldi  r18, 0xFF" "\n"
        "    out  0x1a, r18" "\n"
        "    ldi  r18, 0x00" "\n"
        "    out  0x15, r18" "\n"
        );
    while (1) {
        __asm__(
            "    ldi  r18, 100"	 "\n"
            "    ldi  r19, 174"	 "\n"
            "    ldi  r20, 174"	 "\n"
            "1:  dec  r20"	"\n"
            "    brne 1b"	"\n"
            "    dec  r19"	"\n"
            "    brne 1b"	"\n"
            "    dec  r18"	"\n"
            "    brne 1b"	"\n"
            "    rjmp 1f"	"\n"
            "1:"	"\n"
            "    ldi  r18, 0xFF" "\n"
            "    out  0x15, r18" "\n"
            );
    }
    return 1;
}

I used make disassemble to look into the compiled code.

 

-compiled code with -Os flag

blinkLED.elf:     file format elf32-avr

Disassembly of section .text:

00000000 <__vectors>:
   0:	0c 94 2a 00 	jmp	0x54	; 0x54 <__ctors_end>
   4:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
   8:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
   c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  10:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  14:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  18:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  1c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  20:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  24:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  28:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  2c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  30:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  34:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  38:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  3c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  40:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  44:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  48:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  4c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  50:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>

00000054 <__ctors_end>:
  54:	11 24       	eor	r1, r1
  56:	1f be       	out	0x3f, r1	; 63
  58:	cf e5       	ldi	r28, 0x5F	; 95
  5a:	d4 e0       	ldi	r29, 0x04	; 4
  5c:	de bf       	out	0x3e, r29	; 62
  5e:	cd bf       	out	0x3d, r28	; 61
  60:	0e 94 36 00 	call	0x6c	; 0x6c <main>
  64:	0c 94 49 00 	jmp	0x92	; 0x92 <_exit>

00000068 <__bad_interrupt>:
  68:	0c 94 00 00 	jmp	0	; 0x0 <__vectors>

0000006c <main>:
#include <avr/io.h>
#define F_CPU 1000000UL
#include <util/delay.h>

int main(void) {
    __asm__(
  6c:	2f ef       	ldi	r18, 0xFF	; 255
  6e:	24 bb       	out	0x14, r18	; 20
  70:	2f ef       	ldi	r18, 0xFF	; 255
  72:	2a bb       	out	0x1a, r18	; 26
  74:	20 e0       	ldi	r18, 0x00	; 0
  76:	25 bb       	out	0x15, r18	; 21
        "    out  0x1a, r18" "\n"
        "    ldi  r18, 0x00" "\n"
        "    out  0x15, r18" "\n"
        );
    while (1) {
        __asm__(
  78:	24 e6       	ldi	r18, 0x64	; 100
  7a:	3e ea       	ldi	r19, 0xAE	; 174
  7c:	4e ea       	ldi	r20, 0xAE	; 174
  7e:	4a 95       	dec	r20
  80:	f1 f7       	brne	.-4      	; 0x7e <main+0x12>
  82:	3a 95       	dec	r19
  84:	e1 f7       	brne	.-8      	; 0x7e <main+0x12>
  86:	2a 95       	dec	r18
  88:	d1 f7       	brne	.-12     	; 0x7e <main+0x12>
  8a:	00 c0       	rjmp	.+0      	; 0x8c <main+0x20>
  8c:	2f ef       	ldi	r18, 0xFF	; 255
  8e:	25 bb       	out	0x15, r18	; 21
            "    rjmp 1f"	"\n"
            "1:"	"\n"
            "    ldi  r18, 0xFF" "\n"
            "    out  0x15, r18" "\n"
            );
    }
  90:	f3 cf       	rjmp	.-26     	; 0x78 <main+0xc>

00000092 <_exit>:
  92:	f8 94       	cli

00000094 <__stop_program>:
  94:	ff cf       	rjmp	.-2      	; 0x94 <__stop_program>

-compiled code with -O0 flag

blinkLED.elf:     file format elf32-avr

Disassembly of section .text:

00000000 <__vectors>:
   0:	0c 94 2a 00 	jmp	0x54	; 0x54 <__ctors_end>
   4:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
   8:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
   c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  10:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  14:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  18:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  1c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  20:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  24:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  28:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  2c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  30:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  34:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  38:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  3c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  40:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  44:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  48:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  4c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  50:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>

00000054 <__ctors_end>:
  54:	11 24       	eor	r1, r1
  56:	1f be       	out	0x3f, r1	; 63
  58:	cf e5       	ldi	r28, 0x5F	; 95
  5a:	d4 e0       	ldi	r29, 0x04	; 4
  5c:	de bf       	out	0x3e, r29	; 62
  5e:	cd bf       	out	0x3d, r28	; 61
  60:	0e 94 36 00 	call	0x6c	; 0x6c <main>
  64:	0c 94 4d 00 	jmp	0x9a	; 0x9a <_exit>

00000068 <__bad_interrupt>:
  68:	0c 94 00 00 	jmp	0	; 0x0 <__vectors>

0000006c <main>:
#include <avr/io.h>
#define F_CPU 1000000UL
#include <util/delay.h>

int main(void) {
  6c:	cf 93       	push	r28
  6e:	df 93       	push	r29
  70:	cd b7       	in	r28, 0x3d	; 61
  72:	de b7       	in	r29, 0x3e	; 62
    __asm__(
  74:	2f ef       	ldi	r18, 0xFF	; 255
  76:	24 bb       	out	0x14, r18	; 20
  78:	2f ef       	ldi	r18, 0xFF	; 255
  7a:	2a bb       	out	0x1a, r18	; 26
  7c:	20 e0       	ldi	r18, 0x00	; 0
  7e:	25 bb       	out	0x15, r18	; 21
        "    out  0x1a, r18" "\n"
        "    ldi  r18, 0x00" "\n"
        "    out  0x15, r18" "\n"
        );
    while (1) {
        __asm__(
  80:	24 e6       	ldi	r18, 0x64	; 100
  82:	3e ea       	ldi	r19, 0xAE	; 174
  84:	4e ea       	ldi	r20, 0xAE	; 174
  86:	4a 95       	dec	r20
  88:	f1 f7       	brne	.-4      	; 0x86 <main+0x1a>
  8a:	3a 95       	dec	r19
  8c:	e1 f7       	brne	.-8      	; 0x86 <main+0x1a>
  8e:	2a 95       	dec	r18
  90:	d1 f7       	brne	.-12     	; 0x86 <main+0x1a>
  92:	00 c0       	rjmp	.+0      	; 0x94 <main+0x28>
  94:	2f ef       	ldi	r18, 0xFF	; 255
  96:	25 bb       	out	0x15, r18	; 21
            "    rjmp 1f"	"\n"
            "1:"	"\n"
            "    ldi  r18, 0xFF" "\n"
            "    out  0x15, r18" "\n"
            );
    }
  98:	f3 cf       	rjmp	.-26     	; 0x80 <main+0x14>

0000009a <_exit>:
  9a:	f8 94       	cli

0000009c <__stop_program>:
  9c:	ff cf       	rjmp	.-2      	; 0x9c <__stop_program>

 

The difference between -Os and -O0 flag compilation is:

  6c:	cf 93       	push	r28
  6e:	df 93       	push	r29
  70:	cd b7       	in	r28, 0x3d	; 61
  72:	de b7       	in	r29, 0x3e	; 62

The optimised code (-Os) deletes this part.

Last Edited: Fri. Aug 31, 2018 - 04:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The led finally blinks once every second. The stack has never been properly initialised. I still do not know why. I added four lines of assembly which fixes the problem.

 

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>

int main(void) {
    __asm__(
        "    push r28 " "\n"
        "    push r29 " "\n"
        "    in   r28, 0x3d " "\n"
        "    in   r29, 0x3e " "\n"
        );

    DDRC = 0xff;
    DDRA = 0xff;

    while (1) {
        PORTC = 0b10010011;
        _delay_ms(1000);
        PORTC = 0x00;
        _delay_ms(1000);

    }
    return 1;
}

-MPN

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
    __asm__(
        "    push r28 " "\n"
        "    push r29 " "\n"
        "    in   r28, 0x3d " "\n"
        "    in   r29, 0x3e " "\n"
        );

Utter bollocks - this is NOT the solution!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Utter bollocks - this is NOT the solution!!!

+1

mpn1989 wrote:
The stack has never been properly initialised.

An interesting assertion.  I've lost track -- which model are we dealing with?  MNega16.  Where is the stack pointer for that model?

And what do we see in the posted "doesn't work"/ -Os code:

  58:	cf e5       	ldi	r28, 0x5F	; 95
  5a:	d4 e0       	ldi	r29, 0x04	; 4
  5c:	de bf       	out	0x3e, r29	; 62
  5e:	cd bf       	out	0x3d, r28	; 61

I.e., the stack pointer being initialized.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This getting boring. Your code .lss in #13 was quite obviously >>not<< compiled with -O0. The make file even says -Os. Stop taking wild stabs into the dark. Of course if you build with -O0 it won't work as expected. What does the documentation for delay.h say?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Fri. Aug 31, 2018 - 07:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
Of course if you build with -O0 it won't work as expected.

Weren't we told the opposite?

 

mpn1989 wrote:
If I compile my code with the -Os flag, the LED does not light up. If I compile my code with the -O0 flag, the LED does light up

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I said 'as expected' i.e. the delay will be wildly off because it will do runtime computations in fp.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
That listing looks perfect to me, code that should work (as long as the LED is wired right on PORTB.0). What makes you think the code is wrong? . BTW what on earth is the asm("clr r1") supposed to achieve? It's ignored because it's outside the body of a function but what was the intention?
It's not supposed to be ignored.

Such basic asm statements (no input or output) are allowed outside functions.

In this case, not terribly useful.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
It's not supposed to be ignored. Such basic asm statements (no input or output) are allowed outside functions. In this case, not terribly useful.

???  If not ignored, then there should be code generated for it, right?  Looking at #13 I don't see it...

 

00000054 <__ctors_end>:
  54:    11 24           eor    r1, r1
  56:    1f be           out    0x3f, r1    ; 63
  58:    cf e5           ldi    r28, 0x5F    ; 95
  5a:    d4 e0           ldi    r29, 0x04    ; 4
  5c:    de bf           out    0x3e, r29    ; 62
  5e:    cd bf           out    0x3d, r28    ; 61
  60:    0e 94 36 00     call    0x6c    ; 0x6c <main>
  64:    0c 94 4d 00     jmp    0x9a    ; 0x9a <_exit>

00000068 <__bad_interrupt>:
  68:    0c 94 00 00     jmp    0    ; 0x0 <__vectors>

0000006c <main>:

__asm__("clr  r1   \n\t");

int main(void) {

  DDRB |= 0b00000001;
  6c:    b8 9a           sbi    0x17, 0    ; 23

  while (1) {

    PORTB = 0b00000001;

...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you all for your patience and respectful responses. I appreciate it. If you find this topic boring, I suggest not responding to the thread.

 

I am still trying to get to the bottom of this. It is not bullocks that the LED flashes with one code and does not with the other. This is an observation. Whether my explanation is correct, can be discussed. I use an ATmega16 16PU 1022 and an AVRISPMKII programmer. The chip is mounted on an EasyAVR6 development board which has lots of peripherals including  a bunch of LEDs. I use Ubuntu , Emacs, and and a terminal.

 

If I comment out the "re-initializing the stack-pointer" assembly bit, the LEDs stop flashing. I stopped playing with the optimisation flag. It is now set to -Os. Here is the code:

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>

int main(void) {
/* If I comment this part out, the LEDs don't flash */
    __asm__(
        " ldi	r28, 0x5F " "\n"
        " ldi	r29, 0x04 " "\n"
        " out	0x3e, r29 " "\n"
        " out	0x3d, r28 " "\n"
        );
/* -----------------------------------------------*/
    DDRC = 0xff;

    while (1) {
        PORTC = 0xff;
        _delay_ms(1000);
        PORTC = 0x00;
        _delay_ms(1000);

    }
    return 1;
}

 

If I disassemble the code, we can see that the code actually just initialized the stack pointer, so why do I have to do it again?

 

00000000 <__vectors>:
   0:	0c 94 2a 00 	jmp	0x54	; 0x54 <__ctors_end>
   4:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
   8:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
   c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  10:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  14:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  18:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  1c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  20:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  24:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  28:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  2c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  30:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  34:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  38:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  3c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  40:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  44:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  48:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  4c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  50:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>

00000054 <__ctors_end>:
  54:	11 24       	eor	r1, r1
  56:	1f be       	out	0x3f, r1	; 63
  58:	cf e5       	ldi	r28, 0x5F	; 95
  5a:	d4 e0       	ldi	r29, 0x04	; 4
  5c:	de bf       	out	0x3e, r29	; 62
  5e:	cd bf       	out	0x3d, r28	; 61
  60:	0e 94 36 00 	call	0x6c	; 0x6c <main>
  64:	0c 94 51 00 	jmp	0xa2	; 0xa2 <_exit>

 

0x3d and 0x3e are addresses that point to SPL (stack pointer low) and SPH (stack pointer high), respectively.

Last Edited: Sat. Sep 1, 2018 - 11:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mpn1989 wrote:
It is not bullocks that the LED flashes with one code and does not with the other.

I don't see anywhere here where anyone said that one code might not have had a different result than the other.  See the quote that inspired the bollocks comment and my affirmation.

 

Surely Cliff meant "bullocks"...

Image result for bullocks

or the department store

 

mpn1989 wrote:
If I comment out the "re-initializing the stack-pointer" assembly bit, the LEDs stop flashing.

Back up and look at the posted code where you claimed the "reinitializing stack pointer", which was quoted by Cliff and inspired the offending opinion.  IT IS NOT THE SAME CODE -- IT HAS TWO 'IN' INSTRUCTIONS.  So at this point we have no idea what source code and the associated binary is really loaded into your chip at the present time.  Are you >>sure<< you are sending the code you think you are?  [how have you determined that?]  Is there a boot loader that might be jumping to main()?  Or similar.

 

 

 

 

 

 

 

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Sat. Sep 1, 2018 - 06:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One thing I would do is try a version that doesn't use _delay_ms, but just a home-rolled loop, not called as a function but inserted inline.  If your clock is 16 MHz, and you want to delay, say 100 ms, you need to burn 1.6 million cycles each blink on/off.  A starting point would be

 

volatile uint16_t delay1, delay2

#define MS_COUNT 8000 // seems about right for 1 ms at 16 MHz, but no guarantees

for (delay1 = 100; delay1 != 0; delay1--)
{
    for (delay2 = MS_COUNT; delay2 != 0; delay2--)
        ;
}

At least the inner delay variable needs to be 'volatile' to keep the compiler from optimizing the entire loop away.

 

But it does sound like your build/download process is broken in some way.

Last Edited: Sat. Sep 1, 2018 - 07:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

???  If not ignored, then there should be code generated for [inline ASM code outside of a function], right?  Looking at #13 I don't see it...

Eliminated by the linker due to --gc-sections

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
skeeve wrote:
It's not supposed to be ignored. Such basic asm statements (no input or output) are allowed outside functions. In this case, not terribly useful.

???  If not ignored, then there should be code generated for it, right?  Looking at #13 I don't see it...

It's the first  instruction quoted.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's the first  instruction quoted.

I don't see it generate any opcodes in the .lss:

0000006c <main>:

__asm__("clr  r1   \n\t");

int main(void) {

  DDRB |= 0b00000001;
  6c:    b8 9a           sbi    0x17, 0    ; 23

  while (1) {

    PORTB = 0b00000001;
  6e:    81 e0           ldi    r24, 0x01    ; 1
  70:    88 bb           out    0x18, r24    ; 24

 

It should show up as an eor r1, r1 but there's only one of those and it's in the CRT:

00000054 <__ctors_end>:
  54:    11 24           eor    r1, r1
  56:    1f be           out    0x3f, r1    ; 63
  58:    cf e5           ldi    r28, 0x5F    ; 95
  5a:    d4 e0           ldi    r29, 0x04    ; 4
  5c:    de bf           out    0x3e, r29    ; 62
  5e:    cd bf           out    0x3d, r28    ; 61
  60:    0e 94 36 00     call    0x6c    ; 0x6c <main>
  64:    0c 94 4d 00     jmp    0x9a    ; 0x9a <_exit>

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
It should show up as an eor r1, r1 but there's only one of those and it's in the CRT:
I see your point.

That said, such asm's are allowed and are supposed to generate code.

The question is what removed it?

Garbage collection works on input sections.

It did not have its own .section command,

so it have had to been removed along with an unused function.

That seems unlikely.

I think the more likely scenario is that the compiler removed it as unreachable code.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
That said, such asm's are allowed and are supposed to generate code.
How can C support the generation of code OUTSIDE a function? How could it ever possibly be accessed without a linkable entry point name to be called? Or are you suggesting it should drop "inline" between the CRT and the entry to main() or something??

 

For the latter there's clearly an existing mechanism to achieve that:

__attribute__((section(".init8"), naked)) void asm_code(void) {
    asm("ldi r24, 0x55");
}

As the "call main" is in .init9 then this would slot if just before that:

#include <avr/io.h>

__attribute__((section(".init8"), naked)) void asm_code(void) {
    asm("ldi r24, 0x55");
}

int main(void) {
    while(1) {
    }
}

yields...

00000054 <__ctors_end>:
  54:   11 24           eor     r1, r1
  56:   1f be           out     0x3f, r1        ; 63
  58:   cf e5           ldi     r28, 0x5F       ; 95
  5a:   d4 e0           ldi     r29, 0x04       ; 4
  5c:   de bf           out     0x3e, r29       ; 62
  5e:   cd bf           out     0x3d, r28       ; 61

00000060 <asm_code>:
#include <avr/io.h>

__attribute__((section(".init8"), naked)) void asm_code(void) {
    asm("ldi r24, 0x55");
  60:   85 e5           ldi     r24, 0x55       ; 85
  62:   0e 94 37 00     call    0x6e    ; 0x6e <main>
  66:   0c 94 38 00     jmp     0x70    ; 0x70 <_exit>

But, as far as I know,  this is the only way to get asm "inline" and outside the body of a "normal" function.

 

I guess the reason the compiler does not reject the existence of asm() outside a function body out right is that the following is valid syntax:

uint8_t foo asm("r18");

int main(void) {
    
}

But even so I would have thought:

asm("anything");

int main(void) {   
}

would throw some kind of "error: found asm() floating" message?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How can C support the generation of code OUTSIDE a function?

This is not C.  It is a GCC extension.

 

From https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html:

Remarks

Using extended asm (see Extended Asm) typically produces smaller, safer, and more efficient code, and in most cases it is a better solution than basic asm. However, there are two situations where only basic asm can be used:

  • Extended asm statements have to be inside a C function, so to write inline assembly language at file scope (“top-level”), outside of C functions, you must use basic asm. You can use this technique to emit assembler directives, define assembly language macros that can be invoked elsewhere in the file, or write entire functions in assembly language.
  • Functions declared with the naked attribute also require basic asm (see Function Attributes).

 

Also:

Do not expect a sequence of asm statements to remain perfectly consecutive after compilation. If certain instructions need to remain consecutive in the output, put them in a single multi-instruction asm statement. Note that GCC’s optimizers can move asm statements relative to other code, including across jumps.

 

And:

Under certain circumstances, GCC may duplicate (or remove duplicates of) your assembly code when optimizing. This can lead to unexpected duplicate symbol errors during compilation if your assembly code defines symbols or labels.

 

Perhaps the redundant clr r1 instruction was identified and deduplicated?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

At some point in this thread I stop reading, because something really strange happening with this compiler results.

First, there is a CLI (clear interrupt) at some point, without a single SEI (set interrupt) anywhere.

Second, one of the -Ox options, inserted two PUSH instructions, without POP anywhere, so, stack go down crazy through the SRAM and messes up with the RETurn address from the Call at some point.

There is no Stack setup at the beginning, even that some AVRs automatically set the Stack to the top of the RAM, that is not a rule of thumb, you need to do that.

Also, the routine at 0x60 calls 0x6C that is the supposed 1s time delay, but there is NO return instruction from that whatsoever... 

If this routine is to blink LEDs, it must be a loop, but I don't see any loop for the blinking in the disassembled code, what I see that bothers my brain is this:

 

  80:	24 e6       	ldi	r18, 0x64	; 100
  82:	3e ea       	ldi	r19, 0xAE	; 174
  84:	4e ea       	ldi	r20, 0xAE	; 174
  86:	4a 95       	dec	r20
  88:	f1 f7       	brne	.-4      	; 0x86 <main+0x1a>
  8a:	3a 95       	dec	r19
  8c:	e1 f7       	brne	.-8      	; 0x86 <main+0x1a>
  8e:	2a 95       	dec	r18
  90:	d1 f7       	brne	.-12     	; 0x86 <main+0x1a>
  92:	00 c0       	rjmp	.+0      	; 0x94 <main+0x28>
  94:	2f ef       	ldi	r18, 0xFF	; 255
  96:	25 bb       	out	0x15, r18	; 21

  98:	f3 cf       	rjmp	.-26     	; 0x80 <main+0x14>

 

The above is an abomination.   

Almost one second delay, if the core is running at 16MHz, but the rjmp instruction at 0x98 just restart the delay at 0x80 again and again.

 

Something is very strange here.  I just wonder.

Wagner Lipnharski
Orlando Florida USA

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've now marked stenrst post #8 From 2013 as the solution.

I was messin' with my makefile at that time and did not pass the -mmcu option.

Because of this the initialisation code was not linked in, but the program was, and this sometimes ran, but other times did not.

 

And then 5 years later, in #13 this thread got hijacked by mpn1989.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com