KEIL51调试时一些的错误总结
Keil C51错误及其警告大全

໕ᐺࡇᇙቧᇦ本章列出了编程中可能遇到的致命错误语法错误和警告信息每节包括一个信息的主要说明和消除错误或警告条件可采取的措施致命错误致命错误立即终止编译这些错误通常是命令行指定的无效选项的结果当编译器不能访问一个特定的源包含文件时也产生致命错误致命错误信息采用下面的格式C51 FATAL-ERROR –ACTION<current action>LINE:<line in which the error is detected>ERROR:<corresponding error message> C51 TERMIANTED.C51 FATAL-ERROR –ACTION<current action>FILE:<file in which the error is detected>ERROR:<corresponding error message> C51 TERMIANTED.下面说明Action和Error中可能的内容ActionsALLOCATING MEMORY编译器不能分配足够的存储区来编译指定的源文件CREATING LIST-FILE / OBJECT-FILE / WORKFILE编译器不能建立列表文件OBJ文件或工作文件这个错误的出现可能是磁盘满或写保护或文件已存在和只读GENERATING INTERMEDIATE CODE源文件包含的一个函数太大不能被编译器编译成虚拟代码尝试把函数分小或重新编译OPENING INPUT-FILE编译器不能发现或打开所选的源或包含文件PARSING INVOKE-/#PRAGMA-LINE当在命令行检测到参数计算或在一个#pragma中检测到参数计算就产生这样的错误PARSING SOURCE-FILE/ANALYZING DECLARATIONS源文件包含太多的外部参考减少源文件访问的外部变量和函数的数目WRITING TO FILE当写入列表文件OBJ文件或工作文件时遇到的错误Errors‘(‘ AFTER CONTROL EXPECTED一些控制参数需要用括号包含一个参数当没有左括号时显示本信息‘)’ AFTER PARAMETER EXPECTED本信息表示包含没有参数的右括号BAD DIGIT IN NUMBER一个控制参数的数字参数包含无效字符只能是十进制数CAN’T CREATE FILE在FILE行定义的文件名不能建立CAN’T HA VE GERERAL CONTROL IN INVOCATION LINE一般控制例如EJECT不能包含在命令行把这些控制用#pragma声明放在源文件中FILE DOES NOT EXIST没有发现定义在FILE行的文件FILE WRITE-ERROR因为磁盘空间不够写到列表预打印工作或目标文件时出错IDENTIFIER EXPECTED当DEFINE控制没有参数时产生本信息DEFINE要求一个参数作为标识符这和C语言的规则相同MEMORY SPACE EXHAUSTED编译器不能分配足够的存储区来编译指定的源文件如果始终出现这个信息应该把源文件分成两个或多个小文件再重新编译MORE THAN100ERRORS IN SOURCE-FILE在编译时检测到的错误超过100个这使编译器终止MORE THAN256SEGMENTS/EXTERNALS在一个源文件中的参考超过256个单个的源文件不能有超过256个函数或外部参考这是INTEL目标模块格式OMF-51的历史的限制包含标量和/或bit声明的函数在OBJ文件中生成两个有时候三个段定义NON-NULL ARGUMENT EXPECTED所选的控制参数需要用括号包含一个参数例如一个文件名或一个数字OUT OF RANGE NUMBER一个控制参数的数字参数超出范围例如OPTIMIZE控制只允许数字0到6值7就将产生本错误信息PARSE STACK OVERFLOW解析堆栈溢出如果源程序包含很复杂的表达式或如果块的嵌套深度超过31级就会出现这个错误PREPROCESSOR LINE TOO LONG32K一个中间扩展长度超过32K字符PREPROCESSOR MACROS TOO NESTED在宏扩展期间预处理器所用的堆栈太大这个信息通常表示一个递归的宏定义但也可表示一个宏嵌套太多RESPECIFIED OR CONFLICTING CONTROL一个命令行参数指定了两次或命令行参数冲突SOURCE MUST COME FROM A DISK-FILE源和包含文件必须存在控制台CON CI或类似的设备不能作为输入文件UNKNOWN CONTROL所选的控制参数不认识语法和语义错误语法和语义错误一般出现在源程序中它们确定实际的编程错误当遇到这些错误时编译器尝试绕过错误继续处理源文件当遇到更多的错误时编译器输出另外的错误信息但是不产生OBJ文件语法和语义错误在列表文件中生成一条信息这些错误信息用下面的格式*** ERROR number IN LINE line OF file:error message这里number错误号line对应源文件或包含文件的行号file产生错误的源或包含文件名error message对错误的叙述说明下表按错误号列出了语法和语义错误错误信息列出了主要说明和可能的原因和改正100跳过不可打印字符0x??在源文件中发现一个非法字符注意不检查注释中的字符101字符串没结束一个字符串没有用双引号终止102字符串太长一个字符串不能超过4096个字符用串联符号\在逻辑上可延长字符串超过4096个字符这个模式的行终止符在词汇分析时是连续的103无效的字符常数一个字符常数的格式无效符号\c是无效的除非c是任何可打印的ASCII字符125声明符太复杂20一个目标的声明可包含最多20个类型修饰符[]*这个错误经常伴随着错误126126类型堆栈下溢类型声明堆栈下溢这个错误通常死错误125的副产品127无效存储类一个目标用一个无效的存储空间标识符声明如果一个目标在一个函数外用存储类auto或register声明就会产生本错误129在标记前缺少本错误通常表示前一行缺少分号当出现本错误时编译器会产生很多错误信息130值超出范围在一个using或interrupt标识符后的数字参数是无效的using标识符要求一个0到3之间的寄存器组号interrupt标识符要求一个0到31之间的中断矢量号131函数参数重复一个函数有相同的参数名在函数声明中参数名必须是唯一的132没在正式的参数列表一个函数的参数声明用了一个名称没在参数名列表中例如char function(v0,v1,v2)char *v0,*v1,*v5;/* ‘v5’没在正式列表中 */{/* … */}134函数的xdata/idata/pdata/data不允许函数通常位于code存储区不能在别的存储区运行函数默认定义为存储类型code135bit的存储类错bit标量的声明可能包含一个static或extern存储类register或alien类是无效的136变量用了voidvoid类型只允许作为一个不存在的返回值或一个函数的空参数列表voidfunc(void)或和一个指针组合void *138Interrupt()不能接受或返回值一个中断函数被定义了一个或多个正式的参数或一个返回值中断函数不能包含调用参数或返回值140位在非法的存储空间bit标量的定义可以包含可选的存储类型data如果没有存储类型则默认为data因为位通常在内部数据存储区当试图对一个bit标量定义别的数据类型时会产生本错误141临近标志语法错误期待别的标志…编译器所见的标志是错误的参考所显示的期待的内容142无效的基地址一个sfr或sbit声明的基地址是错误的有效的基地址范围在0x80到0xFF之间如果用符号基地址^位号声明则基地址必须是8的倍数143无效的绝对位地址sbit声明中的绝对位地址必须在0x80到0xFF之间144基地址^位号无效的位号sbit声明中定义的位号必须在0到7之间145未知的sfr146无效sfr一个绝对位基地址^位号的声明包含一个无效的基地址标识符基地址必须是已经声明的sfr任何别的名称是无效的147目标文件太大单个目标文件不能超过6553564K字节-1149struct/union包含函数成员struct或union不能包含一个函数类型的成员但是指向函数的指针是可以的150struct/union包含一个bit成员一个union不能包含bit类型成员这是8051的结构决定的151struct/union自我关联一个结构不能包含自己152位号超出位域位域声明中指定的位号超过给定基类的位号153命名的位域不能为零命名的位域为零只要未命名的位域允许为零154位域指针指向位域的指针不允许155位域要求char/int位域的基类要求char或int unsigned char和unsigned int类型也行156alien只允许对函数157alien函数带可变参数存储类alien只对外部PL/M-51函数允许符号ch a r*,…在alien函数中是非法的PL/M-51函数通常要求一个固定的参数表158函数包含未命名的参数一个函数的参数列表定义包含一个未命名的抽象类型定义这个符号只允许在函数原型中159void后面带类型函数的原型声明可包含一个空参数列表例如int func(void)在void后不能再有类型定义160void无效void类型只在和指针组合或作为一个函数的不存在的返回值中是合法的161忽视了正式参数在一个函数内一个外部函数的声明用了一个没有类型标识符的参数名列表例如extern yylex(a,b,c);180不能指向一个函数指向一个函数的类型是无效的尝试用指针指向一个函数181操作数不兼容对给定的操作符至少一个操作数类型是无效的例如~float_type183左值不能修改要修改的目标位于code存储区或有const属性因此不能修改184sizeof非法操作数sizeof操作符不能确定一个函数或位域的大小185不同的存储空间一个目标声明的存储空间和前一个同样目标声明的存储空间不同186解除参照无效一个内部编译器问题会产生本信息如果本错误重复出现请和技术支持接洽187不是一个左值所需的参数必须是一个可修改的目标地址188未知目标大小因为没有一个数组的维数或间接通过一个void指针一个目标的大小不能计算189&对bit/sfr非法取地址符’&’不允许对bit目标或特殊函数寄存器sfr190&不是一个左值尝试建立一个指针指向一个未知目标193非法操作类型193对ptr非法add/sub193对bit的非法操作193错误操作数类型当对一个给定的操作符用了非法的操作数类型时产生本错误例如无效的表达式如bit*bit ptr+ptr或ptr*anything这个错误信息包括引起错误的操作符下面的操作对bit类型的操作数是可行的赋值=OR/复合OR||=AND/复合AND&&=XOR/复合XOR^^=bit比较= =!=取反~bit操作数可和别的数据类型在表达式中混用在这种情况类型转换自动执行194*间接指向一个未知大小的目标间接操作符*不能和void指针合用因为指针所指的目标的大小是未知的195*间接非法*操作符不能用到非指针参数196存储空间可能无效转换一个常数到一个指针常数产生一个无效的存储空间例如 char*p=0x91234198sizeof返回零sizeof操作符返回一个零199->’的左边要求struct/union指针->操作符的左边参数必须是一个struct指针或一个union指针200.左边要求struct/union.操作符的左边参数要求必须是struct或union类型201未定义的struct/union给定的struct或union名是未知的202未定义的标识符给定的标识符是未定义的203错误的存储类参考名本错误表示编译器的一个问题如果重复出现请接洽技术支持204未定义的成员给定的一个struct或union成员名是未定义的205不能调用一个中断函数一个中断函数不能象一个正常函数一样调用中断的入口和退出代码是特殊的207参数列表声明为void参数列表声明为void的函数不能从调用者接收参数208太多的实参函数调用包含太多的实参209太少的实参调用函数包含太少的实参210太多的嵌套调用函数的嵌套调用不能超过10级211调用不是对一个函数一个函数的调用项不是对一个函数或函数指针求值212间接调用寄存器的参数不匹配通过一个指针的间接函数调用不包含实际的参数一个例外是当所有的参数可以通过寄存器传递这是由于Cx51所用的传递参数的方法被调用的函数名必须是已知的因为参数写到被调用函数的数据段但是对间接调用来说被调用函数的名称是未知的213赋值符的左边不是一个左值赋值符的左边要求一个可修改目标的地址214非法指针转换bit float或集合类型的目标不能转换为指针215非法类型转换struct/union/void不能转换为任何别的类型216标号用在非数组中或维数超出一个数组引用包含太大的维数或目标不是一个数组217非整数索引一个数组的维数表达式必须是char unsigned char int或unsigned int类型别的类型都是非法的218控制表达式用了void类型在一个while for或do的限制表达式中不能用类型void219long常数缩减为int一个常数表达式的值必须能用一个int类型表示220非法常数表达式期望一个常数表达式目标名变量或函数不允许出现在常数表达式中221非常数case/dim表达式一个case或一个维数[ ]必须是一个常数表达式222被零除223被零取模编译器检测到一个被零除或取模225表达式太复杂需简化一个表达式太复杂必须分成两个或多个子表达式226重复的struct/union/enum标记一个struct union或enum名早已定义227表示一个union标记一个union名称早已定义为别的类型228表示一个struct标记一个struct名早已定义为别的类型229表示一个enum标记一个enum名早已定义为别的类型230未知的struct/union/enum标记指定的struct union或enum名未定义231重复定义指定的名称已被定义232重复标号指定的标号已定义233未定义标号表示一个标号未定义有时候这个信息会在实际的标号的几行后出现这是所用的未定义标号的搜索方法引起的234{堆栈范围溢出31超过了最多31个嵌套块超出的嵌套块被忽略235参数<数字>不同类型函数声明的参数类型和函数原型中的不同236参数列表的长度不同函数声明中的参数数目和函数原型中的不同237函数早已定义试图声明一个函数体两次238重复成员239重复参数试图定义一个已存在的struct成员或函数参数240超出128个局部bit在一个函数内不能超过128个bit标量241auto段太大局部目标所需的空间超过模式的极限最大的段大小定义如下SMALL128字节COMPACT256字节LARGE65535字节242太多的初始化软件初始化软件的数目超过初始化目标的数量243字符串超出范围字符串中的字符数目超出字符串初始化的数目244不能初始化错误的类型或类试图初始化一个bit或sfr245未知的pragma跳过本行#pragma状态未知所以整行被忽略246浮点错误当一个浮点参数超出32位的范围就产生本错误32位IEEE值的范围是±1.175494E-38到±3.402823E+38247非地址/常数初始化一个有效的初始化表达式必须是一个常数值求值或一个目标名加或减去一个常数248集合初始化需要大括号给定struct或union初始化缺少大括号{}249段<名>段太大编译器检测到一个数据段太大一个数据段的最大的大小由存储空间决定250\esc值超过255一个字符串常数中的转义序列超过有效值范围最大值是255252非法八进制数指定的字符不是一个有效的八进制数252主要控制放错地方行被忽略主要控制必须被指定在C模块的开头在任何#include命令或声明前253内部错误ASMGEN\CLASS在下列情况下出现本错误一个内在函数例如_testbit_被错误激活这种情况是在没有函数原型存在和实参数目或类型错误对这种原因必须使用合适的声明文件INTRINS.H STRING.H参考第八章中的instrinsic函数Cx51确认一个内部一致性问题请接洽技术支持255switch表达式有非法类型在一个switch表达式没有合法的数据类型256存储模式冲突一个包含alien属性的函数只能包含模式标识符small函数的参数必须位于内部数据区这适用于所有的外部alien声明和alien函数例如alien plm_func(char c) large {…}产生错误256257alien函数不能重入一个包含alien属性的函数不能同时包含reentrant属性函数参数不能跳过虚拟堆栈传递这适用于所有的外部alien声明和alien函数258struct/union成员的存储空间非法非法空间的参数被忽略一个结构的成员或参数不能包含一个存储类型标识符但指针所指的目标可能包含一个存储类型例如struct vp{char code c;int xdata i; };产生错误258struct v1{char c;int xdata *i; };是正确的struct声明259指针不同的存储空间一个空指针被关联到别的不同存储空间的空指针例如char xdata *p1;char idata *p2;p1 = p2; /* 不同的存储空间 */260指针断开一个空指针被关联到一些常数值这些值超过了指针存储空间的值范围例如char idata *p1 = 0x1234; /* 结果是0x34 */261reentrant()内有bit一个可重入属性的函数的声明中不能包含bit目标例如int func1(int i1) reentrant {bit b1,b2; /* 不允许 */return(i1-1);}262using/disable不能返回bit值用using属性声明的函数和禁止中断#pragma disable的函数不能返回一个bit值给调用者例如bit test(void) using 3{bit b0;return(b0);}产生错误262263保存/恢复堆栈保存溢出/下溢#pragma save的最大嵌套深度是八级堆栈的pragma save和restore工作根据LIFO后进先出规则264内在的<内在的名称>声明/激活错误本错误表示一个内在的函数错误定义参数数目或省略号如果用标准的.H文件就不会产生本错误确认使用了Cx51所有的.H文件不要尝试对内在的库函数定义自己的原型265对非重入函数递归调用非重入函数不能被递归调用因为这样会覆盖函数的参数和局部数据如果需要递归调用需声明函数为可重入函数267函数定义需要ANSI类型的原型一个函数被带参数调用但是声明是一个空的参数列表原型必须有完整的参数类型这样编译器就可能通过寄存器传递参数和适合应用的调用机制268任务定义错误任务ID/优先级/using任务声明错误271asm/endasm控制放错地方asm和endasm声明不能嵌套endasm要求一个汇编块前面用asm开头例如#pragma asm...汇编指令...#pragma endasm272asm要求激活SRC控制在一个源文件中使用asm和endasm要求文件用SRC控制编译那么编译器就会生成汇编源文件然后可以用A51汇编273asm/endasm在包含文件中不允许在包含文件中不允许asm和endasm为了调试在包含文件不能有任何的可执行代码274非法的绝对标识符绝对地址标识符对位目标函数和局部函数不允许地址必须和目标的存储空间一致例如下面的声明是无效的因为间接寻址的范围是0x00到0xFFidata int _at_ 0x1000;278常数太大当浮点参数超出32位的浮点值范围就产生本错误32位IEEE值的范围是±1.175494E-38到±3.402823E+38279多次初始化试图多次初始化一个目标280没有使用符号/标号/参数在一个函数中声明了一个符号标号或参数但没有使用281非指针类型转换为指针引用的程序目标不能转换成一个指针282不是一个SFR引用本函数调用要求一个SFR作为参数283asmparms参数不适合寄存器参数不适合可用的CPU寄存器284<名称>在可覆盖空间函数不再可重入一个可重入函数包含对局部变量的明确的存储类型标识符函数不再完全可重入300注释未结束一个注释没有一个结束符*/301期望标识符一个预处理器命令期望一个标识符302误用#操作符字符操作符#没有带一个标识符303期望正式参数字符操作符#没有带一个标识符表示当前所定义的宏的一个正式参数名304错误的宏参数列表宏参数列表没有一个大括号逗号分开的标识符列表305string/char常数未结束一个字符串活字符常数是无效的典型的后引号丢失306宏调用未结束预处理器在收集和扩展一个宏调用的实际的参数时遇到输入文件的结尾307宏名称参数计算不匹配在一个宏调用中实际的参数数目和宏定义的参数数目不匹配本错误表示指定了太少的参数308无效的整数常数表达式一个if/elif命令的数学表达式包含一个语法错误309错误或缺少文件名在一个include命令中的文件名参数是无效的或没有310条件嵌套过多20源文件包含太多的条件编译嵌套命令最多允许20级嵌套311elif/else控制放错地方312endif控制放错地方命令elif else和endif只有在if ifdef或ifndef命令中是合法的313不能清除预定义的宏名称试图清除一个预定义宏用户定义的宏可以用#undef命令删除预定义的宏不能清除314#命令语法错误在一个预处理器命令中字符#必须跟一个新行或一个预处理器命令名例如if/define/ifdef…315未知的#命令名称预处理器命令是未知的316条件未结束到文件结尾endif的数目和if或ifdef的数目不匹配318不能打开文件文件名指定的文件不能打开319文件不是一个磁盘文件指定的文件不是一个磁盘文件文件不能编辑320用户自定义的内容本错误号未预处理器的#error命令保留#error命令产生错误号320送出用户定义的错误内容终止编译器生成代码321缺少<字符>在一个include命令的文件名参数中缺少结束符例如#include<stdio.h325正参名称重复一个宏的正参只能定义一次326宏体不能以##开始或结束##不能是一个宏体的开始或结束327宏宏名超过50个参数每个宏的参数数目不能超过50警告警告产生潜在问题的信息他们可能在目标程序的运行过程中出现警告不妨碍源文件的编译警告在列表文件中生成信息警告信息用下面的格式*** WARNING number IN LINE line OF file: warning message这里number错误号line在源文件或包含文件中的对应行号file错误产生的源或包含文件名warning message警告的内容下表按号列出了警告警告信息包括一个主要的内容和可能的原因和纠正措施173缺少返回表达式一个函数返回一个除了int类型以外的别的类型的值必须包含一个返回声明包括一个表达式为了兼容旧的程序对返回一个int值的函数不作检查182指针指向不同的目标一个指针关联了一个不同类型的地址185不同的存储空间一个目标声明的存储空间和前面声明的同样目标的存储空间不同196存储空间可能无效把一个无效的常数值分配给一个指针无效的指针常数是long或unsigned long编译器对指针采用24位3字节低16位代表偏移高8位代表选择的存储空间198sizeof返回零一个目标的大小计算结果为零如果目标是外部的或如果一个数组的维数没有全知道则值是错误的206缺少函数原型因为没有原型声明被调用的函数是未知的调用一个未知的函数通常是危险的参数的数目和实际要求不一样如果是这种情况函数调用不正确没有函数原型编译器不能检查参数的数目和类型要避免这种警告应在程序中包含函数的原型函数原型必须在函数被调用前声明注意函数定义自动生成原型209实参太少在一个函数调用中包含太少的实参219long常数被缩减为int一个常数表达式的值必须能被一个int类型所表示245未知的pragma本行被忽略#pragma声明是未知的因此整行程序被忽略258struct/union成员的存储空间方法参数的存储空间被忽略一个结构的成员或一个参数不能指定存储类型但是指针所指的目标可以包含一个存储类型例如struct vp{ char code c;int xdata i; };产生警告258struct v1{ char c;int xdata *i; };对struct是正确的声明259指针不同的存储空间两个要比较的指针没有引用相同的存储类型的目标260指针折断把一个指针转换为一个更小偏移区的指针转换会完成但大指针的偏移会折断来适应小指针261bit在重入函数一个reentrant函数不能包含bit因为bit标量不能保存在虚拟堆栈中265名称对非重入函数递归调用发现对一个非重入函数直接递归这可能是故意的但对每个独立的情况进行功能性检查通过生成的代码间接递归由连接/定位器检查271asm/endams控制放错地方asm和endasm不能嵌套endasm要求一个以asm声明开头的汇编块例如#pragma asm...汇编指令...#pragma endasm275表达式可能无效编译器检测到一个表达式不生成代码例如void test(void) {int i1,i2,i3;i1,i2,i3; /* 死表达式 */i1 << i3; /* 结果未使用 */}276常数在条件表达式编译器检测到一个条件表达式有一个常数值在大多数情况下是一个输入错误例如void test(void) {int i1,i2,i3;if( i1 = 1) i2 = 3; /* 常数被赋值 */while( i3 = 2); /* 常数被赋值 */}277指针有不同的存储空间一个typedef声明的存储空间冲突例如typedef char xdata XCC; /* 存储空间xdata */typedef XCC idata PICC; /* 存储空间冲突 */280符号/标号未使用一个符号或标号定义但未使用307宏名称参数计算不匹配一个宏调用的实参的数目和宏定义的参数数目不匹配表示用了太多的的参数过剩的参数被忽略317宏名称重新定义无效一个预定义的宏不能重新定义或清除参考138页的预定义宏常数322未知的标识符在一个#if命令行的标识符未定义等效为FALSE323期望新行发现多余字符一个#命令行正确但包含多余的非注释字符例如#include <stdio.h> foo。
keil软件编译常见错误解释总结和中文翻译

