keil c語言編程常見問題解析(一)

2021-02-19 單片機系列

實用乾貨下載:關注我們「單片機系列」,回復「資料」獲取單片機相關資料。一起走向智能工業革命時代,單片機DIY、基於c語言/彙編的編程。持續更新中······

最新隆重推出作品定製」,定製方法點擊菜單欄「DIY」即可

1. Warning 280:』i』:unreferenced local variable
說明局部變量i 在函數中未作任何的存取操作解決方法消除函數中i 變量的宣告及即定義的參數在程序中並未調用

2 Warning 206:』Music3』:missing function-prototype
說明Music3( )函數未作宣告或未作外部宣告所以無法給其他函數調用
解決方法將敘述void Music3(void)寫在程序的最前端作宣告如果是其他文件的函數則要寫成extern void Music3(void),即作外部宣告

3Error:318:can’t open file 『beep.h』
說明在編譯C:\8051\MANN.C 程序過程中由於main.c 用了指令#i nclude 「beep.h」,但卻找不到所致解決方法編寫一個beep.h 的包含檔並存入到c:\8051 的工作目錄中

4 Error 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 :XDATA SPACE MEMORY OVERLAP
FROM : 0025H
TO: 0025H
說明外部資料ROM 的0025H 重複定義地址
解決方法外部資料ROM 的定義如下Pdata unsigned char XFR_ADC _at_0x25 其中XFR_ADC 變量的名稱為0x25,請檢查是否有其它的變量名稱也是定義在0x25 處並修正它

7 WARNING 206:』DelayX1ms』: missing function-prototype
C:\8051\INPUT.C
Error 267 :』DelayX1ms 『:requires ANSI-style prototype C:\8051\INPUT.C
說明程序中有調用DelayX1ms 函數但該函數沒定義即未編寫程序內容或函數已定義但未作宣告
解決方法編寫DelayX1ms 的內容編寫完後也要作宣告或作外部宣告可在delay.h 的包含檔宣告成外部以便其它函數調用

8 ***WARNING 1:UNRESOLVED EXTERNAL SYMBOL
SYMBOL:MUSIC3

解決辦法:

1.是文件沒有添加到工程裡。

2.可能是因為存在沒有被調用的已經定義的函數。

3.不知道你有沒有把Source group組下面的A51.C刪掉,如果沒有刪,在A51.c上點右鍵,選擇remove file " ".

4.建一個新的c文件,裡面寫一個空的函數,把該文件添加到project中,注意該文件不能再選generate assembler SRC file和assemble SRC file選項。重新編譯工程,如果警告該函數沒被調用,在主文件中調一下。

5.建一個新的c文件,把主文件中的幾個函數移至該文件,把該文件添加到project中,注意該文件不能再選generate assembler SRC file和assemble SRC file選項。重新編譯工程
9***WARNING 2:REFERENCE MADE TO UNRESOLVED EXTERNAL
SYMBOL:MUSIC3
MODULE:C:\8051\MUSIC.OBJ(MUSIC)
ADDRESS:0018H
MUSIC3函數裡面MUSIC這個參數有使用,沒有申明。或者申明了沒有實體。也就是說對於這個參數,編譯器無法解析。
10 ***ERROR 107:ADDESS SPACE OVERFLOW
SPACE: DATA
SEGMENT: _DATA_GOUP_
LENGTH: 0018H

說明data空間已經不夠用,原因是你可能有好多函數,而函數內部的局部變量又沒有定義其空間,這種情況下,系統會將變量分配到你在Otions for Target 對話框裡的設置的空間。如果你在下圖所示中的 Memory Model 裡設置成 Small:variables in DATA,則DATA空間很快便用完,導致data空間不夠用。解決的辦法有兩種,一是通過更改Memory Model設置,可以設置成pdata或xdata,以便有足夠大的空間,但這又帶來新的問題,程序運行速度減慢,而且code代碼也會加大,因為如果一個局部變量被存放在了xdata空間,彙編語言訪問xdata空間的代碼大小要比訪問data空間的代碼大,變量一旦很多,程序的代碼也會逐漸增大;二是根據自己的要求設置變量的空間。所以這涉及到代碼優化的問題,遇到具體問題時,在運行速度和代碼大小之間取得適合自己的情況
Project---->Option for target---->BL51 Locate選項卡,如上圖紅圈部分所示,根據自己系統的存儲器分布情況,可以設置代碼區間和XDATA區間。通常默認情況下,代碼區間很小,所以會造成107號錯誤,根據需求,調大該範圍即可。

11ERROR L105: PUBLIC REFERS TO IGNORED SEGMENT

    SYMBOL:  USARTDATACOUNT

    SEGMENT: ?DT?USART_READWRITE

