在 avr-libc 中不使用 avr headers 的简单 arduino 代码

simple arduino code without using avr headers in avr-libc

我有这个简单的代码

我正在尝试为 arduino 微控制器编译而不使用 avr headers。我刚刚在我的源程序文件中定义了所有宏

但是我的gcc-avr说

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

现在我可以预料到某些 cpu 上会出现此错误,即 io 区域不是此进程的虚拟内存 space,但我 运行 在必须执行的 mocrocontroller 上安装我的代码少量。如何摆脱此消息并编译它并能够 运行 在 arduino

但是 gcc-avr 抛出错误

#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);
  }
}

问题出在宏上,您将寄存器定义为整数,而不是整数的地址。

DDRB 扩展为 0x04 + 0x20 所以你最终得到像 (0x04 + 0x20) |= 0B100000; 这样的代码。您应该可以通过强制转换然后 de-reference:

来解决这个问题
#define _SFR_IO8(io_addr) ( *(volatile uint8_t*) ((io_addr) + __SFR_OFFSET) )

详情见How to access a hardware register from firmware?

另请注意,以双下划线 __ 开头的宏是为编译器保留的,因此我们永远不应使用它,否则我们可能会以命名冲突告终。