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的,当然这些都是你已经很了解的情况下才可以使用的,不然会给你的程序带来某些隐藏的致命打击。