在 iom16.h中定义了 PORTA如下:
#define PORTA _SFR_IO8(0x1B)
接着在sfr_defs.h中定义了_SFR_IO8()如下:
#if _SFR_ASM_COMPAT
......
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
#define _SFR_IO16(io_addr) ((io_addr) + __SFR_OFFSET)
......
#else /* !_SFR_ASM_COMPAT */
......
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
#define _SFR_IO16(io_addr) _MMIO_WORD((io_addr) + __SFR_OFFSET)
......
#endif /* !_SFR_ASM_COMPAT */
这个定义表示:
如果编译器( _SFR_ASM_COMPAT等于1)可以直接使用汇编、那么像 PORTA这样的变量,就是一个地址值。
此时、__SFR_OFFSET是IO寄存器的基地址,其值等于0x00,所以PORTA展开如下:
#define PORTA _SFR_IO8(0x1B)
= ((io_addr) + __SFR_OFFSET)
= ((0x1B) + 0x00)
= 0x1B
在汇编中操作 PORTA时,就是直接操作 PORTA的地址:
否则、如果只能使用C语言,那么操作 PORTA这样的变量,就是一个指针操作的过程。
此时、 PORTA的定义展开如下:
#define PORTA _SFR_IO8(0x1B)
= _MMIO_BYTE((io_addr) + __SFR_OFFSET)
_MMIO_BYTE()的定义如下:
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
这就是用指针的方式去操作一个内存地址,此时 __SFR_OFFSET等于 0x20。
到此、 PORTA的定义进一步展开如下:
#define PORTA _SFR_IO8(0x1B)
= _MMIO_BYTE((io_addr) + __SFR_OFFSET)
= (*(volatile uint8_t *)((io_addr) + __SFR_OFFSET))
= (*(volatile uint8_t *)((0x1B) + __SFR_OFFSET))
= (*(volatile uint8_t *)(0x3B))
__SFR_OFFSET是IO寄存器的基地址,0x1B是PORTA在寄存器文件中的偏移量,加在一起就是PORTA的真实的物理地址(端口地址)。
所以我们对PORTA赋值的时候,就是将数值写入上面这个地址处的寄存器中。
参考avr-libc的介绍:http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr__notes.html
-------------------------------------------------------------------------------------------------------------------------------------
因此、我们可以将PORTA重命名如下:
uint8_t *LED = (uint8_t *)(&PORTA);
然后就可以直接对 LED进行操作,来点亮 LED:
*LED = 0x55;
如果以后更换了 LED的 IO口,只需要修改 LED这个变量的定义即可。
这样对 代码的移植是很有好处的。
也可以进一步打包成这样来隐藏指针操作符:
#define LED (*(volatile uint8_t *)(&PORTA))
最后、如果可以不用#define的定义来隐藏指针操作符就更好了,因为#define定义的部分阅读起来不方便
<还在继续...>
|<----question-001
上一篇:B001-Atmega16-带电复位后不清0的.noinit变量
下一篇:B001-Atmega16-汇编-地址空间分配
推荐阅读最新更新时间:2024-11-11 13:36
推荐帖子
- 自耦式BoostDC/DC变换
- 本帖最后由jameswangsynnex于2015-3-320:00编辑自耦式BoostDC/DC变换
- lorant 移动便携
- 【WEBENCH DIY】晒:基于WEBENCH的11V-18V转5V/2A的降压稳压电路设计
- 基于WEBENCH的11V-18V转5V/2A的降压稳压电路设计设计目标:设计并制作一个11-18V转5V/2A的BUCK电路设计工具:TI公司的WEBENCH(完成电路的在线设计和仿真)芯片选用:1.TPS5430DDA2.LM2596DDPAK(-ADJ)使用WEBENCH设计流程1.进入TI官网主页2.找到WEBENCH®Designer右
- sunduoze 模拟与混合信号
- 又送出2个MAXIM气象站,大家猜猜是谁?
- 随着活动的不断进行,越来越多的朋友完成了自己的应急灯设计。所以也对完成特别优秀的朋友小小的表彰一下下:还有一个气象站,希望还未做完的朋友继续加油哦!又送出2个MAXIM气象站,大家猜猜是谁?恭喜恭喜哈哈!~恭喜!!~~来了,报道了恭喜了。。班竹,下次有活动要大声说哦。。。嘿嘿。。。呵呵,是不是你对论坛还不够关注哟!回复5楼shilaike的帖子谢谢eeworld网站,谢谢SOSO,谢谢灰太狼!谢谢网友!谢谢琳子小姐姐!我感动的流
- EEWORLD社区 DIY/开源硬件专区
- F28335,CCS5.5+Controlsuite,求助下各位大神
- 各位好,首次发帖,激动万分。我们常用的是CCS3.3,芯片主要是F240,F2812等,现在在单位领导的果断决策下升级到了CCS5.5,芯片升级到了F28335,安装完5.5及Controlsuite后,眼前一亮,很是高大上,但自己也迷茫了,很感兴趣,但也无从下手,希望在这里能得到大神们的指点。问题1:Controlsuite中PDF资料的查阅必须得联网下载吗?单位电脑没有联网的,或者是我安装操作有问题?毕竟安装完已经好多个G了,不能脱机查看吗?问题2:有没有类似某些单片机的
- liuyue11a 微控制器 MCU
- 详细介绍MSP430开发工具及其特性
- 目前公司在MSP430开发工具方面主要有仿真器、编程器、各类学习板、转接板、适配器等。一:仿真器、编程器IAR和JTAG无法连接,是怎么回事?这是客户问的问题,在论坛中也很常见,FAE也有在问。我们就从这个问题开始讲解吧。MSP430无论是仿真还是烧写程序,一般可以通过:JTAG、SBW、BSL接口进行。1、JTAG是利用边界扫描技术,在430内部有逻辑接口给JTAG使用,内部有若干个寄存器连接到了430内部数据地址总线上,所以可以访问到430的所有资源,包括全地址FLASH、RAM及各
- fish001 微控制器 MCU
- FPGA设计小技巧
- FPGA设计小技巧mark一下,感谢上传!
- 至芯科技FPGA大牛 FPGA/CPLD
设计资源 培训 开发板 精华推荐
- LTC1704 的典型应用 - 550kHz 同步开关稳压器控制器加上线性稳压器控制器
- DC2290A-E,使用 LTC2385-18、18 位、5Msps 高速 SAR ADC 的演示板
- DI-24 - 30W DC-DC 转换器
- EV-ADF4360-6EB1Z,用于 ADF4360-6 集成 PLL 和 VCO 频率合成器的评估板
- 使用 Infineon Technologies AG 的 OM8501SC 的参考设计
- 工业用 1.8V DC 至 DC 单路输出电源
- A6260高亮度LED电流调节器低电压工作的典型应用
- 超低功耗WiFi和BLE的STM32 Nucleo扩展板
- ZSR330GTA 3.3 伏正电流调节器的典型应用
- LT3663IMS8E-5、具有隔离式 3.3V 输出的 5V 降压型稳压器的典型应用