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