EMS-keil C51常用错误
1. LAB100.C(12): error C216: subscript on non-array or too many dimensions 原程序如下:
#include <reg51.h>
#include <intrins.h>
void delay(int);
unsigned ]={0x28,0x7e,0xa2,0x62,0x74,0x61,0x21,0x7a};
main()
{
int i,j;
P2=0xff;
)
{
P2=0x7f;
;i<;i++)
{
P0=dis_code[i];
P2=_crol_[j,];
j=P2;
delay();
}
}
}
void delay(int x)
{
int i;
;i<x;i++);
}
问题在于P2=_crol_[j,1];
应该改为P2=_crol_(j,1);
2. 从网上COPY的程序执行类似的功能,有时候如果现象没出现,或者不明显,可以调整下延迟函数。
3. 数码管的扫描显示0—7,延迟函数的延迟时间在1ms左右,是通过人眼的视觉暂留而产生的现象,如果延迟函数设置的太大,则看不到持续显示0—7的现象。
4. 用KEILC51调试程序时,出现错误提示为“unprintable character 0XA1 skipped”的问题。 输入法的问题。在程序行输入中文模式下标点符号,不会显示,但是会出现标题这样的问题。 打上//马上就能看到没有显示的标点符号。
5. *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_COMPARE?TESTLCD
说明:程序中有些函数(或片段)以前(调试过程中)从未被调用过,或者根本没有调用它的语句。这条警告信息前应该还有一条信息指示出是哪个函数导致了这一问题。只要做点简单的调整就可以。不理它也没什么大不了的。
解决方法:去掉COMPARE()函数,或利用条件编译#if …..#endif,可保留该函数并不编译。
6. LAB99.C(19): error C141: syntax error near '{', expected 'const' 程序如下:
#include<reg51.h>
#include<intrins.h>
sbit LEDP=P1^;
unsigned char counter;
main()
{
TMOD=0x01;
TH0=0x3C;
TL0=0xB0;
counter=0x0A;
EA=;
ET0=;
TR0=;
)
{};
}
void timer0_int(void) interrupt
{
TH0=0x3C;
TL0=0xB0;
counter--;
)
{
counter=0x0A;
LEDP=~LEDP;
}
}
问题在中断函数的写法上,C下面51的中断函数要这么写:
void timer0_int(void) interrupt N using M
其中的N是不同中断对应的中断号,一般单片机的书上都有说明的,M是这个中断函数在存储空间中所占的bank,一般不要和main函数的一样就可以了,而main函数的在bank0,那么针对51单片机,这个M可以为1,2,3。
7. C51编译警告“*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL”
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
SYMBOL: ?C_START
MODULE: .STARTUP.obj (?C_STARTUP)
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
SYMBOL: ?C_START
MODULE: .STARTUP.obj (?C_STARTUP)
ADDRESS: 000DH
如果你在用C51编译器出现上面的警告,并且找遍了网上也没能找出个究竟时,你是否觉得这个问题很难,难得以至于没人能回答呢?其实这个只是初学者和粗心者才会犯的错误:没把C文件添加到项目中!另外,还有可能是因为存在没有被调用的已经定义的函数。
8. *** WARNING L15: MULTIPLE CALL TO SEGMENT***
原因Warning 15向我们表明了linker发现了一个函数,这个函数不仅在main code里被调用了,而且在ISR(或者被ISR调用的函数中)被调用了。或者是被同时被多个ISR同时调用了。这样会产生一个问题,就是在此函数不是一个可重入函数,而当此函数已经在执行时它可能被另一个ISR所调用。这样就会导致结果是可变的而且很可能会导致一些参数的错误。另一个问题就是本地变量和参数所使用的内存可能被其他函数的内存覆盖。如果函数是由中断所调用的,则此函数的内存就会被使用。这会引起其它函数的内存错误。
举例来说,对于你的第一个警告,WRITE_GMVLX1_REG是会被多个root所调用。其被定义在D_GMVLX1.C或者D_GMVLX1.A51中。他不仅会被ISR(或者被ISR调用的函数)而且也会被MAIN.C中的VSYNC_INTERRUPT函数所调用。
解决办法:
(1)主程序调用该函数时禁止中断,可以在该函数被调用时用#pragma disable语句来实现禁止中断的目的。必须使用OVERLAY指令将该函数从覆盖分析中除去。
(2)复制两份该函数的代码,一份到主程序中,另一份复制到中断服务程序中。
(3)将该函数设为重入型。例如:
void myfunc(void) reentrant {
...
}
这种设置将会产生一个可重入堆栈,该堆栈被被用于存储函数值和局部变量,用这种方法时重入堆栈必须在STARTUP.A51文件中配置。这种方法消耗更多的RAM并会降低重入函数的执行速度。
9.
void delay(unsigned char i)
{
while(i--)
{;}
}
main()
{
unsigned char i,k;
)
{
i=;
delay(i);
i=;
delay(i);
k=;
}
}
编译器的意思是我那行程序i=7;没有用,怎么解决这个问题?呢实际上是被编译了的,调用函数时传递的的确是7。没有写回到 i 倒是事实,因为编译器认为后面不再用 i 了,所以就没有回写。如果你将下面的k=10改成k=i,那么就会将7写回到i,并且keil编译器不会直接使用立即数7,而用一条减1指令,从前面的8减1变成7。
10. 单片机中_crol_函数的的意思:
_crol_(a,m) 将a循环左移,步进为m
_cror_(a,n) 将a循环右移,步进为n
11.
if(temp-ret>min_value)
{
min_value=temp-ret;
min_id=i;
}
LAB06.C(72): error C193: '-': illegal op-type(s)
此处需要强制类型转换,因为上面有一定义
unsigned ]; unsigned ;
temp和ret不是同一类型数据。
12.
#include"stdafx.h"
#include"stdio.h"
#include"conio.h"
int main(int argc, char* argv[])
{
][]={ {"","","","*"},
{"","","*","*","*"},
{"","*","*","*","*","*"},
{"*","*","*","*","*","*","*"},
{"","*","*","*","*","*"},
{"","","*","*","*"},
{"","","","*"}};
int i,j;
printf("%c",a[i][j]);
;
}
error C242: 'a[][]': too many initializers
如果要使用缺省赋值,则前面的每行不能缺省赋值,只能在最后缺省,也就是你可以对前7行进行完全赋值,后两行缺省,却不能每行中缺一些,还缺行. initializer 初始化。
13. Warning 280:’i?unreferenced local variable
说明局部变量 i 在函数中未作任何的存取操作。解决方法:消除函数中 i 变量的宣告。
14. Warning 206:’Music3?missing -prototype
说明Music3( )函数未作宣告,或未作外部宣告。所以无法给其他函数调用。
解决方法:将叙述void Music3(void)写在程序的最前端作宣告;如果是其他文件的函数,则要写成extern void Music3(void),即作外部宣告。
15. Compling :C:\8051\MANN.C Error:318:can’t open file ‘beep.h?
说明在编译C:\8051\MANN.C 程序过程中由于main.c 用了指令#i nclude ‚beep.h?但却找不到所致。解决方法:编写一个beep.h 的包含档并存入到c:\8051 的工作目录中。
16.
Compling:C:\8051\LED.C
Error 237:’LedOn? already has a body
说明LedOn( )函数名称重复定义即有两个以上一样的函数名称。解决方法:修正其中的一个函数名称,使得函数名称都是独立的。
17.
***WARNING 16:UNCALLED SEGMENT,IGNORED FOR OVERLAY PROCESS
SEGMENT: ?PR?_DELAYX1MS?DELAY
说明DelayX1ms( )函数未被其它函数调用也会占用程序记忆体空间。解决方法:去掉DelayX1ms( )函数或利用条件编诿if ?.#endif,可保留该函数并不编译
18.
***WARNING 6 :XDATA SPACE MEMORY OVERLAP
FROM : 0025H
TO: 0025H
说明外部资料ROM 的0025H 重复定义地址
解决方法:外部资料ROM 的定义如下
Pdata unsigned char XFR_ADC _at_0x25
其中XFR_ADC 变量的名称0x25,请检查是否有其它的变量名称也是定义在0x25 处并修正它。
19.
WARNING 206:’DelayX1ms? missing -prototype C:\8051\INPUT.C
Error 267 :’DelayX1ms ?requires ANSI-style prototype C:\8051\INPUT.C
说明程序中有调用DelayX1ms 函数,但该函数没定义,即未编写程序内容或函数已定义但未作宣告。
解决方法:编写DelayX1ms 的内容编写完后也要作宣告或作外部宣告,可在delay.h 的包含档宣告成外部以便便其它函数调用。
20、
WARNING 1:UNRESOLVED EXTERNAL SYMBOL
SYMBOL:MUSIC3
MODULE:C:\8051\MUSIC.OBJ(MUSIC)
***WARNING 2:REFERENCE MADE TO UNRESOLVED EXTERNAL
SYMBOL:MUSIC3
MODULE:C:\8051\MUSIC.OBJ(MUSIC)
ADDRESS:0018H
说明程序中有调用MUSIC 函数,但未将该函数的含扩档C 加入到工程档Prj 作编译和连接。
解决方法:设MUSIC3 函数在MUSIC.C里,将MUSIC.C 添加到工程文件中去。
21、
ERROR 107:ADDESS SPACE OVERFLOW
SPACE: DATA
SEGMENT: _DATA_GOUP_
LENGTH: 0018H
***ERROR 118: REFERENCE MADE TO ERRONEOUS EXTERNAL
SYMBOL: VOLUME
MODULE: C:\8051\OSDM.OBJ (OSDM)
ADDRESS: 4036H
说明data 存储空间的地址范围为0~0x7f,当公用变量数目和函数里的局部变量如果存储模式设为SMALL,则局部变量先使用工作寄存器R2~R7 作暂存,当存储器不够用时,则会以data 型别的空间作暂存的个数超过0x7f 时,就会出现地址不够的现象
解决方法:将以data 型别定义的公共变量修改为idata 型别的定义。
22、ERROR L104: MULTIPLE PUBLIC DEFINITIONS
是104号错误,你头文件里的变量定义被多次调用,相当于多次定义了。(注意头文件里与主函数间容易同时调用相同的变。
分析如下:
1、从字面上的意思来看,这个警告信息说的是xdata空间的内存被覆盖了。C51对于片外变量,可以使用xdata关键字来标识,对于这些变量的操作,当然要比片内变量要慢一点,但是胜在空间比内部变量的空间要大得多,所以在大多数情况下都是使用xdata变量空间的.
那么xdata空间的内存被覆盖到底是什么意思呢,原来是C51在定义xdata区域变量的时候,可以使用关键字"_at_"来直接定义某个变量的地址,这一般是用来定义硬件地址的。这样看来,这个警告信息的意思就比较明确了,就是编译器发现两个被指定了地址的变量使用了同一个地址空间。
譬如我的错误就是定义了一个变量,其地址在0x8000,这是一个数组,长度为16,然后又定义了一个变量,其地址在0x800A,这下明白了吧,第一个变量的起始地址是0x8000,长度16,结束地址就是0x800F,正好包括了0x800A这个地址,所以导致上述的警告信息。
2、没有进行函数声明:调用没有声明的外部函数、使用位于没有声明的在调用函数候补的被调用函数 。
3、解决办法:
a、是文件没有添加到工程里。
b、可能是因为存在没有被调用的已经定义的函数。
c、不知道你有没有把Source group组下面的A51.C删掉,如果没有删,在A51.c上点右键,选择remove file " ".
d、建一个新的c文件,里面写一个空的函数,把该文件添加到project中,注意该文件不能再选generate assembler SRC file和assemble SRC file选项。重新编译工程,如果警告该函数没被调用,在主文件中调一下。
e、建一个新的c文件,把主文件中的几个函数移至该文件,把该文件添加到project中,注意该文件不能再选generate assembler SRC file和assemble SRC file选项。重新编译工程。
其他:UNRESOLVED EXTERNAL SYMBOL 说明连接的时候没有找到外部变量
extern xdata unsigned char RxPnt; 只是说明引用外部变量,并不是实际的声明。
应该在某个.c文件里有xdata unsigned char RxPnt才行。
extern中对这个变量做了声明,说这个变量将会在这个文件中用到,但并没有定义,也就是那个变量并没有真实存在,需要要某个地方定义一下。
4、出现该错误是因为Code的大小超出了系统的代码存储空间,但大多时候该错误是在物理空间足够的情况下发生,这时可以考虑keil的设置问题,如下图:

Project---->Option for target---->BL51 Locate选项卡,如上图红圈部分所示,根据自己系统的存储器分布情况,可以设置代码区间和XDATA区间。通常默认情况下,代码区间很小,所以会造成107号错误,根据需求,调大该范围即可。
5、原文见:http://hi.baidu.com/pepsi360/blog/item/66c44afbf8f53f1e6d22eba4.html。c/c++语言中有很多地方要用到extern,但是如果没有真正的了解它的意义,会给编程带来很大的麻烦,为了使大家少走弯路,特祥细的说明一下。
对于比较小的程序,一般只有一个c文件和一个头文件,全局变量我们通常会直接定义在c文件中,在程序之前加int i定义。如果要在头文件中定义有以下两种方法:用extern来声明:extern int i;这一句只是对变量i进行声明,在c文件的程序之前必须加上int i进行定义。extern int i=0;这一句声明和定义都做了。
对于大一点的程序,有很多c文件和头文件,这个时候全局变量就必须在头文件中声明(不需要初始化),然后在一个c文件中定义(该初始化的要初始化)。如果在头文件中定义,则编译的时候会出现重复定义的错误。如果只有头文件中声明就会出现没有定义有警告。
*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
SYMBOL: K
MODULE: 222.obj (222)
出现上述错误则是因为变量k重复定义,把你的头文件中的变量定义前加extern(只是变量声明不用初始化),再在某一个你要调用该变量的c文件的程序之前再定义(注意第一个调用的c文件要负责附带初始化该变量,其他调用的c文件就不需要初始化过程啦)。
最后在说明一点就是某些警告如果你不想他进入你的视线,可以在Project---->Option for target---->BL51-msic下的warmings里面填写相应错误的序号就可以了。

比如图中的16就是屏蔽警告L16的,当然这些都是你已经很了解的情况下才可以使用的,不然会给你的程序带来某些隐藏的致命打击。
EMS-keil C51常用错误的更多相关文章
- KEIL C51高级编程
第一节 绝对地址访问C51提供了三种访问绝对地址的方法: 1. 绝对宏:在程序中,用“#include”即可使用其中定义的宏来访问绝对地址,包括:CBYTE.XBYTE.PWORD.DBYTE.CWO ...
- Keil C51编译及连接技术
主要介绍Keil C51的预处理方法如宏定义.常用的预处理指令及文件包含指令,C51编译库的选择及代码优化原理,C51与汇编混合编程的方法与实现以及超过64KB空间的地址分页方法的C51实现. 教学目 ...
- keil C51 指针总结
变量就是一种在程序执行过程中其值能不断变化的量.要在程序中使用变量必须先用标识符作为变量名,并指出所用的数据类型和存储模式,这样编译系统才能为变量分配相应的存储空间.定义一个变量的格式如下: [存储种 ...
- keil c51笔记
第一章 Keil C51开发系统基本知识 第一节 系统概述 Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上.结构性.可读性. ...
- Keil C51程序调试过程
用Keil C51编写程序时,经常需要调试,如果不是经常用这个软件的话,很容易忘记这些调试步骤,现在举一个例子“验证延迟函数delay()使其延迟的时间为500ms”说明. 源程序写完后,就可以调试了 ...
- Keil C51软件的使用
进入 Keil C51 后,屏幕如下图所示.几秒钟后出现编辑界 启动Keil C51时的屏幕 进入Keil C51后的编辑界面 简单程序的调试:学习程序设计语言.学习某种程序软件,最好的方法是直接操作 ...
- KEIL C51 中嵌入汇编以及C51与A51间的相互调用
如何在 KEIL C51(v6.21) 中调用汇编函数的一个示例 有关c51调用汇编的方法已经有很多帖子讲到,但是一般只讲要点,很少有对整个过程作详细描述,对于初学者是不够的,这里笔者通过一个简单例子 ...
- Hash查找法在Keil C51中的实现
摘要:散列(hash)是一种重要的存储方法,也是一种常见的查找方法.它是指在记录的存储位置和它的关键字之间建立一个确定的对应关系.本文以射频卡门禁控制器为例,说明用射频卡卡号作为关键字,用Hash查找 ...
- Keil C51中变量的使用
引言 8051内核单片机是一种通用单片机,在国内占有较大的市场份额.在将C语言用于51内核单片机的研究方面,Keil公司做得最为成功.由于51内核单片机的存储结构的特殊性,Keil C51中变量的使用 ...
随机推荐
- 【算法与数据结构】在n个数中取第k大的数(基础篇)
(转载请注明出处:http://blog.csdn.net/buptgshengod) 题目介绍 在n个数中取第k大的数(基础篇),之所以叫基础篇是因为还有很多更高级的算法,这些 ...
- Java使用Protocol Buffers入门四步骤
Protocol Buffers(简称protobuf)是谷歌的一项技术.用于将结构化的数据序列化.反序列化.经经常使用于网络传输. 这货实际上相似于XML生成和解析.但protobuf的效率高于XM ...
- 根据IP地址获取IP的详细信息
<?php header('Content-Type:text/html; charset=utf-8'); function ip_data() { $ip = GetIP(); $url = ...
- [转] Java中的容器
在书写程序的时候,我们常常需要对大量的对象引用进行管理.为了实现有效的归类管理,我们常常将同类的引用放置在同一数据容器中. 由于数据容器中存放了我们随时可能需要使用到的对象引用,所以一般的数据容器要都 ...
- [转] weak_ptr解决shared_ptr环状引用所引起的内存泄漏
http://blog.csdn.net/liuzhi1218/article/details/6993135 循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引 ...
- c++回调编程本质
1. boost:bind获得一个函数对象,就像函数指针一样,这个行为可以作为回调 2. bosot:bind的函数对象可以保存别的对象的引用,回调对象的成员函数 3. boost:function是 ...
- CSS入门学习(转)
一.基础学习 1.何为CSS CSS是Cascading Style Sheets(层叠样式表)的简称,是一种标记语言,它不需要编译,可以直接由浏览器执行(属于浏览器解释型语 言). CSS文件也可以 ...
- CSS3 @font-face使用实例
Windows10操作系统使用实例: 1.准备好对应格式的字体库 2.方正字体使用实例 <!DOCTYPE html> <html> <head> <meta ...
- xls和xlsx
xls XLS 就是 Microsoft Excel 工作表,是一种非常常用的电子表格格式.xls文件可以使用Microsoft Excel打开,另外微软为那些没有安装Excel的用户开发了专门的 ...
- Python中小中花括号的区别
Python主要有三种数据类型:字典.列表.元组.其分别由花括号.中括号.小括号表示. 如: 字典:dic={'a':12, 'b':34} 列表:list=[1,2,3,4] 元组:tup=(1,2 ...