_SFR_IO8(0x04) 在做什么?自动录像机

What does _SFR_IO8(0x04) is doing? AVR

我正在尝试在汇编中编写一个程序来在汇编中切换 Arduino MEGA2560 的板载 LED。

为此,我只需将引脚(在本例中为 13,即 PB7)的方向指示为输出,然后将该引脚设置为高电平或低电平。

我了解到有两个寄存器与此问题相关。一个是端口的方向寄存器 (DDRB) 和引脚状态寄存器 (PORTB)

所以我试图了解这些寄存器的编号或地址,以便我可以在汇编中为它们赋值。我进入了定义这些常量的 C++ 库 (iomxx0.h) 例如 DDRB 定义如下:

#define DDRB    _SFR_IO8(0x04)
#define DDB7    7
#define DDB6    6
#define DDB5    5
#define DDB4    4
#define DDB3    3
#define DDB2    2
#define DDB1    1
#define DDB0    0

我很好奇寄存器的地址是不是0x04? 如果是这样,_SFR_IO8() 在做什么?

那是一个宏。有兴趣的可以在headers中找到它的定义:

#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)

#ifndef __SFR_OFFSET
/* Define as 0 before including this file for compatibility with old asm
   sources that don't subtract __SFR_OFFSET from symbolic I/O addresses.  */
#  if __AVR_ARCH__ >= 100
#    define __SFR_OFFSET 0x00
#  else
#    define __SFR_OFFSET 0x20
#  endif
#endif

此外,

#define _SFR_IO_ADDR(sfr) ((sfr) - __SFR_OFFSET)
#define _SFR_MEM_ADDR(sfr) (sfr)

在 AVR 上,您可以使用普通内存 read/write 或 in/out 指令访问 SFR。但是,地址取决于访问方法。这些宏的存在就是为了帮助你。在您的情况下,0x04 是 IO 地址,0x24 是内存映射地址。