Ram空間不足:

外部變量:定義處不用加External,聲明處要加External

將以data 型別定義的公共變量修改為idata 型別的定義

12***ERROR 118: REFERENCE MADE TO ERRONEOUS EXTERNAL
SYMBOL: VOLUME
MODULE: C:\8051\OSDM.OBJ (OSDM)
ADDRESS: 4036H
定義了某某函數或全部變量在不同文件裡面想調用它,卻在包含頭文件裡面少了extern語句,或只有主程序和包含頭文件沒有(EXTERN.定義語句(函數)).

如果調試時有些if結構裡的語句符合條件沒有執行,或者某些語句不符合條件也被執行,那是因為if和else裡有相同的語句,編譯的時候作優化處理了。

13 WARNING 15 (MULTIPLE CALL TO SEGMENT) 症狀

原因

Warning 15向我們表明了linker發現了一個函數,這個函數不僅在main code裡被調用了,而且在ISR(或者被ISR調用的函數中)被調用了。或者是被同時被多個ISR同時調用了。

這樣會產生一個問題,就是在此函數不是一個可重入函數,而當此函數已經在執行時它可能被另一個ISR所調用。這樣就會導致結果是可變的而且很可能會導致一些參數的錯誤。

另一個問題就是本地變量和參數所使用的內存可能被其他函數的內存覆蓋。如果函數是由中斷所調用的,則此函數的內存就會被使用。這會引起其它函數的內存錯誤。

解決方法

有幾種方法去解決這個問題

如果你100%確認這個函數的兩個副本都不會同時執行(如果此函數是被main調用並且中斷是未被使能的)並且此函數沒有使用內存(只使用的寄存器),那麼你就可以忽略此警告

如果此函數使用了內存,你就要使用OVERLAY directive來將此函數從覆蓋分析(overlay anaysis)中移除。舉例如下:

 OVERLAY (?PR?_WRITE_GMVLX1_REG?D_GMVLX1 ! *)

如上語句能阻止被此函數使用的內存遭到覆蓋。如果這個函數調用了你程序中其他的在別處的函數,那麼你可能需要將這些函數也排除在覆蓋分析之外。

如果當此函數在執行時可以被調用,那麼事情就會變得比較的複雜。你可能需要:無論何時當從main中調用此函數時,需要關閉中斷。你可能需要對被調用的函數使用#pragma disable。你也必須使用OVERLAY directive將此函數從overlay analysis中移除。 為此函數創建兩個副本。一個給main,一個給ISR。

使此函數可重入。

14E:\VCWORK\2815.C(826): error C236: '_wrbyte': different length of parameter lists

子函數裡的形參聲明的方式不對,需要每個參數都定義一下類型

 

E:\VCWORK\2815.C(743): error C183: unmodifiable lvalue

出現error C183: unmodifiable lvalue的錯誤,最後發現時存在一個數組是uchar code xx[5],後邊把它用作接受串口的緩衝區,顯示uchar code是不能改變的,是寫在rom中的。應該改成uchar xx[5],這是寫在ram中的
原因:修改了不能改變的變量,

E:\VCWORK\2815.C(799): error C242: 'array[]': too many initializers

15 ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: _WRITE_DATA MODULE: .\ds18b20start.obj (DS18B20

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文件就不需要初始化過程啦)

14MAIN.C(85): warning C259: 'parameter': pointer: different mspace

原因,函數調用時候的實參和聲明時候的形參存儲空間不同,修改成一致即可。

16 E:\VC\2815\2815\FTOC.C(32): warning C231: '_memcpy': attempt to redefine intrinsic function

17*** ERROR L121: IMPROPER FIXUP

訪問內存指令超出指令的尋址範圍了,例如 MOVX @Ri 指令超出了PDATA段的範圍,或者是ACALL 指令超出了2k的尋址範圍.
檢查你的調用子函數的命令.特別是那些LCALL,ACALL等

18*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL

    SYMBOL:  MAIN

    MODULE:  C:\KEIL\C51\LIB\C51S.LIB (?C_INIT)

    ADDRESS: 080DH

在main函數裡面C_INIT這個參數有使用,沒有申明。或者申明了沒有實體。也就是說對於這個參數,編譯器無法解析。

  今天用Keil4寫程序時遇到這個問題:warning C316:unterminated conditionals