Keil编译时出现错误和警告的总结和C 编译器错误信息中文翻译(1)L15重复调用***WARNING L15: MULTIPLE CALL TO SEGMENTSEGMENT: ?PR?SPI_RECEIVE_WORD?D_SPICALLER1: ?PR?VSYNC_INTERRUPT?MAINCALLER2: ?C_C51STARTUP该警告表示连接器发现有一个函数可能会被主函数和一个中断服务程序(或者调用中断服务程序的函数)同时调用,或者同时被多个中断服务程序调用。
出现这种问题的原因之一是这个函数是不可重入性函数,当该函数运行时它可能会被一个中断打断,从而使得结果发生变化并可能会引起一些变量形式的冲突(即引起函数内一些数据的丢失,可重入性函数在任何时候都可以被ISR打断,一段时间后又可以运行,但是相应数据不会丢失)。
原因之二是用于局部变量和变量(暂且这样翻译,arguments,[自变量,变元一数值,用于确定程序或子程序的值])的内存区被其他函数的内存区所覆盖,如果该函数被中断,则它的内存区就会被使用,这将导致其他函数的内存冲突。
例如,第一个警告中函数WRITE_GMVLX1_REG 在D_GMVLX1.C 或者D_GMVLX1.A51被定义,它被一个中断服务程序或者一个调用了中断服务程序的函数调用了,调用它的函数是VSYNC_INTERRUPT,在MAIN.C中。
解决方法:如果你确定两个函数决不会在同一时间执行(该函数被主程序调用并且中断被禁止),并且该函数不占用内存(假设只使用寄存器),则你可以完全忽略这种警告。
如果该函数占用了内存,则应该使用连接器(linker)OVERLAY指令将函数从覆盖分析(overlay analysis)中除去,例如:OVERLAY (?PR?_WRITE_GMVLX1_REG?D_GMVLX1 ! *)上面的指令防止了该函数使用的内存区被其他函数覆盖。
如果该函数中调用了其他函数,而这些被调用在程序中其他地方也被调用,你可能会需要也将这些函数排除在覆盖分析(overlay analysis)之外。
KEIL51常见警告错误说明

