利用数组的方式可以选择的访问寄存器

[复制链接]
986|34
手机看帖
扫描二维码
随时随地手机跟帖
langgq|  楼主 | 2019-2-15 12:22 | 显示全部楼层 |阅读模式
在8051的片内RAM中的高128字节,有两个地址空间,一个是SFR寄存器空间,只可直接访问,而另一个空间是存储空间只可间接访问。
在C语言中,寄存器这样定义sfr ACC=0xXX;这样sfr就相当于一个数据结构,如同int float一样。可是它不可以(sfr)(0xEF)这样的数据类型转换,也不可以定义数组:
sfr PCON[2]={0xEE,0xF3};这样也是出错的。
我的问题是,我想利用数组的方式可以选择的访问寄存器,如同,给寄存器地址,0xE1,0xE2,0xE3;赋值。如同数组一样赋值,EX[3]={0xE1,0xE2,0xE3};
for(i=0;i<3;I++)
EX=0x12; //EX就代表了那三个寄存器,是给他们分别赋值。
langgq|  楼主 | 2019-2-15 12:27 | 显示全部楼层
各位,我应该怎么实现在C语言中实现这中给寄存器赋值的方法呢。

使用特权

评论回复
lium| | 2019-2-15 12:29 | 显示全部楼层
不可以用数组,只能用直接寻址访问

使用特权

评论回复
guoyt| | 2019-2-15 12:32 | 显示全部楼层
是啊,用数组就成了间接寻址方式了

使用特权

评论回复
zhuhuis| | 2019-2-15 12:36 | 显示全部楼层
谢谢楼上的回复,我的意思是使用如同数组的方式来实现,根据i的不同,给不同的寄存器赋值。
否则的话,只能使用switch 语句了。
如:        switch(i)
           {
          case        0:  PCA0CPM0  = (INT8U)(0x00);  break;                                
          case        1:        PCA0CPM1  = (INT8U)(0x00);  break;
          case        2:        PCA0CPM2  = (INT8U)(0x00);  break;
          case        3:        PCA0CPM3  = (INT8U)(0x00);  break;
          case        4:        PCA0CPM4  = (INT8U)(0x00);  break;
           case        5:        PCA0CPM5  = (INT8U)(0x00);  break;  
           default  :         break;

         } //其中的PCA0CPM1等都是用sfr定义的寄存器。
这样的方式实现对寄存器选择性赋值的话,程序编译出来会很大的。
如果有一种如同数组赋值方式的方法的话,那就精简多了。就如同这样一个函数:

void fuzhi(int8u i)
{
      PCA0CPM(i) =(INT8U)(0x00);  
}
如同以上形式的话就简单多了。
我说的是如同给数组赋值的方式,这种简洁的方法,并不是局限于数组的形式。

使用特权

评论回复
yufe| | 2019-2-15 12:41 | 显示全部楼层

都说了只能直接寻址
你知道什么是直接寻址吗

使用特权

评论回复
llia| | 2019-2-15 12:45 | 显示全部楼层

LZ也真的敢创新!!!
sfr是C51中特有的关键字,还是按它的规定用吧!!!!

使用特权

评论回复
langgq|  楼主 | 2019-2-15 12:49 | 显示全部楼层
我知道只可以直接寻址的,这一点我在1楼已经说的很明白了。我说的意思是,用一种简洁的方式,有选择性的给不同的寄存器赋值,而不是想switch那样只能列举所有的出来,那样程序会大很多的。

使用特权

评论回复
langgq|  楼主 | 2019-2-15 12:51 | 显示全部楼层

sfr在它的作用上来看,它如同int, float数据类型一样,sfr是定义寄存器类型的,但是它不可以如下使用:
(1) 定义数组 sfr PCON[2] = {0xE1,0xE2};
(2) 强制类型转换 (sfr)(0xE1);

使用特权

评论回复
wangzsa| | 2019-2-15 12:54 | 显示全部楼层

先不说寻址方式的问题,你这样写,编译器通过得了吗?
就算通得过,你再去看看访问数组的汇编是怎么样的?  特别是你说的用for循环去访问!
编译器是先把数组的头地址放到r0中,然后用偏移量间接去寻址。

使用特权

评论回复
zhuww| | 2019-2-15 12:57 | 显示全部楼层

LZ要先搞清楚,什么是51的直接寻址

使用特权

评论回复
guoyt| | 2019-2-15 13:04 | 显示全部楼层
直接寻址意味着每条指令中<语句>必须要有SFR的名字

使用特权

评论回复
langgq|  楼主 | 2019-2-15 13:07 | 显示全部楼层
我想用一种简洁的方式,有选择性的给不同的寄存器赋值

使用特权

评论回复
langgq|  楼主 | 2019-2-15 13:10 | 显示全部楼层
而且对sfr定义的寄存器的处理是由编译器来处理的。当对寄存器操作时,c编译后的汇编指令就配处理成相应的直接寻址赋值方式。

使用特权

评论回复
langgq|  楼主 | 2019-2-15 13:14 | 显示全部楼层
我的想法是,怎么样使编译器对如同数组形式的变量或常量对其编译为直接寻址方式呢。

使用特权

评论回复
wangpe| | 2019-2-15 13:17 | 显示全部楼层
知道数组乍定位元素的吗?

使用特权

评论回复
liuzaiy| | 2019-2-15 13:20 | 显示全部楼层

大怎么了  不好么?

谁告诉你不好了.

玩汇编 的目的原来仅仅是为了让代码更小?

使用特权

评论回复
zhanglli| | 2019-2-15 13:24 | 显示全部楼层
问题还是在直接寻址上,一条指令必须有明确的操作数,就算使用类似数组的方式来实现,根据程序处理的逻辑,还是必须使用间接寻址的。

使用特权

评论回复
lium| | 2019-2-15 13:28 | 显示全部楼层
要是这类问题再统一编址的arm空间上就好实现了。寄存器是有自己唯一的地址,与别内存,flash空间没有重叠。

使用特权

评论回复
langgq|  楼主 | 2019-2-15 13:31 | 显示全部楼层
用汇编指令别写也不可能实现用数组方式解决switch case这类的问题。就如同,我们可以POP AR0,但我们不能POP R0一样,指令是需要确切的地址的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

932

主题

8762

帖子

1

粉丝