打印

KEIL 又一个大难题~ 你是否遇到过~

[复制链接]
14254|30
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dudongdao|  楼主 | 2009-7-29 22:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请教一个KEIL的问题.问了好多人,没有人给出解决办法,请各位隐士大侠们指点迷津~~~
     用STC12C5404~~  程序量有4K,EEP区域有2K~~  由于程序量不够,想把一些表格数据放到EEP中,本来想用_at_来指定绝对地址,但是指定了绝对地址就不能给绝对地址赋初始值,所以想C中嵌入汇编来解决,遇到下面问题:
   程序区地址:0-1024*4  4K
   EPP区地址:0X2E00--0X2F00  2K
   用嵌入汇编指令
   #pragma  asm
   org 0X2E00
   DB 00H,02H.........
   #pragma  endasm
   这样写后编译没问题,但看编译出来的HEX文件,程序都放到0X2E00之后了
   我想把程序放前4K,数据表格放0X2E00之后~~  有没有好办法,问了STC的
   老姚,他说这个芯片是我设计的,但我只会汇编~~  不会C~~ 
   请高手指点一下~~
    

相关帖子

沙发
dudongdao|  楼主 | 2009-7-29 22:56 | 只看该作者

顶起来

STC烧写软件是判断HEX文件的地址~~  有些地址他判断为EEP数据,就直接烧写的EEP区域,所以我要定义表格到那个数据去。  

使用特权

评论回复
板凳
dudongdao|  楼主 | 2009-7-30 09:17 | 只看该作者

使用特权

评论回复
地板
dudongdao|  楼主 | 2009-7-30 12:23 | 只看该作者

顶起来

使用特权

评论回复
5
呆板书生| | 2009-7-30 14:06 | 只看该作者

at的问题

at只是在编译器中指定了地址,但要真正解决这个问题,在于link命令,

在keil的 link命令中,有指定某个模块的开始地址的参数,我曾经用于,不过比较麻烦,我不知道为什么嵌入式的编译器都这样,包括PIC 的c 语言,用了at命令后,还是要另外设定

使用特权

评论回复
6
dudongdao|  楼主 | 2009-7-30 15:18 | 只看该作者

说说吧,高手~

    麻烦就麻烦了~~   讲解一下~~  如何设置~~   就等高手出招了~~~

使用特权

评论回复
7
dudongdao|  楼主 | 2009-7-30 21:41 | 只看该作者

使用特权

评论回复
8
冷漠| | 2009-7-30 21:42 | 只看该作者

这还不简单。

第一种方法:把你的常数段用数组写:

const char  tab[]={ 0x00,0x02,.........};

这样,常数段必然编译在代码段之后。

代码段前缀是PR,常数段前缀是CO,代码段由startup.a51确定定位从0000H开始,常数段tab你自己由CODE命令愿意定在哪都行。(甚至PR段中间。)

第2种:把常数写成另一个模块TAB.A51(或TAB.C) ,这样得到2个  .OBJ ,定位TAB.obj在2E00H,总该知道方法?

使用特权

评论回复
9
dudongdao|  楼主 | 2009-7-30 21:51 | 只看该作者

试过了,还有疑问

定义为CONST是到DATA区域的,不是CODE区域。
能不能给个例子~~  指定地址到0X2E00去~~  指定一个数据就可以~~
给个例子~~  谢谢~~

使用特权

评论回复
10
冷漠| | 2009-7-30 22:13 | 只看该作者

呵呵

const char code tab[]={ 0x00,0x02,.........};


BL51 ....OBJ  CODE(?co?tab(0x2e00))  

大意如此,请查书。实际是写到BL51 Locate标签页中。

使用特权

评论回复
11
Lenglx| | 2009-7-30 22:45 | 只看该作者

用汇编是可以的

不管是嵌入汇编,或者干脆使用纯汇编文件
但不能用org
用CSEG 

CSEG AT 22E0H
DB 4,.....

使用特权

评论回复
12
dudongdao|  楼主 | 2009-7-31 00:19 | 只看该作者

编译出现错误

不可能用全汇编,程序是C的~~
按你的方法改之后出现如下编译错误

*** ERROR L121: IMPROPER FIXUP
    MODULE:  .outputmain.obj (MAIN)
    SEGMENT: ?PR?SYSTIMERRUN?MAIN
    OFFSET:  000CH

使用特权

评论回复
13
dudongdao|  楼主 | 2009-7-31 00:50 | 只看该作者

改了插入汇编的位置,可以编译通过,但还有个问题

插入语句
#pragma  asm
CSEG AT 2E00H
DB 4

生成的HEX
 002DF0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
 002E00   04 E5 52 64 01 70 30 F5 52 75 53 01 E5 3F D3 94 
 002E10   00 40 06 D5 3F 03 E4 F5 3E 05 56 E5 56 C3 94 64 
 002E20   40 15 E4 F5 56 75 54 01 05 57 E5 57 D3 94 3C 40 
 002E30   06 E4 F5 57 75 55 01 22 

2E00位置数据对,但是2E00后面又放了一段程序代码,导致烧进芯片工作不正常,死机。

还有什么高招吗,在线等啊,谢谢~~~

使用特权

评论回复
14
冷漠| | 2009-7-31 08:40 | 只看该作者

弄清连接/定位器的工作方式。

1、定义常数段
char  code  tab[]={ 0x00,0x02,.........};  //注意定义在CODE段

2、在BL51 Locate标签页的code项填写?CO?你的模块名(0x2e00)。重新编译即可。

   在模拟调试窗口观察汇编码,C:002e00: 地址处已经是tab常数数组各元素了。

使用特权

评论回复
15
elife| | 2009-7-31 08:48 | 只看该作者

刚才试了个,把所有的需在EEPROM的变量定义在一个单独的C文件

