2017-04-10 149 views
2

有人可以幫助嗎?PIC18變量聲明和初始化失敗硬件

總結:聲明和初始化變量在PIC硬件中不起作用 - 但它在仿真中工作正常。另外,如果變量是一個結構,這個問題似乎更糟。我正在使用:Explorer 8板上的MPLAB X IDE V3.55,XC8 V1.41,PIC18F26K40和PICKIT3調試器電纜。

詳情:

對於這樣一個簡單的例子:

uint8_t myvar = 0x55; 

void main(void) 
{ 
    uint8_t var = myvar; 
} 

在調試器MYVAR使用變量窗口始終是零,當我在硬件上運行此。但是,如果我在模擬器中運行相同的代碼,那一切都OK!

我:

  • 打破了問題到能重現問題
  • 嘗試禁用編譯器優化的最簡單的形式 - 不解決這個問題

檢查「文件的值註冊調試器窗口。在硬件中運行時,我看不到0x55 - 但它在模擬器中(地址爲0x21)。

它在硬件的工作,如果:

  • MYVAR聲明並初始化爲一個const
  • MYVAR聲明和本地初始化(內部主)

現在,如果我使用結構類型,而不是一個簡單的uint8_t像:

typedef struct { 
    uint8_t a; 
    char b[8]; 
}MYSTRUCT; 

MYSTRUCT ms = { 0x55, "HELLO" }; 

void main(void) 
{ 
    uint8_t var = ms.a; 
} 

所述MS變量是初始在模擬中正確使用,但不是硬件。這次如果變量是以main或全局聲明的話,它不會初始化。同樣,聲明爲const也行。 所以似乎有不一致的位置:

           uint8_t  struct type 
global variable declaration and initialisation  N  N 
global const declaration and initialisation  Y  Y 
local variable declaration and initialisation  Y  N 

經過調試,並彙編(。作爲)通過步進文件,它看起來就像myvar可以嘗試進行初始化,但由於某種原因,只是不以硬件。 請參閱下面的.as文件中的相關行。在關鍵階段的地址和值顯示爲在仿真過程中從調試器捕獲。您可以在末尾看到'__pdataCOMRAM'(指向myVar的ram的指針)被賦值爲0x55。如果我在硬件中逐步完成所有步驟都是相同的,但是當我們到達末尾時'__pdataCOMRAM'的值不是0x55,而是0x00。

            Address Value 

global __pdataCOMRAM 
__pdataCOMRAM: 
    file "main.c" 
    line 32 
global _myVar 
    myVar:           0x21 0x00 
    ds  1   
    file "dist/C18_18F87K22/debug\initTest.X.debug.as"  
    line #  
psect cinit  
; Initialize objects allocated to COMRAM (1 bytes)  
    global __pidataCOMRAM        0x144 0xff55 
    ; load TBLPTR registers with __pidataCOMRAM 
    movlw low (__pidataCOMRAM)   
    movwf tblptrl  
    movlw high(__pidataCOMRAM)   
    movwf tblptrh  
    movlw low highword(__pidataCOMRAM)   
    movwf tblptru  
    tblrd*+ ;fetch initializer   
    movff tablat, __pdataCOMRAM+0     0x21  0x55 

我做了愚蠢的事情在這裏還是有我丟失或者是一個編譯器或調試錯誤編譯器選項? 我想了解這個問題,所以我不會在我的發展中陷入任何陷阱。

乾杯, 史蒂夫

+0

我想你應該看看你的鏈接腳本。據我所知,啓動代碼不會執行從閃存'.data'部分的副本以衝擊初始化全局變量。看起來,所有的全局變量都被認爲是'.bss'節,因此在啓動時將其歸零。你有沒有試圖聲明爲靜態'uint8_t myvar = 0x55'? – LPs

+0

這是微控制器編程中一個非常常見的錯誤。我不知道這個特定的工具鏈,但可能你已經創建了一個「最小啓動」或「快速啓動」或類似的項目。創建一個新項目,看看是否有一些選項叫做「標準啓動」,「ANSI啓動」或類似的東西。 – Lundin

+0

優化編譯器可以放棄整個'uint8_t var = myvar;'var''作爲'var'從不使用。用'var'做一些事情,不需要使用調試器即可看到。 – chux

回答

2

它似乎有一種被稱爲硅問題進行復位後立即停止訪問程序存儲器。有一個ERRATA宏'NVMREG'作爲解決方法。要解決的具體步驟如下: 設置項目選項'Conf'>'XC8全局選項'>'XC8鏈接器'選擇'其他選項'類別,然後將NVMREG添加到勘誤選項。 然後一切正常。 在微芯片論壇上登錄1and0

+1

好。我很高興我離開了Microchip世界...... – LPs