Board logo

标题: 请教MC9S12XDP512扩展外部RAM的问题 [打印本页]

作者: iehome    时间: 2008-1-17 08:44     标题: 请教MC9S12XDP512扩展外部RAM的问题

在我设计系统中,在保留的 $008000~$0F7FFF RAM区域扩展了128K的RAM(采用CS3片选信号)。现在为了验证扩展RAM的设计是否正确,就参考了网上版主的两个贴子来对外部RAM区进行写读。
1在prm文件中包括以下内容:
SEGMENTS
...
MY_RAM = READ_WRITE 0x000800 TO 0x0207FF;
...
END


PLACEMENT
...
EXT_RAM INTO MY_RAM;
...
END

2在main.c文件中包括以下内容:
#pragma DATA_SEG __PPAGE_SEG EXT_RAM

unsigned int EXT_SEG00;
unsigned int EXT_SEG01;

#pragma DATA_SEG DEFAULT

void main(void)
{

MODE = 0xA0; // Normal expanded mode
MMCCTL0 = 0x08; // Enable CS3:according to $008000~$0F7FFF

unsigned int temp;
temp=1;
unsigned int *pt1;
pt1 = & EXT_SEG00;
temp = *pt1;

EnableInterrupts;
for(;;) {} // Wait forever
}
但是在编译的时候,就是怎么也通不过,在prm文件中的定义就有错误,还有 MODE 、MMCCTL0 寄存器的设置要去掉才行。这是什么原因呢?扩展的128K RAM是否需要分页呢?又是如何定义的?

另外,我在CW4.6中“选Compiler for HC12的Options,在Code Generation里勾上PPAGE Regiseter is used for paging,然后在下面的参数栏里填上RUNTIME”,编译器提示设置不正确的,这又是什么原因啊?
还有,版主说的“外部地址最好选用内部空间没有占用的地址,这样就不会发生冲突。如果要用BDM进行编程或调试,MCU的管脚电平配置成正常单片模式即可。当程序运行后再写寄存器,使MCU进入扩展模式。”我对后一句话不是很理解。因为,我准备在系统设计中将MC9S12XDP512的运行模式定死,就是Normal expanded mode,而不再使用拨码开关。(根据MC9S12XDP512的datasheet,其BDM在每一种模式下都是active的。)这有矛盾吗?我的设计方法可行不?


作者: strongchen    时间: 2008-1-17 11:41

如果你要通过PPAGE来访问扩展地址,就要把扩展地址放到FLASH的窗口区,即8000~BFFF窗口区。你可以参考CodeWarrior本身的PRM文件来定义。
作者: strongchen    时间: 2008-1-17 11:46

当对扩展模式进行仿真和调试时,一般需要先将MCU配置成正常单片模式,然后再通过写MODE寄存器的方式进入扩展模式。在正常使用时,则可以直接将MCU配置成扩展模式。此时再写一次MODE寄存器也不会有问题。
作者: iehome    时间: 2008-1-17 16:10

谢谢版主的回复!
那如果我扩展就是在保留的 $008000~$0F7FFF RAM区域,我怎么来访问外部RAM呢?上面我对PRM文件的定义有错误吗?
还有,在正常使用时,我把MODC,MODB,MODA管脚通过拨码开关设为101,发现程序无法正常烧写,提示FF7A有错误,这是什么原因啊?(PRM文件还是单片模式时的PRM文件)

作者: iehome    时间: 2008-1-22 16:58

目前,我在1在prm文件中定义如下:
SEGMENTS
...
/* Here we use logical addressing */

RAM_D8 = READ_WRITE 0xD81000 TO 0xD81FFF;
RAM_D9 = READ_WRITE 0xD91000 TO 0xD91FFF;
RAM_DA = READ_WRITE 0xDA1000 TO 0xDA1FFF;
RAM_DB = READ_WRITE 0xDB1000 TO 0xDB1FFF;
RAM_DC = READ_WRITE 0xDC1000 TO 0xDC1FFF;
RAM_DD = READ_WRITE 0xDD1000 TO 0xDD1FFF;
RAM_DE = READ_WRITE 0xDE1000 TO 0xDE1FFF;
RAM_DF = READ_WRITE 0xDF1000 TO 0xDF1FFF;

RAM_E0 = READ_WRITE 0xE01000 TO 0xE01FFF;
RAM_E1 = READ_WRITE 0xE11000 TO 0xE11FFF;
RAM_E2 = READ_WRITE 0xE21000 TO 0xE21FFF;
RAM_E3 = READ_WRITE 0xE31000 TO 0xE31FFF;
RAM_E4 = READ_WRITE 0xE41000 TO 0xE41FFF;
RAM_E5 = READ_WRITE 0xE51000 TO 0xE51FFF;
RAM_E6 = READ_WRITE 0xE61000 TO 0xE61FFF;
RAM_E7 = READ_WRITE 0xE71000 TO 0xE71FFF;
RAM_E8 = READ_WRITE 0xE81000 TO 0xE81FFF;
RAM_E9 = READ_WRITE 0xE91000 TO 0xE91FFF;
RAM_EA = READ_WRITE 0xEA1000 TO 0xEA1FFF;
RAM_EB = READ_WRITE 0xEB1000 TO 0xEB1FFF;
RAM_EC = READ_WRITE 0xEC1000 TO 0xEC1FFF;
RAM_ED = READ_WRITE 0xED1000 TO 0xED1FFF;
RAM_EE = READ_WRITE 0xEE1000 TO 0xEE1FFF;
RAM_EF = READ_WRITE 0xEF1000 TO 0xEF1FFF;