1.Warning 280:‟i‟:unreferenced local variable说明局部变量i 在函数中未作任何的存取操作。
解决方法消除函数中i 变量的宣告。
2.Warning 206:‟Music3‟:m issing function-prototype说明Music3( )函数未作宣告或未作外部宣告所以无法给其他函数调用。
解决方法将叙述void Music3(void)写在程序的最前端作宣告如果是其他文件的函数则要写成extern void Music3(void),即作外部宣告。
3.Com pling :C:\8051\MANN.CError:318:can‟t open file …beep.h‟说明在编译C:\8051\MANN.C 程序过程中由于m ain.c 用了指令#include “beep.h”,但却找不到所致。
解决方法编写一个beep.h 的包含档并存入到c:\8051 的工作目录中。
4.Com pling:C:\8051\LED.CError 237:‟LedOn‟:function already has a body说明LedOn( )函数名称重复定义即有两个以上一样的函数名称。
解决方法修正其中的一个函数名称使得函数名称都是独立的。
5. ***WARNING 16:UNCALLED SEGMENT,IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_DELAYX1MS?DELAY说明DelayX1m s( )函数未被其它函数调用也会占用程序记忆体空间。
解决方法去掉DelayX1m s( )函数或利用条件编译#if …..#endif,可保留该函数并不编译。
6. ***WARNING 6 :XDATA SPACE MEMOR Y OVERLAPFROM : 0025HTO: 0025H说明外部资料ROM 的0025H 重复定义地址解决方法外部资料ROM 的定义如下Pdata unsigned char XFR_ADC _at_0x25 其中XFR_ADC 变量的名称为0x25,请检查是否有其它的变量名称也是定义在0x25 处并修正它7 .WARNING 206:‟DelayX1m s‟: missing function-prototypeC:\8051\INPUT.CError 267 :‟DelayX1m s …:requires ANSI-style prototype C:\8051\INPUT.C说明程序中有调用DelayX1m s 函数但该函数没定义即未编写程序内容或函数已定义但未作宣告。
我总结的KEIL51调试的错误总结