中,比如test.c中,然后在项目的option for target 中找到BL51 locate,在CODE 输入框中输入 ?CO?TEST(0X2E00).编译就行了。其实就是10楼说的方法。如果不想定义在一个文件中,每个包含code常数的文件都要在输入命令行中,用‘,’号隔开。

使用特权

评论回复
16
呆板书生| | 2009-7-31 08:57 | 只看该作者

应该这样

如果在 C51 中有一部分程序需要直接定位到内部程序存储器中的某个特定地址单元例如在MCU 的内部存储器有两块地址不连续的FLASH 存储器一个为0000H-7FFFH 的BLOCK0存储块,另一个为地址在0E000H-0FFFFH 的BLOCK1 存储块在

C51 语言中使用At直接地址定位命令是不行的。

如果想在0FC00H 的BLOCK1 存储块中存储一部分子程序BLOCK1_ASM.A51 和在0F800H 的BLOCK1 存储块中存储C_BLOCK1.C 中的程序应该如何操作呢?

1. 首先不能在ASM_BLOCK1.A51 子程序中使用”ORG 0F000H”的定位命令,因为在与C_BLOCK1.C51 连接过程中会出错.

2. 将ASM_BLOCK1.A51 文件中的所有汇编语言子程序定位到0XFC00 程序地址之后在连接选项"KEIL C51/PROJECT/OPTIONS FOR TARGET/BL51 LOCATE/CODE"栏中加入再定位段

--BLOCK1 的定位命令:"BLOCK1(0XFC00)" 注: BLOCK1(0XFC00)--其中的BLOCK1 是在文件中的SEGMENT定义的段名

3. 将C_BLOCK1.C 文件中的所有C51 函数定位到0XF800 程序地址之后

a) 在连接选项"KEIL C51/PROJECT/OPTIONS FOR TARGET/BL51 LOCATE/CODE"中加入模块定位命令:"*C_BLOCK1(0XF800)"

b) *C_BLOCK1(0XF800)---使C_BLOCK1.C 文件中所有的函数都连续定位到0XF800 后面的区域

c) ?PR?_DELAYMS?C_BLOCK1(0XF800)---表示只将C_BLOCK1.C 文件中的DELAYMS 函数定位到0XF800 后面的区域。

在C51 V7.00之后,这些设置都可以用鼠标选择,我不知道如何上传图片,具体操作请自己摸索一下。其实不是很难,

使用特权

评论回复
17
呆板书生| | 2009-7-31 09:09 | 只看该作者

上图片

使用特权

评论回复
18
dudongdao|  楼主 | 2009-7-31 09:26 | 只看该作者

恢复冷漠大侠

定义数组:
U8 code tab[]=

 0xC6,0xA2,0x0E,0xC8,0x00,0x0B,     
 0xC6,0xA2,0x17,0xC8,0x00,0x08,     
 0xC6,0xA2,0x10,0xC8,0x00,0x50,     
 0xC6,0x22,0x2F,0xC8,0x00,0x9A, 
 0xFF
};

使用特权

评论回复
19
冷漠| | 2009-7-31 09:34 | 只看该作者

17楼能否教教咱如何截图?

呆板书生的图截取的挺漂亮的。教教咱们菜鸟。需要专门软件?

有个师弟教咱用屏幕拷贝,还没试过。

使用特权

评论回复
20
dudongdao|  楼主 | 2009-7-31 09:55 | 只看该作者

谢谢大家 试验结果如下

冷漠大侠:
定义表格如下:
放入单独C文件中
U8 code tab[]=

 0xC6,0xA2,0x0E,0xC8,0x00,0x0B,     
 0xC6,0xA2,0x17,0xC8,0x00,0x08,     
 0xC6,0xA2,0x10,0xC8,0x00,0x50,     
 0xC6,0x22,0x2F,0xC8,0x00,0x9A, 
 0xFF
};
编译器插入命令:
?CO?tab(0X2E00)

编译结果:
assembling .outputmain.src...
linking...
*** ERROR L110: CANNOT FIND SEGMENT
    SEGMENT: ?CO?TAB
Program Size: data=96.1 xdata=0 code=2762
Target not created


回复elife大侠
定义表格如下:
放入单独C文件中 asm.c
U8 code tab[]=

 0xC6,0xA2,0x0E,0xC8,0x00,0x0B,     
 0xC6,0xA2,0x17,0xC8,0x00,0x08,     
 0xC6,0xA2,0x10,0xC8,0x00,0x50,     
 0xC6,0x22,0x2F,0xC8,0x00,0x9A, 
 0xFF
};
加入命令:?CO?asm(0X2E00)
编译结果:
assembling .outputmain.src...
linking...
*** ERROR L110: CANNOT FIND SEGMENT
    SEGMENT: ?CO?ASM
Program Size: data=96.1 xdata=0 code=2762
Target not created



回复书生大侠:
定义表格如下:
放入单独C文件中 asm.c
U8 code tab[]=

 0xC6,0xA2,0x0E,0xC8,0x00,0x0B,     
 0xC6,0xA2,0x17,0xC8,0x00,0x08,     
 0xC6,0xA2,0x10,0xC8,0x00,0x50,     
 0xC6,0x22,0x2F,0xC8,0x00,0x9A, 
 0xFF
};
加入命令:*asm(0X2E00)
编译结果:

assembling .outputmain.src...
linking...
*** ERROR L130: NO MATCHING SEGMENT FOR WILDCARD SEGMENT NAME
    SEGMENT: *ASM
Program Size: data=96.1 xdata=0 code=2762
Target not created


上面是我试验的结果,文件名字,表格名字大小写都试过了。
是不是我哪里设置还不正确。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

90

主题

413

帖子

1

粉丝