Superfire 发表于 2022-5-13 15:27:12

C51使用PDATA出现异常,求助

本帖最后由 Superfire 于 2022-5-13 15:33 编辑


前辈们好,近些日子用到一个HX711,驱动程序用的下面的:
Reference Driver(C)
//-------------------------------------------------------------------
sbit ADDO = P2^0;
sbit ADSK = P2^1;
unsigned long ReadCount(void){
unsigned long Count;
unsigned char i;
ADDO=1;
ADSK=0;
Count=0;
while(ADDO);
for (i=0;i<24;i++){
ADSK=1;
Count=Count<<1;
ADSK=0;
if(ADDO) Count++;
}
ADSK=1;
Count=Count^0x800000;
ADSK=0;
return(Count);
}

使用正常,没问题。。
但过些时间,增加一些别的东西,有个情况,keil编译告知data空间不足。
看网上教程,将图中所标memory model改成了pdata,改完之后,上面这个段程序就不能正常运行了,返回值持续为0。回头用这个demo跑程序,改成pdata也复现同样的情况。
将unsigned long类型改成unsigned int,demo程序可以运行,但不足24位,数据丢一些。。所以是跟数据类型有关系吗?
看坛友介绍,pdata是扩展的低256字节,和一些介绍https://www.amobbs.com/forum.php?mod=viewthread&tid=4842069&highlight=pdata;
看完不知道这些意味着什么,是否我这次的问题与其中相关。
请坛友们指点一下,非常感谢!

wudicgi 发表于 2022-5-13 16:07:17

Device 选的是 Intel 80/87C52, 有没有问题?

tang_qianfeng 发表于 2022-5-13 16:12:43

Pdata应该要先赋值P2的吧

szdy 发表于 2022-5-13 19:52:12

pdata是分页寻址片外ram,你板上有吗?若有地址你是否赋值正确?

vuo50z 发表于 2022-5-16 10:01:23

一直没搞懂这个pdata有什么用,还要手动对P2赋值换页,难道是为了不同进程的内存空间切换?

Superfire 发表于 2022-5-16 10:30:24

szdy 发表于 2022-5-13 19:52
pdata是分页寻址片外ram,你板上有吗?若有地址你是否赋值正确?
(引用自4楼)

没有外置的,片内有集成256b的RAM;;地址赋值应如何操作,这点不太明白

Superfire 发表于 2022-5-16 10:34:11

vuo50z 发表于 2022-5-16 10:01
一直没搞懂这个pdata有什么用,还要手动对P2赋值换页,难道是为了不同进程的内存空间切换? ...
(引用自5楼)

P2赋值是指的什么

vuo50z 发表于 2022-5-16 13:00:39

Superfire 发表于 2022-5-16 10:30
没有外置的,片内有集成256b的RAM;;地址赋值应如何操作,这点不太明白
(引用自6楼)

还是要了解下51的体系结构。51的地址空间比较复杂,内部ram,rom和外部ram有各自的存取方式,其中内部ram还包含了寄存器和bit区。

lyl1070 发表于 2022-5-16 16:57:02

本帖最后由 lyl1070 于 2022-5-16 17:13 编辑

memory model选项是指,将默认的变量存放到哪个位置(除了指定位置的变量外,没有指定的都放在这个位置)。
举例:

uchar idata i,flag; // 定义到idata区域。
uchar data i,flag; // 定义到data区域。
uchar xdata i,flag; // 定义到xdata区域。

uchar pdata i,flag; // 定义到pdata区域。

uchar i,flag; // 定义到memory model选项中的区域。

注:

data:固定指前⾯0x00-0x7f的128个RAM,可以⽤acc直接读写的,速度最快,⽣成的代码也最⼩。
idata:固定指前⾯0x00-0xff的256个RAM,其中前128和data的128完全相同,只是因为访问的⽅式不同。
idata是⽤类似C中的指针⽅式访问的。汇编中的语句为:mox ACC,@Rx.(不重要的补充:c中idata做指针式的访问效果很好)。

另外程序堆栈只能存放在idata中,而且是80H~0xFF之间,所以程序必须留出足够的idata空间,而不能超过128个。

xdata:外部扩展RAM,⼀般指外部0x0000-0xffff空间,⽤DPTR访问。