KEIL51调试时一些的错误总结(1)提示无M51文件编译时候提示:F:\...\XX.M51File has been changed outside the editor, reload ?------解决方法:重新生成项目,产生STARTUP.A51即可。
(2)L15重复调用***WARNING L15: MULTIPLE CALL TO SEGMENTSEGMENT: ?PR?SPI_RECEIVE_WORD?D_SPICALLER1: ?PR?VSYNC_INTERRUPT?MAINCALLER2: ?C_C51STARTUP如果函数可以在其执行时被调用,则情况会变得更复杂一些。
这时可以采用以下几种方法:1.主程序调用该函数时禁止中断,可以在该函数被调用时用#pragma disable语句来实现禁止中断的目的。
必须使用OVERLAY指令将该函数从覆盖分析中除去。
2.复制两份该函数的代码,一份到主程序中,另一份复制到中断服务程序中。
3.将该函数设为重入型。
例如:void myfunc(void) reentrant {...}这种设置将会产生一个可重入堆栈,该堆栈被被用于存储函数值和局部变量,用这种方法时重入堆栈必须在STARTUP.A51文件中配置。
这种方法消耗更多的RAM并会降低重入函数的执行速度。
(3)L16无调用*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESSSEGMENT: ?PR?_COMPARE?TESTLCD说明:程序中有些函数例如COMPARE(或片段)以前(调试过程中)从未被调用过,或者根本没有调用它的语句。
这条警告信息前应该还有一条信息指示出是哪个函数导致了这一问题。
只要做点简单的调整就可以。
不理它也没什么大不了的。
解决方法:去掉COMPARE()函数或利用条件编译#if …..#endif,可保留该函数并不编译。
Keil调试常见错误

