找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4952|回复: 21
收起左侧

STC单片机使用XDATA变量出问题,有高手帮忙看一下

  [复制链接]
ID:419909 发表于 2021-10-21 16:28 | 显示全部楼层 |阅读模式
用的是STC 的8G2K64S4,先说一下目前状况,我以前一般做些小东西。用不了太多变量。一直是用Keil 默认模式。即所有变量使用 DATA的。后面因为产品需要。变量需要用到XDATA时,才选PDATA或者XDATA模式。但是这两种模式都非常容易出问题。经常是打印结果不正确。或者乱码。好像这些变量的值会相互串扰一样。这种情况发生在我目前使用的好几个型号了。比如15W4K。如果全部变量用DATA就没问题,但是这样的话。变量不够用。解决不了问题,

下面图片就是目前遇到的情况:
比如这个tem[]数组。目前放在函数内,那么这个功能函数可以正常。但是另一个函数的变量却出问题。
假如把tem[]放到头件内。变量公共变量,那么问题又来了。这个函数显示不正常。但是另一个函数却又能正常了。
真是头大。有试过把这个变量的类型改为DATA或者XDATA。都不行。总有一个函数出错。
这个问题已经折磨我2天了。问一下有没有遇到过相同问题的黑友。

系统设置。PDATA

系统设置。PDATA

TEM数组

TEM数组
回复

使用道具 举报

ID:57657 发表于 2021-10-21 18:11 | 显示全部楼层
Keil5退回4试试,不同版本编译出来的大小都不一样。
回复

使用道具 举报

ID:94031 发表于 2021-10-21 18:34 | 显示全部楼层
应该是优化级别问题,不是使用XDATA变量出问题。
回复

使用道具 举报

ID:624769 发表于 2021-10-21 19:01 | 显示全部楼层
设置里, Memory 选Small in DATA  不要选PDATA 和 XDATA
代码里声明的时候,手动标注  pdata xdata 即可
不然编译会把所有声明变量的时候, 没有 标DATA 的 编译成 PDATA或者XDATA,而你代码里没有声明 unsigned char data 这个习惯的吧?所以Memory Model  就不要动,固定small
回复

使用道具 举报

ID:419909 发表于 2021-10-21 19:18 | 显示全部楼层
188610329 发表于 2021-10-21 19:01
设置里, Memory 选Small in DATA  不要选PDATA 和 XDATA
代码里声明的时候,手动标注  pdata xdata 即可
...

感谢回复,Small in DATA模式也是一样的。而且在Small in DATA模式下。手工标注XDATA变量更容易出问题。特别是用在函数传参数的时候。
回复

使用道具 举报

ID:419909 发表于 2021-10-21 19:19 | 显示全部楼层
xuyaqi 发表于 2021-10-21 18:34
应该是优化级别问题,不是使用XDATA变量出问题。

目前优化级别是8级,系统默认值。我迟点试试更低一些级的。
回复

使用道具 举报

ID:624769 发表于 2021-10-21 19:34 | 显示全部楼层
wfqxgw 发表于 2021-10-21 19:18
感谢回复,Small in DATA模式也是一样的。而且在Small in DATA模式下。手工标注XDATA变量更容易出问题。 ...

你代码里那个 bit idata 是什么情况? bit的话,只能是DATA 虽然 IDATA分布 0~ff 其中包含了BIT的0x20~0x2F但是,在汇编角度 DATA 和 IDATA属于两个分类, bit 只能隶属于 DATA的BITADDRESS, 而不能隶属于 IDATA
回复

使用道具 举报

ID:419909 发表于 2021-10-21 19:46 | 显示全部楼层
188610329 发表于 2021-10-21 19:34
你代码里那个 bit idata 是什么情况? bit的话,只能是DATA 虽然 IDATA分布 0~ff 其中包含了BIT的0x20~0x ...

感谢指正。我这边写错。那应该是bit bdata 最好。之所以用idata,我以为是这个是位寻址的。其实主要还是想省内存。经常跟这些小容易单下机抠内存。希望各个变量都能达到最大化使用效率。。
一般经常用到的对读速度要求快的,我用DATA和PDATA。普通的就用XDATA.
回复

使用道具 举报

ID:624769 发表于 2021-10-21 20:47 | 显示全部楼层
wfqxgw 发表于 2021-10-21 19:46
感谢指正。我这边写错。那应该是bit bdata 最好。之所以用idata,我以为是这个是位寻址的。其实主要还是 ...

其实,STC单片机,你启用双DPTR数据指针功能的话,XDATA的效率比PDATA高。因为PDATA的关键Ri寄存器可能会被其他程序占用,而你程序设计的好的话,可以把一路DPTR指针给你XDATA专用。那么不需要反复赋值,还能定义自增自减,不管代码量还是执行速度都要比PDATA高。
回复

使用道具 举报

ID:419909 发表于 2021-10-21 21:38 | 显示全部楼层
188610329 发表于 2021-10-21 20:47
其实,STC单片机,你启用双DPTR数据指针功能的话,XDATA的效率比PDATA高。因为PDATA的关键Ri寄存器可能会 ...

这个我还不太清楚。没试过。按以前的话。明显感觉XDATA很慢的。频繁读取写的话。刷新率一下总体至少50%。PDATA相对没什么变化。至少感觉不到太多。
另外。XDATA问题还是解决不了。用了idata和DATA做为变量都不行。刚刚用了一个将错就错方案。之前不是感觉这些变量内容有串扰吗?现在我折中一个方案。把这个数组位置增加多一位。tem[16]改为tem[17],居然解决了。是不是完全没问题还不知道。至少目前各个功能正常。先说一下。
回复