跑了幾個論壇,在審視了一遍代碼之後,知道了原因:

  像類似XX.C(99):warning C316:unterminated conditionals這種警告的話XX.c文件有一個凌亂的條件編譯或預編譯。因為C語言中有些頭文件中的預編譯或宏定義,那麼條件編譯就避免不了。寫條件編譯時,可能有忘寫一個基本的語句。比如說,你用了條件編譯#ifndef而忘記寫#endif。因為他們本來就是配套的。有前者必有後者。不能丟掉其中任何一個。一個include文件最後的#endif 少了# 前綴或者沒有#endif,都會出現類似警告。就像你寫C語句,你不會寫了 int i   而不能忘記寫 " ; " ,否者就不能把一個語句表達完整。

  總之,出現上述問題。先看看整個C文件中是否出現上述錯誤,或整個工程中自己寫的那些頭文件中裡面的條件編譯是否都寫對了,即:前面寫了#ifndef,後面是否有對應的#endif。

20 DS1302.C(86): error C183: unmodifiable lvalue

code的內容只能讀,不能改.    定義數組時把code去掉。

21  keil編譯警告 『Argument':conversion:pointer to non-pointer是什麼問題

應該是參數傳遞錯誤,指針參數處傳遞了非指針參數。

22 *** ERROR L114: SEGMENT DOES NOT FIT

塊大小與目標設備不符。段溢出了,你的DATA區超過了256位元組

你的idata變量太大(CEH),與器件容量不匹配。可能你的單片機型號選成31了,選個256位元組內部RAM的應該就行,將定義為data的變量定義為xdata類型,問題解決了。

23 error C193 :bad operand type

%  取模不能用浮點數,

frequence  要轉成整型來取模,小數位可以乘10後轉整型來得到。

 


 長按識別圖中二維碼關注我們

單片機系列

  看完的同時,請分享到朋友圈

  每天更新單片機各種知識,電子

  製作DIY,及電子行業最新資訊

                   衷心的感謝您的支持