1. Warning 280:’i’:unreferenced local variable说明局部变量i 在函数中未作任何的存取操作解决方法消除函数中i 变量的宣告2 Warning 206:’Music3’:missing function-prototype说明Music3( )函数未作宣告或未作外部宣告所以无法给其他函数调用解决方法将叙述void Music3(void)写在程序的最前端作宣告如果是其他文件的函数则要写成extern void Music3(void),即作外部宣告3 Compling :C:\8051\MANN.CError:318:can’t open file ‘beep.h’说明在编译C:\8051\MANN.C 程序过程中由于main.c 用了指令#i nclude “beep.h”,但却找不到所致解决方法编写一个beep.h 的包含档并存入到c:\8051 的工作目录中4 Compling:C:\8051\LED.CError 237:’LedOn’:function already has a body说明LedOn( )函数名称重复定义即有两个以上一样的函数名称解决方法修正其中的一个函数名称使得函数名称都是独立的5 ***WARNING 16:UNCALLED SEGMENT,IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_DELAYX1MS?DELAY说明DelayX1ms( )函数未被其它函数调用也会占用程序记忆体空间解决方法去掉DelayX1ms( )函数或利用条件编译#if …..#endif,可保留该函数并不编译6 ***WARNING 6 :XDA TA SPACE MEMORY OVERLAPFROM : 0025HTO: 0025H说明外部资料ROM 的0025H 重复定义地址解决方法外部资料ROM 的定义如下Pdata unsigned char XFR_ADC _at_0x25 其中XFR_ADC变量的名称为0x25,请检查是否有其它的变量名称也是定义在0x25 处并修正它7 WARNING 206:’DelayX1ms’: missing function-prototypeC:\8051\INPUT.CError 267 :’DelayX1ms ‘:requires ANSI-style prototype C:\8051\INPUT.C说明程序中有调用DelayX1ms 函数但该函数没定义即未编写程序内容或函数已定义但未作宣告解决方法编写DelayX1ms 的内容编写完后也要作宣告或作外部宣告可在delay.h 的包含档宣告成外部以便其它函数调用8 ***WARNING 1:UNRESOLVED EXTERNAL SYMBOLSYMBOL:MUSIC3MODULE:C:\8051\MUSIC.OBJ(MUSIC)***WARNING 2:REFERENCE MADE TO UNRESOLVED EXTERNALSYMBOL:MUSIC3MODULE:C:\8051\MUSIC.OBJ(MUSIC)ADDRESS:0018H说明程序中有调用MUSIC 函数但未将该函数的含扩档C 加入到工程档Prj 作编译和连接解决方法设MUSIC3 函数在MUSIC C 里将MUSIC C 添加到工程文件中去9 ***ERROR 107:ADDESS SPACE OVERFLOWSPACE: DATASEGMENT: _DATA_GOUP_LENGTH: 0018H***ERROR 118: REFERENCE MADE TO ERRONEOUS EXTERNALSYMBOL: VOLUMEMODULE: C:\8051\OSDM.OBJ (OSDM)ADDRESS: 4036H说明data 存储空间的地址范围为0~0x7f,当公用变量数目和函数里的局部变量如果存储模式设为SMALL 则局部变量先使用工作寄存器R2~R7 作暂存当存储器不够用时则会以data 型别的空间作暂存的个数超过0x7f 时就会出现地址不够的现象解决方法将以data 型别定义的公共变量修改为idata 型别的定义说明如对编译出错感兴趣的网友能否把你们常遇到的错误信息收集起来并提出最终的解决办法加以归纳以期共享10.***WARNING L15: MULTIPLE CALL TO SEGMENTSEGMENT: ?PR?_WRITE_GMVLX1_REG?D_GMVLX1CALLER1: ?PR?VSYNC_INTERRUPT?MAINCALLER2: ?C_C51STARTUP***WARNING L15: MULTIPLE CALL TO SEGMENTSEGMENT: ?PR?_SPI_SEND_WORD?D_SPICALLER1: ?PR?VSYNC_INTERRUPT?MAINCALLER2: ?C_C51STARTUP***WARNING L15: MULTIPLE CALL TO SEGMENTSEGMENT: ?PR?SPI_RECEIVE_WORD?D_SPICALLER1: ?PR?VSYNC_INTERRUPT?MAINCALLER2: ?C_C51STARTUP该警告表示连接器发现有一个函数可能会被主函数和一个中断服务程序(或者调用中断服务程序的函数)同时调用,或者同时被多个中断服务程序调用。
Keil中的常见错误和警告