RAM_F0 = READ_WRITE 0xF01000 TO 0xF01FFF;
RAM_F1 = READ_WRITE 0xF11000 TO 0xF11FFF;
RAM_F2 = READ_WRITE 0xF21000 TO 0xF21FFF;
RAM_F3 = READ_WRITE 0xF31000 TO 0xF31FFF;
RAM_F4 = READ_WRITE 0xF41000 TO 0xF41FFF;
RAM_F5 = READ_WRITE 0xF51000 TO 0xF51FFF;
RAM_F6 = READ_WRITE 0xF61000 TO 0xF61FFF;
RAM_F7 = READ_WRITE 0xF71000 TO 0xF71FFF;


RAM_F8 = READ_WRITE 0xF81000 TO 0xF81FFF;
RAM_F9 = READ_WRITE 0xF91000 TO 0xF91FFF;
RAM_FA = READ_WRITE 0xFA1000 TO 0xFA1FFF;
RAM_FB = READ_WRITE 0xFB1000 TO 0xFB1FFF;
RAM_FC = READ_WRITE 0xFC1000 TO 0xFC1FFF;
RAM_FD = READ_WRITE 0xFD1000 TO 0xFD1FFF;
/* RAM_FE = READ_WRITE 0xFE1000 TO 0xFE1FFF; intentionally not defined: equivalent to RAM: 0x2000..0x2FFF */
/* RAM_FF = READ_WRITE 0xFF1000 TO 0xFF1FFF; intentionally not defined: equivalent to RAM: 0x3000..0x3FFF */

...
END


PLACEMENT
...
PAGED_RAM INTO /* when using banked addressing for variable data, make sure to specif the option -D__FAR_DATA on the compiler command line */

RAM_D8, RAM_D9, RAM_DA, RAM_DB, RAM_DC, RAM_DD, RAM_DE, RAM_DF,
RAM_E0, RAM_E1, RAM_E2, RAM_E3, RAM_E4, RAM_E5, RAM_E6, RAM_E7,
RAM_E8, RAM_E9, RAM_EA, RAM_EB, RAM_EC, RAM_ED, RAM_EE, RAM_EF,
RAM_F0, RAM_F1, RAM_F2, RAM_F3, RAM_F4, RAM_F5, RAM_F6, RAM_F7,

RAM_F8, RAM_F9, RAM_FA, RAM_FB, RAM_FC, RAM_FD;
...
END

在主程序中定义如下:
#pragma DATA_SEG _RPAGE_SEG PAGED_RAM

unsigned char pagedRamVariable = 0xAA;

#pragma DATA_SEG DEFAULT

unsigned char * pointerToVariable;
void main(void)
{
//write a value
pagedRamVariable=0xBB;


//Initialize pointer to point at address of pagedRamVariable
pointerToVariable=&pagedRamVariable;

//write another value via use of pointer
*pointerToVariable=0x20;

for(;;)
{ }

}
但是,在仿真模式下,pagedRamVariable数据却是在2100‘L的地址,即默认的RAM区(RAM_FE),而不是指定的RAM_D8区。请问一下,这是什么地方出错了呢?
作者: iehome    时间: 2008-1-23 08:56

现在通过global addressing的方式可以访问外部RAM了,不过好像要在正常单片模式烧写程序,烧写好以后,再通过拨码切换到正常扩展模式。是不是扩展方式下,只有这种操作方式啊?版主,“在正常使用时,则可以直接将MCU配置成扩展模式。”这一句话怎么理解呢?
还有,当采用logical addressing的方式怎样才能正确访问外部RAM呢?上面的现象是怎么回事?
作者: strongchen    时间: 2008-1-23 10:32

要了解的是S12X本身的地址总线还是16位的,如果要访问扩展地址区,必须通过分页窗口或全局地址的形式。
作者: iehome    时间: 2008-1-23 11:04

版主,上面我就是通过分页窗口的形式去做的啊。
#pragma DATA_SEG _RPAGE_SEG PAGED_RAM

unsigned char pagedRamVariable = 0xAA;

#pragma DATA_SEG DEFAULT
但现象是:pagedRamVariable数据跑到了2100‘L的地址,即默认的RAM区,而不是指定的PAGED_RAM区(1000‘L开始的地址)???困惑中。
作者: iehome    时间: 2008-1-23 14:29

问题已解决啦!
原来的#pragma DATA_SEG _RPAGE_SEG PAGED_RAM
应改为:
#pragma DATA_SEG __RPAGE_SEG PAGED
那__RPAGE_SEG的一小杠短了,真是想不到的错误啊!

[此贴子已经被作者于2008-1-23 14:29:09编辑过]






欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0