0

I wrote this simple blinking light program for Arduino Micro:

void main() {
  *((volatile unsigned char *)(0x27)) = 128;
  volatile unsigned char x = 0;
  volatile unsigned char y = 0;
  volatile unsigned char z = 0;
start:
  *((volatile unsigned char *)(0x28)) = 0;
  for (x = 0; x < 255; x++) {
    for (y = 0; y < 255; y++) {
      for (z = 0; z < 255; z++) {
      }
    }
  }
  *((volatile unsigned char *)(0x28)) = 128;
  for (x = 0; x < 255; x++) {
    for (y = 0; y < 255; y++) {
      for (z = 0; z < 255; z++) {
      }
    }
  }
  goto start;
}

I built the program and sent it to Arduino:

avr-gcc -c -Os -Wall -mmcu=atmega32u4 test.c -o test.o
avr-gcc -Os -Wl,--gc-sections -mmcu=atmega32u4 -o test.elf test.o -lm
avr-objcopy -O ihex -R .eeprom test.elf test.hex
avrdude -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D -Uflash:w:test.hex:i

The program works.

Then I tried - just for fun and learning - to store loops' control variables in SRAM, at addresses that I chose. According to page 20 of this PDF document, SRAM addresses start at 255, so addresses 300, 301 and 302 are in SRAM. So I modified the program this way:

void main() {
  *((volatile unsigned char *)(0x27)) = 128;
  volatile unsigned char * x = (unsigned char *) 300;
  volatile unsigned char * y = (unsigned char *) 301;
  volatile unsigned char * z = (unsigned char *) 302;
start:
  *((volatile unsigned char *)(0x28)) = 0;
  for (*x = 0; *x < 255; *x++) {
    for (*y = 0; *y < 255; *y++) {
      for (*z = 0; *z < 255; *z++) {
      }
    }
  }
  *((volatile unsigned char *)(0x28)) = 128;
  for (*x = 0; *x < 255; *x++) {
    for (*y = 0; *y < 255; *y++) {
      for (*z = 0; *z < 255; *z++) {
      }
    }
  }
  goto start;
}

I tried to build and send it to Arduino with the same command as before, but now it doesn't seem to work - the LED is on, but doesn't blink.

Other sources (for instance this page) say that SRAM addresses start at 0x60, so I changed the program to use addresses 97, 98 and 99, but the program still does not work.

Did I do something wrong?

user983447
  • 1,598
  • 4
  • 19
  • 36
  • 3
    The unconventional way you're writing your code is making things super difficult. You should include the header file `avr/io.h` so you can get definitions of SFRs (e.g. for blinking the LED). You should include `avr/delay.h` so you can get accurate delay loop routines. You should not try to write to arbitrary places in RAM; just declare normal C variables in your program and read and write to them. The compiler will know how to put those variables into RAM. and how to read and write from them (this last tip might solve your immediate problem). – David Grayson Feb 17 '18 at 20:36
  • 1
    Once you learn how to write AVR programs the normal way, then you can look at the assembly listing from the compiler to understand what's going on under the hood and invent new ways to write the code. – David Grayson Feb 17 '18 at 20:37

1 Answers1

0

The problem was that I wrote "*x++" but I should have written "(*x)++". When I fixed it, the program works. Here is how it looks like when fixed:

void main() {
  *((volatile unsigned char *)(0x27)) = 128;
  volatile unsigned char * x = (unsigned char *) 301;
  volatile unsigned char * y = (unsigned char *) 302;
  volatile unsigned char * z = (unsigned char *) 303;
start:
  *((volatile unsigned char *)(0x28)) = 0;
  for (*x = 0; *x < 255; (*x)++) {
  for (*y = 0; *y < 255; (*y)++) {
  for (*z = 0; *z < 255; (*z)++) {
  }
  }
  }
  *((volatile unsigned char *)(0x28)) = 128;
  for (*x = 0; *x < 255; (*x)++) {
  for (*y = 0; *y < 255; (*y)++) {
  for (*z = 0; *z < 255; (*z)++) {
  }
  }
  }
  goto start;
}
user983447
  • 1,598
  • 4
  • 19
  • 36