相關焦點

  • 單片機keil 常見問題
    一、混合編程1、模塊內接口:使用如下標誌符:#pragma asm彙編語句#pragma endasm注意:如果在c51程序中使用了彙編語言
  • 簡析單片機keil常見問題
    一、混合編程  1、模塊內接口:  使用如下標誌符:  #pragma asm  彙編語句  #pragma endasm  注意:如果在c51程序中使用了彙編語言,注意在keil編譯器中需要激活Properties中的「
  • keil C語言與彙編語言混合編程
    不同類型的數據及其傳遞參數的寄存器如下表所示: 在C和彙編混合編程的時候,存在C語言和彙編語言的變量以及函數的接口問題。在C程序中定義的變量,編譯為.asm文件後,都被放進了.bss區,而且變量名的前面都帶了一個下劃線。
  • 學單片機如何編程?非常詳細的Keil工程建立全過程講解
    相信用過彙編語言後再使用C來開發,體會更加深刻,當然如果彙編語言和硬體結構熟練到一定程度,使用彙編語言會更具優勢,但對於大部分初學者而言,Keil C51應該是首選。掌握這一軟體的使用對於使用51系列單片機的愛好者來說是十分必要的,即使不使用C語言而僅用彙編語言編程,其方便易用的集成環境、強大的軟體仿真調試工具也會令你事半功倍。
  • 單片機C語言模塊化編程方法
    初學者往往搞不懂如何模塊化編程,其實它是簡單易學,而且又是組織良好程序結構行之有效的方法之一.本文將先大概講一下模塊化的方法和注意事項,最後將以初學者使用最廣的keil c編譯器為例,給出模塊化編程的詳細步驟。
  • Keil編譯常見問題
    需要將.C文件添加到工程文件中warning: #1-D main.c(7): warning: #1-D: last line of file ends without a newline當使用keil編譯時,彈出這樣的警告信息:main.c(7): warning: #1-D: last line of file ends without a newline
  • 在keil中怎麼燒寫程序
    打開APP 在keil中怎麼燒寫程序 發表於 2017-11-16 10:52:58   什麼是keil
  • 單片機的程式語言:彙編語言、C語言、PL/M和BASIC語言
    單片機系統同樣也由硬體系統和軟體系統構成,因此涉及到程序的編寫問題。單片機的程式語言很多,目前常見的程式語言有4種,即彙編語言、C語言、PL/M和BASIC語言。下面我們來介紹一下吧:一、BASIC程式語言BASIC是一種高級語言,它的英文含義是「初學者通用符號指令代碼」,是在1965年5月,由美國科學家託馬斯•庫爾茲研製出來的。
  • DS80C400的Keil C語言編程
    簡單程序,如網絡揚聲器,可以用彙編語言輕鬆實現,更複雜一點的,如HTTP伺服器這種需要與文件系統交互的程序,可以使用C語言。 文中介紹了如何從Keil的uVision2開發套件著手構建一個DS80C400的C語言應用程式,通過實現一個簡單的HTTP伺服器演示如何使用DS80C400的ROM功能。
  • KEIL4 工程到 KEIL5 程序的移植方法
    首先我們用 keil5 打開 keil4 的工程, 則會彈出下面的窗口, 這就是我們程序兼容的關鍵。此文件在Keil4.7裡沒有,需要在網上下載一份,然後放 發表於 2020-06-13 keil4.74中運行s3c2440程序出現警告 進行一步驟修改 安裝提示 一步一步的修改 解析 警告  warning: A1608W:
  • 自學單片機第三篇:keil軟體
    官網的軟體各方面都有保證,英文並不影響使用,因為我們能用的功能項目,位置就那幾個,記住就好了,而且不用擔心莫名其妙的問題。打開官網,點擊上方的「download」進入下載頁面。圖標雙擊打開軟體,界面如下。第一個選項是文件,下拉表中,我們當前要點擊下圖黃色部分,安裝證書。
  • C/C+編程筆記:C語言編程面試常見問題,全是經典題!
    如果有剛剛學習編程的小夥伴也可以看一下,都是當時大學應該學懂的,但是因為我以前沒有好好聽課,有些也沒有注意到,現在也是提醒大家吧~ C語言的主要特徵是什麼? C是一種過程語言。
  • 單片機模塊化編程的原則有哪些
    目前我們在學習和開發單片機時廣泛採用 c 語言進行編程,當我們開發的單片機項目較小時,或者我們所寫的練習程序很小時,我們總是習慣於將所有代碼編寫在同一個 c 文件下,由於程序代碼量較少,通常為幾十行或者上百行, 此時這種操作是可行方便的, 也沒有什麼問題。
  • 單片機程式語言的比較
    例如,懂得彙編語言指令就可以使用在片內ram作變量的優勢,因為片外變量需要幾條指令才能設置累加器和數據指針進行存取。同樣的,當要求使用浮點數和啟用函數時也只有具備彙編編程經驗才能避免生成龐大的、效率低的程序,對於這方面的編程,沒有彙編語言是做不到的。
  • 被雙十一套路所傷的,請到這裡取暖——「 用 C語言編寫自己的程式語言 」
    如果你的目標不僅僅是一個碼農,而是軟體工程師,那你應該好好看看本課,相信會對你了解程式語言的設計思想,實現高質量編程會有很大的幫助。1. 內容簡介我們在學習程式語言的時候會學到很多的語法規則,很多巧妙的用法,這些都是怎麼實現的?
  • 單片機編程軟體大佬:明確單片機編程軟體編寫單片機程序步驟
    單片機用什麼軟體編程?單片機開發中除必要的硬體外,同樣離不開軟體,我們寫的彙編語言源程序要變為CPU可以執行的機器碼有兩種方法,一種是手工彙編,另一種是機器彙編,目前已極少使用手工彙編的方法了。機器彙編是通過彙編軟體將源程序變為機器碼,用於MCS-51單片機的彙編軟體有早期的A51,隨著單片機開發技術的不斷發展,從普遍使用彙編語言到逐漸使用高級語言開發,單片機的開發軟體也在不斷發展,Keil軟體是目前最流行開發MCS-51系列單片機的軟體,這從近年來各仿真機廠商紛紛宣布全面支持Keil即可看出。
  • 人工智慧機器人研發的十大熱門程式語言:不死 Java、不朽 C/C ++,以及新貴 Python
    流水的程式語言,鐵打的 Java、C/C++。進行人工智慧機器人研發,應該選擇哪種程式語言?這是很多機器人專家在自身的職業生涯中都會存在的一個入門級思考。畢竟,在學習一門程式語言時,需要花費大量的時間及精力,如果掌握了這門語言卻又不發揮其真實的價值,又有什麼用呢?但不幸的是,到目前為止,也沒有一個確切而直接的答案出現。
  • 做嵌入式編程,為什麼用的是C語言而不是C++呢?
    C語言發展到現在,差不多50年的時間了,現在正是c語言過渡到C++語言成為嵌入式開發主流語言的最佳契機。 對於習慣了用C語言開發的嵌入式程式設計師來說,對C++語言是有一些誤解和偏見的。
  • 程式語言學哪個比較好?2019年最實用的程式語言
    學習編程關鍵是要找到一種合適的語言,那麼程式語言那麼多,該如何選擇?下面萬古網校小編為大家分享一篇關於程式語言選擇的文章,希望能給你帶來幫助!第一大類語言包括Java、C、Python和C++。這類語言都是非常通用的語言,它們並不局限於特定的編程平臺或用途。
  • 單片機與C語言——keil c51教程(1)
    單片機C語言教程(一) 學習單片機實在不是件易事,一來要購買高價格的編程器,仿真器,二來要學習程式語言,還有眾多種類的單片機選擇真是件讓人頭腦的事