IAR的MSP430 C編程基礎(chǔ)知識
好,我們從新建一個工程開始,打開IAR,空白,project,create new project,C,main,確定。給工程起個名字,保存。OK,工程建立完畢了。這時工程里已經(jīng)有個main.c了,并且有一個完整的程序,如下:
#include "io430.h"
int main( void )
{
}
Make一下,保存工作區(qū)文件,就可順利編譯通過了。
(本人所使用的IAR版本為5.3,為了能體驗更好的IAR特性,請使用較新且較穩(wěn)定的版本)
從頭文件包含說起,這個io430.h是IAR為C語言所推薦的頭文件,這個頭文件以匿名結(jié)構(gòu)體的形式對430的寄存器進(jìn)行聲明,匿名結(jié)構(gòu)體已經(jīng)在C11中納入標(biāo)準(zhǔn)C,這種聲明方式在ARM中廣為流傳。之前較早的版本可能使用的是msp430.h,這個頭文件都是以宏定義的形式對寄存器進(jìn)行聲明的,C和匯編都可以包含此文件,這里有豐富的宏定義,如SELA__REFOCLK,選擇REFOCLK作為ACLK。這在io430.h是沒有的,因此如果以前的工程包含的是msp430.h,那么移植到使用io430.h將會出現(xiàn)一些問題。
頭文件的選擇根據(jù)自己的習(xí)慣決定,但是像畫蛇添足一樣把頭文件改成#inlcude “msp430f149.h”就沒有必要了,因為IAR已經(jīng)自動幫我們選擇了合適的頭文件,這在移植到其他的器件時,不用做任何更改;我們所要做的就是在工程的option中,選擇我們的device,我們新建的這個工程默認(rèn)的device為msp430f149,現(xiàn)在我們更換器件為msp430f5418A,重新make一下。我們來看工程左邊的文件拓?fù)浣Y(jié)構(gòu),如圖1.1:
1.
2.
現(xiàn)在來了解一下一個耳熟的詞匯:C運(yùn)行時庫
眾所周知,在單片機(jī)上電瞬間,只有flash中有數(shù)據(jù)和代碼,RAM的內(nèi)容是不確定的。單片機(jī)執(zhí)行的第一條指令絕對不是main函數(shù),而是C運(yùn)行時庫的初始化函數(shù),為我們寫的C代碼搭建C運(yùn)行時環(huán)境。首先設(shè)置SP,也就是設(shè)置棧,SP通常設(shè)置為RAM的最高地址。其次就是初始化內(nèi)存,初始化全局變量,靜態(tài)變量,以及在RAM中的函數(shù),這些數(shù)據(jù)都是從flash中拷貝過來的,因此我們的變量不僅僅占用著RAM,還有可能占據(jù)著一份flash(未初始化的全局變量和靜態(tài)變量初始化為0,將未初始化的數(shù)據(jù)放在一個區(qū)域,只需要將這個區(qū)域清0即可,不需要從flash拷貝)。數(shù)據(jù)初始化完畢后就開始從main函數(shù)開始了,執(zhí)行我們所寫的代碼。因為430的看門狗在復(fù)位之后是開著的,因此需要初始化數(shù)據(jù)量過大的話,就有可能導(dǎo)致看門狗溢出復(fù)位,從而main函數(shù)永遠(yuǎn)得不到執(zhí)行。解決此問題的辦法就是在程序中加入一個函數(shù):int __low_level_init(void),在此函數(shù)中加入停止看門狗的語句,并返回1即可,__low_level_init函數(shù)將在初始化代碼之前執(zhí)行。
注:初始化代碼并未包含在dl430xsfn.r43中,應(yīng)該是由編譯器單獨(dú)生成的一段代碼,我理解這些代碼應(yīng)該屬于C運(yùn)行時庫的范疇。這都是我的個人見解。
C運(yùn)行時庫還包含著所有的C標(biāo)準(zhǔn)庫,如strlen、memcpy等函數(shù);還有乘除法的實現(xiàn)等等。
評論