pdata:外部扩展RAM的低256个字节,地址出现在A0-A7的上时读写,⽤movx ACC,@Rx读写。

这个⽐较特殊。
有些说pdata是xdata的某一页,页数由某个寄存器控制。没用过,不好说。
所以楼主的程序使用pdata的前提是你的MCU要有xdata,还要指定页。

有例子:

MCU支持传统的访问外部RAM方法,可以使用MOVXA,@Ri或MOVX@Ri,A;来访问外部低256字节RAM;
使用MOVX A,@DPTR或MOVX@DPTR,A来访问外部480字节RAM。

用户也能用XPAGE寄存器来访问外部RAM,仅用MOVX A,@Ri或MOVX@Ri,A指令即可。
用户能用XPAGE来表示高于256字节的RAM地址。

chenerbox2 发表于 2022-5-16 17:47:37

我理解 PDATA就是XDATA 的前256个字节, 因为访问不需要高位地址,比用DPTR访问快一点

芯片自带的XDATA 应该不要设置页,直接用就是了, 现在的片子总感觉没必要分这么细了, 麻烦,全用XDATA算了,

arm 发表于 2022-5-16 17:52:32

lyl1070 发表于 2022-5-16 16:57
memory model选项是指,将默认的变量存放到哪个位置(除了指定位置的变量外,没有指定的都放在这个位置)。 ...
(引用自9楼)

另外程序堆栈只能存放在idata中,而且是80H~0xFF之间,所以程序必须留出足够的idata空间,而不能超过128个

这个你错了,SP在idata内都可以,不是必须80H~0FF范围

lyl1070 发表于 2022-5-16 18:01:01

arm 发表于 2022-5-16 17:52
另外程序堆栈只能存放在idata中,而且是80H~0xFF之间,所以程序必须留出足够的idata空间,而不能超过128 ...
(引用自11楼)

这个倒是没注意过,我一般都是64或100个。

#define                SP_LEN                        100                                                        // 定义SP堆栈指针长度
uchar        idata SP_ADDR        _at_ (0xFF-SP_LEN);                // 定义SP堆栈位置,预留到idata区的未端

szdy 发表于 2022-5-16 18:54:10

Superfire 发表于 2022-5-16 10:30
没有外置的,片内有集成256b的RAM;;地址赋值应如何操作,这点不太明白
(引用自6楼)

一般而言PDATA是51系列用扩展外设芯片内部的RAM,如8155,8255等IO扩展芯片内部的RAM,如果是51那芯片自身内部的PDATA那少见,你要看看芯片手册地址该如何定义

Superfire 发表于 2022-5-16 22:26:14

szdy 发表于 2022-5-16 18:54
一般而言PDATA是51系列用扩展外设芯片内部的RAM,如8155,8255等IO扩展芯片内部的RAM,如果是51那芯片自身内 ...
(引用自13楼)

查到的RC系列是256+256字节,内部确实是扩展了256字节,
MOVX @DPTR /xdata 地址大于100H才访问外部
MOVX @Ri /pdata 只访问内部扩展RAM
我目前的理解是:用pdata声明的变量,或者使用memory model选项(选择pdata),都会放在内部扩展的256字节上;
那么是不是可以理解 256+256则没有额外xdata呢?或者说,就此单片机来说来说,xdata空间=扩展256字节,也就是pdata区。
如9楼所指,程序应该是可以执行的;
那么回到demo程序里,为什么就异常了捏

vuo50z 发表于 2022-5-17 10:04:26

arm 发表于 2022-5-16 17:52
另外程序堆栈只能存放在idata中,而且是80H~0xFF之间,所以程序必须留出足够的idata空间,而不能超过128 ...
(引用自11楼)

keil编译器可以模拟一个软堆栈(其他编译器应该也可以),放在xdata用dptr访问。
当年移植过usos ii,所有函数都要声明成可重入的,堆栈放在idata根本没法跑。

TangCS 发表于 2022-7-12 18:03:10

xdata pdata都是访问外部的内存,现在一般都是集成在芯片内部。pdata看指令会比xdata快一点,其次pdata是访问低256字节,xdata可以访问64KB
页: [1]
查看完整版本: C51使用PDATA出现异常,求助