Keil中的常见错误和警告C51编译器识别错类型有三种1、致命错误:伪指令控制行有错、命令行指定的无效选项、访问不存在的原文件或头文件等。
致命错误立即终止程序编译。
2、语法及语义错误:语法和语义错误都发生在源文件中。
有这类错误时,给出提示但不产生目标文件,错误超过一定数量才终止编译。
3、警告:警告出现并不影响目标文件的产生,但执行时有可能发生问题,程序员应斟酌处理。
错误信息及可能发生的原因列表*ERROR 100:unprintable character 0x??skipped源文件中发现非法字符(注意,注解内的字符不做检查)。
*ERROR 101:unclosed string字符串未用引号结尾。
*ERROR 102:string too long字符串不得超过511 个字符。
为了定义更长的串,用户必须使用续行符‘\’逻辑的继续该字符串,在词汇分析时遇到以该符号结尾的行会与下行连接起来.*ERROR 103: invalid character constant试图再声明一个已定义的宏,已存在的宏可以用#undef指令删除。
预定义的宏不能删除。
*ERROR 104: identifier expected预处理器指令期望产生一个标示符,如ifdef。
*ERROR 105: unclosed comment当注解无结束界定符(*/)时产生此错误。
*EROOR 106: unbalanced#if-endif controlsendif的数量与if或ifdef的数量不匹配。
*ERROR 107:include file nesting exceeds 9include指令后的文件名无效或丢失*ERROR 108:expected string,如#error “string”预处理器指令期望一个串变量。
*ERROR 109:由#error 伪指令引入的错误信息以错误信号形式显示。
*ERROR 110:missing directive预处理行#后缺少伪指令。
51单片机编程让新手最容易出错的几点总结

