标题: C51单片机在主程序里怎么访问特殊功能寄存器或者说怎么更改先前SFR定义的地址? [打印本页]

作者: 旧言四    时间: 2022-4-27 14:17
标题: C51单片机在主程序里怎么访问特殊功能寄存器或者说怎么更改先前SFR定义的地址?
环境 :KielC51
MCU :IAP15W4K61S4
应用环境:利用两组IO端口(P1^6\P1^5 和 P4^1\P4^2)模拟IIC总线和显示驱动芯片1648A及外部EEPROM通信,现在用的两组独立的代码实现IIC协议。现在设想改为两个端口共用一组代码以减少代码量,之前想过使用改变指针指向来重定向端口,但是在主程序里发现通过SFR定义的地址无法通过指针获取。
请问有好的解决方案吗。

作者: munuc_w    时间: 2022-4-27 16:10
IIC设备是有地址的,放在一组总线上就可以了,用地址区分设备。
作者: 旧言四    时间: 2022-4-27 16:31
munuc_w 发表于 2022-4-27 16:10
IIC设备是有地址的,放在一组总线上就可以了,用地址区分设备。

感谢回复  确实使用一条总线确实可以实现目的 但是因为在结构上也是两个IIC外设单独挂载的 所以暂时不能用这种方法。这边首选还是设想一种方案以软件来实现外设端口的跳转,了解到51的SFR地址区域只能采用直接寻址,是不是代表着没有办法在主程序中以指针或者中间值替换的方式改变SFR关键字的定义地址呢
作者: yzwzfyz    时间: 2022-4-27 17:37
51系统单片机中的特殊寄存器的地址是:80-FFH
而高端RAM的地址也是:80-FFH
这两个地址是相同的。51为了能区分它们,在指令系统上做了如下的规定:
直接寻址(访问)对应的是特殊寄存器。
间接寻址(访问)对应的是高端RAM。
明白这一点就不难理解了。
你用指针访问80H,而80H即表示特殊寄存器的P0口,也表示高端RAM中的80H。现在知道你访问的是哪一个了吧。
要读通CPU手册,这些手册上都有。
作者: Hephaestus    时间: 2022-4-27 17:42
纯c51语言是无法实现你需要的功能,只能用汇编写函数,用c语言调用这个函数。
作者: 旧言四    时间: 2022-4-27 17:43
yzwzfyz 发表于 2022-4-27 17:37
51系统单片机中的特殊寄存器的地址是:80-FFH
而高端RAM的地址也是:80-FFH
这两个地址是相同的。51为了 ...

确实如此

1651052485(1).png (171.45 KB, 下载次数: 33)

1651052485(1).png

作者: lkc8210    时间: 2022-4-27 17:53
IAP15W4K61S4有61k ROM
就那一点点的代码量CV十次都绰绰有余
作者: Y_G_G    时间: 2022-4-27 21:15
7#已经回复过了
如果不是代码空间已经不够用了,实在不理解为什么要减少代码量?C+V它不香吗?
说不定整半天,代码量反而更多了
再说,当初设计的时候就应该先看一下IIC的从机地址,如果不是一样的地址,那就两根线足够了
作者: 188610329    时间: 2022-4-27 21:57
旧言四 发表于 2022-4-27 16:31
感谢回复  确实使用一条总线确实可以实现目的 但是因为在结构上也是两个IIC外设单独挂载的 所以暂时不能 ...

说实话, STC15 系列没有硬件 IIC, 换句话说,你只能通过软件模拟来 操作IIC, 也就是说不可能在后台读写IIC器件,必须前台读写的话,同一之间你只能访问一个IIC器件,因此,两个IIC器件,分别用两个套IO来操控的意义何在? 感觉是给自己增加工作量啊……
作者: 旧言四    时间: 2022-4-28 09:10
Y_G_G 发表于 2022-4-27 21:15
7#已经回复过了
如果不是代码空间已经不够用了,实在不理解为什么要减少代码量?C+V它不香吗?
说不定整半天 ...

好巧不巧的是  硬件IIC地址都是0XA0 外部EEPROM采用的是SOT-23-5的封装也没有办法更改从机地址
作者: 旧言四    时间: 2022-4-28 09:12
188610329 发表于 2022-4-27 21:57
说实话, STC15 系列没有硬件 IIC, 换句话说,你只能通过软件模拟来 操作IIC, 也就是说不可能在后台读写II ...

给自己挖了个大坑
作者: 旧言四    时间: 2022-4-28 09:14
Hephaestus 发表于 2022-4-27 17:42
纯c51语言是无法实现你需要的功能,只能用汇编写函数,用c语言调用这个函数。

感谢回复  值得参考的建议
作者: lkc8210    时间: 2022-4-28 13:32
其实又不用全代码CV
只需要加个全局变量来選擇用个腳就可以了

if(IIC_Sel)//0=IIC1, 1=IIC2
SDA1 = 1;
else
SDA2 =1;
作者: 旧言四    时间: 2022-4-28 14:17
lkc8210 发表于 2022-4-28 13:32
其实又不用全代码CV
只需要加个全局变量来選擇用个腳就可以了

感谢回复  这样的话确实是比较省时间  




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1