專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

IAR編譯器的常見(jiàn)問(wèn)題

作者:佚名   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2013年10月21日   【字體:

最近因?yàn)轫?xiàng)目需要開(kāi)始使用IAR for AVR,我用的是5.40版本的,主要是5.40以上才包括了aTtiny87,至于安裝文件和和諧文件,大家自己找吧,很好找的。

       

1.編譯報(bào)錯(cuò)如圖所示:

很顯然你沒(méi)有使能寄存器的位定義。方法如下:Project ——> Option ——> General Options ——> System(如下圖所示),勾選

Enable bit definitions in I/O-Include files即可

 

2.MCU型號(hào)選擇

 

如果和我一樣都次都是以空工程創(chuàng)建的話,不過(guò)忘了第一步先進(jìn)Project ——> Option ——> General Options ——> Target選擇所使用的MCU型號(hào),不然編譯免不了要報(bào)錯(cuò),如下圖所示。

 

3. 堆棧大小

  今天下午編譯一個(gè)程序,0錯(cuò)誤0警告,挺好,可一運(yùn)行就跑飛,根本不能正常運(yùn)行。

  其實(shí)是我沒(méi)有正常設(shè)置堆棧大小導(dǎo)致的這種問(wèn)題,尤其是在寫(xiě)大工程時(shí),這種錯(cuò)誤出現(xiàn)的概率很高。GCC和IAR分配堆棧的方式不同,IAR先分配堆?臻g,相當(dāng)于定義一個(gè)全局?jǐn)?shù)組為堆?臻g,堆棧初始為堆?臻g最高地址;GCC不用先分配堆棧,自動(dòng)把RAM剩余空間作為堆?臻g,堆棧初始為RAM最高地址。

先編譯看看自己的程序用了多少ram,在看看總共有多少ram。

然后Project ——> Option ——> Linker ——> List選擇生成LIST文件,并包含stack選項(xiàng),如下圖所示。

 

在./Debug/list目錄下,得到.map(可能是.lst等其他格式)文件,用記事本打開(kāi),找到以下內(nèi)容:

****************************************
* *
*               CALL GRAPH                     *
* *
****************************************

->Sub-tree of type: Interrupt function tree that does not make
: indirect calls
CSTACK
| Stack used (prev) : 00000000
01 int_T0_OV
| Stack used (prev) : 00000000
| + function block : 0000000C

......(省略N行)

01 main
| Stack used (prev) : 0000003A
| + function block : 00000000
<-Sub-tree of type: Function tree
| Stack used : 000000E2

找到最大的Stack used,我的就是000000E2,這就是用到的最大的堆?臻g,保守一點(diǎn),我設(shè)置成0x100字節(jié),沒(méi)有超過(guò)剩余RAM,再重新編譯,運(yùn)行,仿真器沒(méi)有堆棧不足警告,程序也能正常運(yùn)行了。

 

如下圖所示:

 

4. 查看匯編

相信一個(gè)優(yōu)秀的單片機(jī)軟件工程師都多多少少會(huì)去看看編譯器的匯編代碼,看看有沒(méi)有什么問(wèn)題或者看看編譯器有沒(méi)有自作聰明的做些什么

Project ——> Option ——> C/C++ complier ——> List,勾選output assembler files,編譯后則生成離線匯編代碼文件

此時(shí)在工程目錄下的Debug-->List即可看到所有參加編譯的C文件對(duì)應(yīng)的匯編文件,后綴名為*.s90

 

5.內(nèi)聯(lián)函數(shù)

inline函數(shù)傳統(tǒng)上只有C++支持,但I(xiàn)AR EW也支持在C代碼中使用inline.
#pragma inline:建議編譯器對(duì)緊隨其后的函數(shù)進(jìn)行inline處理
#pragma inline = forced: 強(qiáng)制編譯器對(duì)緊隨其后的函數(shù)進(jìn)行inline處理

/***************************** 錯(cuò)誤描述 ******************************************/
// tft.c中定義內(nèi)聯(lián)函數(shù)
#pragma inline = forced          //強(qiáng)制inline
void TFT_Write_Colour(const RGB_COLOUR *rgb)
{ 
  //...code....
}

// tft.h中聲明函數(shù)
void TFT_Write_Colour(const RGB_COLOUR *rgb);

// main.c中調(diào)用函數(shù)
// 編譯報(bào)錯(cuò):main中引用了未定義的外部函數(shù)TFT_Write_Colour。


/***************************** 解決辦法 ******************************************/
// tft.h中“定義函數(shù)”
#pragma inline = forced          //在IAR EW430中,這里必須用強(qiáng)制inline;用inline可能導(dǎo)致編譯器忽略內(nèi)聯(lián),而定義成普通函數(shù)而出錯(cuò)。
void TFT_Write_Colour(const RGB_COLOUR *rgb)
{ 
  //...code....
}

// main.c中包含tft.h,并調(diào)用函數(shù)
// 結(jié)果:編譯正確

 

 6. 如何把變量定義到flash空間

unsigned char __flash temptab[] = {1,2,3,4,5};  <br>__flash unsigned char a @ 0x8; // 定義變量存放在flash 空間0X08單元

 

7. 關(guān)于內(nèi)存模型

AVR 微控制器的其中一個(gè)特點(diǎn)是它有一種存儲(chǔ)器訪問(wèn)方法均衡了“cheap access limited to small memory areas”與“more expensive accessmethods that can access any location in memory”。
在AVR_IAR C/C++編譯器中,通過(guò)選擇某種存儲(chǔ)模式(memory model),可設(shè)置一些訪問(wèn)方法為默認(rèn)的存儲(chǔ)器訪問(wèn)方法(default memory accessmethod)。共有三種可用的存儲(chǔ)模式——Tiny,Small 和Large。你的處理器選項(xiàng)決定了哪些模式可以使用。如果你不指定一種存儲(chǔ)模式,則編譯器自動(dòng)設(shè)定-v0、-v1、-v2、-v3、-v5 選項(xiàng)下的默認(rèn)方法為T(mén)iny,-v4 和-v6 選項(xiàng)下的訪問(wèn)方法為Small。  

 

8. 關(guān)于生成文件格式的設(shè)置

如圖,在linker -> outpu ->other中可設(shè)置相應(yīng)的輸出文件格式.

比如要生成bin格式,選擇raw-binary就可以了, 如果是要生成hex格式,那么可以選intel-extern ,不過(guò)這個(gè)時(shí)候文件擴(kuò)展名是*.a90,可以把"Override default " 打鉤,然后修改后綴名為hex就行了.

------------------------------------------------------------------------------------------------------------------

關(guān)閉窗口

相關(guān)文章