标签归档:RAM

C51扩展外部RAM释放P2口

51单片机经常要使用一些外部器件,有些器件内部有寄存器,一般都把这些寄存器当做外部RAM读写。以IC卡读卡芯片RC500为例,这个芯片有D0-D7共8个数据线,接在51的P0口,D0-D7既做地址线也做数据线。RC500的NWR、NRD、ALE与51单片机的WR、RD、ALE相连。RC500内部寄存器地址范围是00-0XFF。此时如果把RC500的片选CS接在P2.7,那么要读RC500内部地址0X34的值,可以用*0X7F34读得。向0X34写入value可以用*0x7F34=value来实现。

这样编译后查看汇编语言可以看到读写RC500采用的是MOVX A,@DPTR命令,也就是说在读写器件寄存器时,P0口发送寄存器低地址0X00-0XFF,P2口发送高地址0X7F。在单片机I/O口紧张的情况下,这种用法P2口除了扩展其它外部RAM外,就不能做其它用途了。比如不能接按键扫描。因为每次读写RC500寄存器都会改变P2口的电平。按键扫描I/O口电平肯定就不对了。

那么如何释放P2口?51读写外部RAM还有一条指令MOVX A,@R0,这条指令选择外部RAM时,只输出8位地址到P0口,不影响P2口。还以RC500为例。读写寄存器可以如下处理:

#define ReadIO(x) (*(uchar volatile pdata *)(x))

#define WriteIO(x,rc500data) ((*(uchar volatile pdata *)(x)) = rc500data)

这条语句的关键是pdata。采用这种方法编译后汇编语句就是MOVX A,@R0。这样P2口就可以用做其它用途了。不过这种方式下,RC500的片选要单独用一条语句来实现。不像MOVX A,@DPTR执行时,已经执行了片选动作。