Search code examples
carduinomicrocontroller

simple arduino code without using avr headers in avr-libc


I have this simple code

That I am trying to compile for arduino microcontroller and without using avr headers. I just defined all macros in my source program file

but my gcc-avr says

led.c:15:8: error: lvalue required as left operand of assignment
   DDRB |= 0B100000; // PORTB5 1010
        ^

Now I can expect this error on some cpu that io area is not virtual memory space of this process but I am running my code on mocrocontroller that must have execution bit. how to get rid of this message and compile it and able to run on arduino

But the gcc-avr throws error that

#define F_CPU 16000000
#define BLINK_DELAY_MS 5000

#include <util/delay.h>

#define __SFR_OFFSET 0x20
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
#define DDRB    _SFR_IO8(0x04)
#define PORTB   _SFR_IO8(0x05)
int main (void)
{
  // Arduino digital pin 13 (pin 5 of PORTB) for output
  DDRB |= 0B100000; // PORTB5 1010
  
  while(1) {
    // turn LED on
    PORTB |= 0B100000; // PORTB5
   // _delay_ms(BLINK_DELAY_MS);
   int x=0;
   
    while(x<25)
    {
        x++;
    }
    x=0;
    // turn LED off
    PORTB &= ~ 0B100000; // PORTB5
    //hello
    while(x<25)
    {
        x++;
    }
    //_delay_ms(BLINK_DELAY_MS);
  }
}

Solution

  • The problems are the macros, you are defining the register as an integer, not as an address to an integer.

    DDRB expands to 0x04 + 0x20 so you end up with code like (0x04 + 0x20) |= 0B100000;. You should be able to fix this with a cast and then de-reference:

    #define _SFR_IO8(io_addr) ( *(volatile uint8_t*) ((io_addr) + __SFR_OFFSET) )
    

    For details see How to access a hardware register from firmware?

    Please also note that macros starting with double underscore __ are reserved for the compiler, so we should never use that or we might end up with naming collisions.