alanding 发表于 2022-12-21 12:03:19

Keil C51的问题

Keil C51似乎有内存分配的策略问题,表现如下(LX51加了REMOVEUNUSED):

MCU 是STC8A8K64S4A12。

data部分,假设寄存器组用了012,3空闲,同时用了位变量,这样0x18-0x1f造成一个空洞,Keil会把堆栈设定在0x18,一运行就死机,查看反汇编启动代码发现的,解决办法倒也简单,设置一个用不到的变量把空洞占住就好了。

//static unsigned char volatile data fictitious_space1 _at_ 0x08;
//static unsigned char volatile data fictitious_space2 _at_ 0x10;
static unsigned char volatile data fictitious_space3 _at_ 0x18;


xdata部分,外接的32K SRAM,起始地址0x8000,结果Keil对低地址的8K内存视而不见,只使用空洞以上的,这个不知道有什么办法能让Keil优先使用低地址。
目前的解决方法是专门学了一点VHDL用CPLD译码,把内外SRAM连成一个40K的整体。

同时发现了一个STC8A8K64S4A12的小BUG,BUS_SPEED寄存器的低3位不能置0,否则RD脚无输出,WR正常(或者记反了),最小要置为 1

zhp 发表于 2022-12-21 12:58:56

1、对于你所提到的C51内存分配策略的问题,我这边从来没有遇到过

2、外接32K的SRAM时,你程序中要怎么使用是你自己代码来决定的,Keil不会对内部的8K视而不见
比如你需要使用内部8K,那将AUXR中的EXTRAM设置为0,RAM地址设置为0~1FFFH以内,就会自动使用内部的8K,若需要使用外部,则只需要将AUXR中的EXTRAM设置为0就可以了,地址范围设置0~FFFFH都可以

3、你所提到的STC8A8K64S4A12的小BUG,我这边实际测试没问题
我测试时将BUS_SPEED设置为0,访问外部扩展RAM时,RD信号为3个时钟,WR信号为1个时钟

注意:对于相同的BUS_SPEED,RD和WR的宽度是不一样的
请参考数据手册中读写外部扩展RAM的时序图


梁工 发表于 2022-12-21 13:47:11

使用C语言,一定要抛开汇编思想,不要使用 _at_ 指定位置,反而让编译器不好分配。
KEIL C51编译器已经非常完善,很少会有BUG(全球数以百万计的用户,有问题早能发现改好)。

alanding 发表于 2022-12-21 14:41:46

刚把备份找出来重新编译了次,问题果然没了,C51现在用的是V9.55版本,我要记录下这个版本后不用考虑这个问题;外接SRAM试不了了,毕竟是前年的事,早已移交给用户。
梁工,这不是汇编思想,当时不把这块内存占住C51会把堆栈设这里,这才用的 at 指定位置.
当时BUS_SPEED置为0内存自检从没成功过,搬出示波器看到RD或者WR少一个信号,置为1后一切正常,就这么一直用下去了,没想过改变,甚至没再关注过,我们用户也不会允许整天改产品,最低要求能工作10年。

zhp 发表于 2022-12-21 15:36:43

alanding 发表于 2022-12-21 14:41
刚把备份找出来重新编译了次,问题果然没了,C51现在用的是V9.55版本,我要记录下这个版本后不用考虑这个问 ...

BUS_SPEED设置的值与外部的SRAM的时序、以及你的工作频率有关
如果你的工作频率比较慢,SRAM的时序要求又比较宽,BUS_SPEED设置为0是可以的(这个在我们的学习板上有测试通过)
正是因为每个客户的工作频率不同、使用的SRAM也不一样,没法在硬件设计时就固定下来,所以才设计了BUS_SPEED这个寄存器
页: [1]
查看完整版本: Keil C51的问题