使用道具 举报

ID:401564 发表于 2021-10-21 22:41 | 显示全部楼层
系统设置。PDATA,这个不变
把tem 数组的PDATA不要了
直接 unsigned char tem[16]
试一下
回复

使用道具 举报

ID:90212 发表于 2021-10-21 22:42 | 显示全部楼层
你这个问题跟我前两天发的“stc15单片机串口通信的诡异问题”似乎有关联,你有兴趣可以下载附件测试下
回复

使用道具 举报

ID:624769 发表于 2021-10-21 23:25 | 显示全部楼层
wfqxgw 发表于 2021-10-21 21:38
这个我还不太清楚。没试过。按以前的话。明显感觉XDATA很慢的。频繁读取写的话。刷新率一下总体至少50%。 ...

看到你设置里,单片机选的STC15W408AS, 但是,你说你单片机的型号是8G2K64S4,所以最好你重新选一下,然后把On-chipROM,和On_chipXRAM都打个勾试试。虽然,型号选择应该关系不大,但是由于寄存器策略有不少变化,可能会在编译时转汇编的过程对PDATA调用有一定影响。毕竟PDATA本来就比较特殊,调用方式每家都不一样,STC是规定最开始的256字节,WCH的话,是通过每256字节的分页方式,可以整个XRAM都用PDATA调用,所以不排除型号没选对,编译器就罢工的可能。
回复

使用道具 举报

ID:419909 发表于 2021-10-22 07:50 | 显示全部楼层
Y_G_G 发表于 2021-10-21 22:41
系统设置。PDATA,这个不变
把tem 数组的PDATA不要了
直接 unsigned char tem[16]

试过了的。在variables in PDATA模式下。不加修饰,系统是按XDATA定义的。我也试过手工加unsigned char data tem[16],问题一样的。这些变量在内存里面估计是有位置共用。但是在退出函数时。不能及时清除导致在装载另一个函数时那个内容还在。Startup51.不知道是不是要改一个这个文件,
回复

使用道具 举报

ID:419909 发表于 2021-10-22 08:17 | 显示全部楼层
188610329 发表于 2021-10-21 23:25
看到你设置里,单片机选的STC15W408AS, 但是,你说你单片机的型号是8G2K64S4,所以最好你重新选一下,然后 ...

那个是对于仿真才用到。编译器不影响的。也有试过勾选所有的选项了。我觉得应该是内存管理堆栈那里设置问题。也百度了比较久了。问题还没不知道是哪里。虽然目前问题暂时能解决。但是不知道原因的话。后面还会出现的。所以。如果能找到根源。就最好。
回复

使用道具 举报

ID:65956 发表于 2021-10-22 08:27 | 显示全部楼层
我用了很多项目,都不曾有这个问题,有时候XDATA用了很多也不曾如你所说,不用在KEIL特别设置,都用默认就可以了
回复

使用道具 举报

ID:419909 发表于 2021-10-22 09:00 | 显示全部楼层
aking991 发表于 2021-10-22 08:27
我用了很多项目,都不曾有这个问题,有时候XDATA用了很多也不曾如你所说,不用在KEIL特别设置,都用默认就 ...

不知道你是不是全部都用XDATA。这样速度觉得很慢。有试过混合用吗。DATA和XDATA变量混用。
回复

使用道具 举报

ID:298123 发表于 2021-10-22 11:07 | 显示全部楼层
加上static 定义。 编译器会优化,共享变量导致
回复

使用道具 举报

ID:47286 发表于 2021-10-22 12:27 | 显示全部楼层
我说不出多少理论 就是实际的经验 从STC11系到8系都没啥问题 供你参考

51hei截图_20211022121542.png


1. 只能选DATA或者XDATA STC貌似不支持PDATA 我试过uchar pdata x 也会出问题 只能用到idata 个人看法是data是低128 idata是高128 然后就是xdata

2. 选存储模式=DATA 变量要用XDATA需要声明 反之选存储模式=xdata又要把变量放在基本内存时需要声明data或者idata

3. 某些型号必须勾选 使用内部XDATA 才能使用 大部分不需要 不勾选基本上等同于存储模式=DATA 看编译后的内存使用 没有成功开启xdata会报内存溢出

4. 使用xdata 相同优化等级下代码量会增加不少 如果程序空间有限 要考虑这点

5. xdata变量是否可用和优化等级没什么关系
回复

使用道具 举报

ID:419909 发表于 2021-10-22 13:34 | 显示全部楼层
dzbj 发表于 2021-10-22 12:27
我说不出多少理论 就是实际的经验 从STC11系到8系都没啥问题 供你参考

好的。谢谢。我按这个设置试试。
回复

使用道具 举报

ID:419909 发表于 2021-10-25 09:58 | 显示全部楼层
188610329 发表于 2021-10-21 20:47
其实,STC单片机,你启用双DPTR数据指针功能的话,XDATA的效率比PDATA高。因为PDATA的关键Ri寄存器可能会 ...

觉得还是回复一下。方便后面其它人需要。经测试。目前8G2K支持DPTR。所以选了DPTR这个选项之后。速度确实快多了。接近原来DATA变量速度。谢谢你的提醒。
回复

使用道具 举报

ID:883242 发表于 2022-1-4 21:18 | 显示全部楼层
DATA不够用应该优先选用IDATA,然后才是PDATA,如果还不够用最后才是XDATA。

DATA是直接寻址,只有120字节,高128字节直接寻址是SFR,间接寻址才是RAM。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表