51单片机编程让新手最容易出错的几点总结
1、在写头件时,有的朋友会把'<>'或''''这两忘记写,比如说:#include reg52.h,它就写成这样,所以你编译的时候肯定会出错的,正确的应该这样:#include <reg52.h>;再说一点,一般'<>'的是编译器中自带的文件,而''''是自己定义的头文件,这是C语言规则里面提到的,不这样写也没事,但是我们也应该遵守是吧!
2、在写宏定义时最容把关键字中字母写错,#define uint unsigned int #define uchar unsigned char,在网上找到很多鞋童,把unsigned中的'n'写成'h',不知道是不是有近视还是按错了,所以大家写程序的时候特别注意,没事的时候,多写程序,把32个关键字记牢,以免后面写程序时犯同样的毛病。
3、在写宏定义时,后面不需要写分号,有的朋友经常这样,#define False 0;这句是用False代替0;,当在调用时,比如:return False;你们说这样写有没有错,有可能的朋友说没错,但是真正的是错了,在编译的时候肯定会错,那么错在那呢?因为#define False 0;,它的作用是用False代替'0;',所以在调用时这样return False,后面不要加分号。
为了避免错误,大家在定义宏时,后面最好不要加分号。
Keil 编译错误信息大全

例如,第一个警告中函数WRITE_GMVLX1_REG 在D_GMVLX1.C 或者D_GMVLX1.A51被定义,它被一个中断服务程序或者一个调用了中断
服务程序的函数调用了,调用它的函数是VSYNC_INTERRUPT,在MAIN.C中。
解决方法:
如果你确定两个函数决不会在同一时间执行(该函数被主程序调用并且中断被禁止),并且该函数不占用内存(假设只使用寄存器),
则你可以完全忽略这种警告。
如果该函数占用了内存,则应该使用连接器(linker)OVERLAY指令将函数从覆盖分析(overlay analysis)中除去,例如:
OVERLAY (?PR?_WRITE_GMVLX1_REG?D_GMVLX1 !*)
上面的指令防止了该函数使用的内存区被其他函数覆盖。如果该函数中调用了其他函数,而这些被调用在程序中其他地方也被调用,
你可能会需要也将这些函数排除在覆盖分析(overlay analysis)之外。这种OVERLAY指令能使编译器除去上述警告信息................
Keil 编译错误信息大全:
第一种错误信息:警告连接器发现有一个函数可能会被主函数和一个中断服务程序(或者调用中断服务程序的函数)同时调用,
或者同时被多个中断服务程序调用。
***WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?_WRITE_GMVLX1_REG?D_GMVLX1
出现这种问题的原因之一是这个函数是不可重入性函数,当该函数运行时它可能会被一个中断打断,从而使得结果发生变化
并可能会引起一些变量形式的冲突(即引起函数内一些数据的丢失,可重入性函数在任何时候都可以被ISR打断,一段时间后又可以
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
----
回答:程序里有带中文标点,用英文重新写一遍即可
(12)A45汇编出现数字、字母混淆
MOV PO,A ;put on next 11
...
MOV RO,#0FFH ; 14
MOV R1,#OFFH ; 15
...
DJNZ RO,DLY_LP ;19
MOV R0,#OFFH ; 20
...
编译后:
出现这种问题的原因之一是这个函数是不可重入性函数,当该函数运行时它可能会被一个中断打断,从而使得结果发生变化并可能会引起一些变量形式的冲突(即引起函数内一些数据的丢失,可重入性函数在任何时候都可以被ISR打断,一段时间后又可以
运行,但是相应数据不会丢失)。
原因之二是用于局部变量和变量(暂且这样翻译,arguments,[自变量,变元一数值,用于确定程序或子程序的值])的内存区被其他函数的内存区所覆盖,如果该函数被中断,则它的内存区就会被使用,这将导致其他函数的内存冲突。
ledtest.asm(19): error A45: UNDEFINED SYMBOL (PASS-2)
ledtest.asm(20): error A45: UNDEFINED SYMBOL (PASS-2)
Target not created
---------
注意:
字母“O” 和 数字 “0”。主要错在这里。
定义了如下的数组:
unsigned char a[36]={'0xfe','0xfd','0xfb','0xf7','0xef','0xdf','0xbf','0x7f','0x7e','0x7d','0x7b','0x77','0x6f','0x5f','0x3f','0x3e','0x3d','0x3b','0x37','0x2f','0x1f','0x1e','0x1d','0x1b','0x17','0x0f','0x0e','0x0d','0x0b','0x07','0x06','0x05','0x03','0x02','0x01','0x00'};
如果该函数占用了内存,则应该使用连接器(linker)OVERLAY指令将函数从覆盖分析(overlay analysis)中除去,例如:
OVERLAY (?PR?_WRITE_GMVLX1_REG?D_GMVLX1 ! *)
上面的指令防止了该函数使用的内存区被其他函数覆盖。如果该函数中调用了其他函数,而这些被调用在程序中其他地方也被调用,你可能会需要也将这些函数排除在覆盖分析(overlay analysis)之外。这种OVERLAY指令能使编译器除去上述警告信息。
同上错误有很多个,还有D:\KEIL\C51\INC\REG52.H(2): error C141: syntax error near '#'
D:\KEIL\C51\INC\REG52.H(2): error C129: missing ';' before '<'
但是reg52.h头文件是keil 自带的(见下),为何会报错呀。
SEGMENT: ?PR?_COMPARE?TESTLCD
说明:程序中有些函数例如COMPARE(或片段)以前(调试过程中)从未被调用过,或者根本没有调用它的语句。
这条警告信息前应该还有一条信息指示出是哪个函数导致了这一问题。只要做点简单的调整就可以。不理它也没什么大不了的。
解决方法:去掉COMPARE()函数或利用条件编译#if …..#endif,可保留该函数并不编译。
部分程序:
{
pval = P1 /* Read P1 into pval */
P3 = pval; /* Write pval to P3 */
}
编译提示出错:
MAIN.C(22): error C141: syntax error near 'P3'
改正: P1后加";"
(9)C129汇编与C后缀问题
如果函数可以在其执行时被调用,则情况会变得更复杂一些。这时可以采用以下几种方法:
1.主程序调用该函数时禁止中断,可以在该函数被调用时用#pragma disable语句来实现禁止中断的目的。必须使用OVERLAY指令将该函数从覆盖分析中除去。
2.复制两份该函数的代码,一份到主程序中,另一份复制到中断服务程序中。
KEIL51调试时一些的错误总结
(1)提示无M51文件
编译时候提示:
F:\...\XX.M51
File has been chቤተ መጻሕፍቲ ባይዱnged outside the editor, reload ?
------
解决方法:
重新生成项目,产生STARTUP.A51即可。
(2)L15重复调用
***WARNING L15: MULTIPLE CALL TO SEGMENT
COPYRIGHT KEIL ELEKTRONIK GmbH 1987 - 2005
"STARTUP.obj",
"test.obj"
TO "test"
*** FATAL ERROR L210: I/O ERROR ON INPUT FILE:
EXCEPTION 0021H: PATH OR FILE NOT FOUND
FILE: test.obj
Target not created
---------
设置上的问题,在程序里屏蔽掉#pragma src即可
(7)C206函数未定义
该函数没定义
MAIN.C(15): warning C206: 'delay1': missing function-prototype
(8)C141少分号
例如写这么一段小程序,保存为c0.c,编译时出现error c129,miss ; before 0000;
如果保存为:c0.asm就不会出现这个错误,保存为c的话,先调用c51编译器,按c语言的要求编译,所以出现错误;可以参考一些书,专门介绍keilc这个编译器的;
(10)C101和C141关于数组引号问题
ledtest.asm(11): error A45: UNDEFINED SYMBOL (PASS-2)
ledtest.asm(14): error A45: UNDEFINED SYMBOL (PASS-2)
ledtest.asm(15): error A45: UNDEFINED SYMBOL (PASS-2)
3.将该函数设为重入型。例如:
void myfunc(void) reentrant {
...
}
这种设置将会产生一个可重入堆栈,该堆栈被被用于存储函数值和局部变量,用这种方法时重入堆栈必须在STARTUP.A51文件中配置。这种方法消耗更多的RAM并会降低重入函数的执行速度。
(3)L16无调用
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
可是编译的时候总通不过,错误提示如下:
Build target 'Target 1'
compiling shaomiao.c...
SHAOMIAO.C(3): error C101: ''0': invalid character constant
SHAOMIAO.C(3): error C141: syntax error near 'xfe'
SEGMENT: ?PR?DELAY?MAIN
(6)L210程序前生成SRC语句
Build target 'Target 1'
assembling STARTUP.A51...
compiling test.C...
linking...
BL51 BANKED LINKER/LOCATER V6.00 - SN: K1JXC-94Z4V9
Program Size: data=8.0 xdata=0 code=9
---
修改:
缺少主程序(其实是笔误),将mian改为main
(5)L16主程序没用到前面定义的函数
主程序里没用到前面定义的函数,编译时显示:
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
(4)L10和L16"主程序名字写错(或无主程序)"
程序中:
void mian (void)
编译提示:
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
SEGMENT: ?PR?MIAN?MAIN
*** WARNING L10: CANNOT DETERMINE ROOT SEGMENT
例如,第一个警告中函数WRITE_GMVLX1_REG 在D_GMVLX1.C 或者D_GMVLX1.A51被定义,它被一个中断服务程序或者一个调用了中断服务程序的函数调用了,调用它的函数是VSYNC_INTERRUPT,在MAIN.C中。