c - AVR I/O 宏定义如何工作以允许访问寄存器?
问题描述
我正在查看 ATmega2560 寄存器映射 ( iom2560.h
) 的标头,其中包含所有寄存器的定义。例如:
#define PINA _SFR_IO8(0X00)
//Macro definition:
#define _SFR_IO8(io_addr) ((io_addr) + 0X20)
所以 PINA 是一个 8 位十六进制值,对应 8 位单片机寄存器的地址。当我编写代码时,只需键入以下代码即可更改寄存器内的值:
PINA |= (1 << 3); // Setting the third bit.
这是一个问题:为什么我可以_SFR_IO8(0X00)
通过将值分配给 PINA 来写入寄存器值(“由他的地址指向”)?不是指向寄存器的地址吗?编译器是如何工作的?
非常感谢您提前
解决方案
简短的回答 - 隐藏在 Atmel 包含的标头中的是一组宏,它们创建指向寄存器位置的指针。以下是该过程的简要概述:
您的 Makefile 定义要使用的设备,然后将定义传递给编译器。
DEVICE = atmega2560
...
-D__$(DEVICE)__
然后包含 io.h,它会根据您的设备自动包含必要的标头:
// In main source file
#include <io.h>
// In io.h
#include <avr/sfr_defs.h>
// ...
#elif defined (__AVR_ATmega2560__)
# include <avr/iom2560.h>
// In sfr_defs.h
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
#define __SFR_OFFSET 0x20
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
// In iom2560.h
#include <avr/iomxx0_1.h>
// Other device specific definitions
// Om iomxx0_1.h
#define PINA _SFR_IO8(0X00)
// Other device family shared definitions
所以如果你展开所有这些,你得到的是一个指向寄存器地址的易失性指针。当您在代码中使用 PINA 时,预编译器会将其替换为所有扩展宏:
PINA
_SFR_IO8(0X00)
_MMIO_BYTE((0X00) + __SFR_OFFSET)
(*(volatile uint8_t *)((0X00) + 0x20))
它指定 PINA 是指向 0x20 的易失性 8 位内存地址的指针。然后,每当访问该地址时,内部芯片架构就会将该地址映射到适当的外设寄存器。
推荐阅读
- c# - 交叉绑定复选框 - isChecked #1 -> isEnabled #2
- c - 我的终端只打印 main 的第一个输出
- r - rmarkdown data.table 编译后绘图不匹配
- string - 在 IDL 中连接字符串和整数时出现错误的空格
- c# - 异步方法在android后台服务xamarin中不起作用
- javascript - 更改重点元素的 ng-model
- python - 如何在子进程中使用 sshkey
- node.js - 使用 Bluebird 在 typescript 中引发编译错误
- c# - Xamarin C# 无法将 c# 类转换为 Android.content.context
- asp.net - 如何在 Web API 中执行 Action Method 之前调用特定函数?