stm8的C語(yǔ)言編程(1)--基本程序與啟動(dòng)代碼分析
現(xiàn)在幾乎所有的單片機(jī)都能用C語(yǔ)言編程了,采用C語(yǔ)言編程確實(shí)能帶來(lái)很多好處,至少可讀性比匯編語(yǔ)言強(qiáng)多了。 在STM8的開(kāi)發(fā)環(huán)境中,可以通過(guò)新建一個(gè)工程,自動(dòng)地建立起一個(gè)C語(yǔ)言的框架,生成后開(kāi)發(fā)環(huán)境會(huì)自動(dòng)生成2個(gè)C語(yǔ)言的程序,一個(gè)是main.c,另一個(gè)是stm8_interrupt_vector.c。main.c中就是一個(gè)空的main()函數(shù),如下所示:
/* MAIN.C file * * Copyright (c)2002-2005 STMicroelectronics */
main() { while (1); }
而在stm8_interrupt_vector.c中,就是聲明了對(duì)應(yīng)該芯片的中斷向量,如下所示: /* BASICINTERRUPT VECTOR TABLE FOR STM8 devices * Copyright (c) 2007 STMicroelectronics */
typedef void @far(*interrupt_handler_t)(void);
struct interrupt_vector { unsigned char interrupt_instruction; interrupt_handler_t interrupt_handler; };
@far @interrupt voidNonHandledInterrupt (void) { /* in order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction */ return; }
extern void_stext(); /* startup routine */
struct interrupt_vectorconst _vectab[] = { {0x82, (interrupt_handler_t)_stext}, /* reset */ {0x82, NonHandledInterrupt}, /* trap */ {0x82, NonHandledInterrupt}, /* irq0 */ {0x82, NonHandledInterrupt}, /* irq1 */ {0x82, NonHandledInterrupt}, /* irq2 */ {0x82, NonHandledInterrupt}, /* irq3 */ {0x82, NonHandledInterrupt}, /* irq4 */ {0x82, NonHandledInterrupt}, /* irq5 */ {0x82, NonHandledInterrupt}, /* irq6 */ {0x82, NonHandledInterrupt}, /* irq7 */ {0x82, NonHandledInterrupt}, /* irq8 */ {0x82, NonHandledInterrupt}, /* irq9 */ {0x82, NonHandledInterrupt}, /* irq10 */ {0x82, NonHandledInterrupt}, /* irq11 */ {0x82, NonHandledInterrupt}, /* irq12 */ {0x82, NonHandledInterrupt}, /* irq13 */ {0x82, NonHandledInterrupt}, /* irq14 */ {0x82, NonHandledInterrupt}, /* irq15 */ {0x82, NonHandledInterrupt}, /* irq16 */ {0x82, NonHandledInterrupt}, /* irq17 */ {0x82, NonHandledInterrupt}, /* irq18 */ {0x82, NonHandledInterrupt}, /* irq19 */ {0x82, NonHandledInterrupt}, /* irq20 */ {0x82, NonHandledInterrupt}, /* irq21 */ {0x82, NonHandledInterrupt}, /* irq22 */ {0x82, NonHandledInterrupt}, /* irq23 */ {0x82, NonHandledInterrupt}, /* irq24 */ {0x82, NonHandledInterrupt}, /* irq25 */ {0x82, NonHandledInterrupt}, /* irq26 */ {0x82, NonHandledInterrupt}, /* irq27 */ {0x82, NonHandledInterrupt}, /* irq28 */ {0x82, NonHandledInterrupt}, /* irq29 */ }; 在stm8_interrupt_vector.c中,除了定義了中斷向量表外,還定義了空的中斷服務(wù)程序,用于那些不用的中斷。當(dāng)然在自動(dòng)建立時(shí),所有的中斷服務(wù)都是空的,因此,除了第1個(gè)復(fù)位的向量外,其它都指向那個(gè)空的中斷服務(wù)函數(shù)。 生成框架后,就可以用Build菜單下的Rebuild All對(duì)項(xiàng)目進(jìn)行編譯和連接,生成所需的目標(biāo)文件,然后就可以加載到STM8的芯片中,這里由于main()函數(shù)是一個(gè)空函數(shù),因此沒(méi)有任何實(shí)際的功能。不過(guò)我們可以把這個(gè)框架對(duì)應(yīng)的匯編代碼反出來(lái),看看C語(yǔ)言生成的代碼,這樣可以更深入地了解C語(yǔ)言編程的特點(diǎn)。 生成的代碼包括4個(gè)部分,如圖1、圖2、圖3、圖4所示。
0.jpg (337.92 KB, 下載次數(shù): 110)
下載附件
2016-12-30 01:48 上傳
圖1
1.jpg (36.48 KB, 下載次數(shù): 120)
下載附件
2016-12-30 01:48 上傳
圖2
2.jpg (250.22 KB, 下載次數(shù): 118)
下載附件
2016-12-30 01:48 上傳
圖3
3.jpg (25.9 KB, 下載次數(shù): 109)
下載附件
2016-12-30 01:48 上傳
圖4
圖1顯示的是從內(nèi)存地址8000H開(kāi)始的中斷向量表,中斷向量表中的第1行82008083H為復(fù)位后單片機(jī)運(yùn)行的第1跳指令的地址。從表中可以看出,單片機(jī)復(fù)位后,將從8083H開(kāi)始運(yùn)行。其它行的中斷向量都指向同一個(gè)位置的中斷服務(wù)程序80D0H。 圖2顯示的是3個(gè)字節(jié),前2個(gè)字節(jié)8083H為復(fù)位后的第1條指令的地址,第3個(gè)字節(jié)是一個(gè)常量0,后面的啟動(dòng)代碼要用到。 圖3顯示的是啟動(dòng)代碼,啟動(dòng)代碼中除了初始化堆棧指針外,就是初始化RAM單元。由于目前是一個(gè)空的框架,因此在初始化完堆棧指針(設(shè)置成0FFFH)后,由于8082H單元的內(nèi)容為0,因此程序就跳到了80B1H,此處是一個(gè)循環(huán),將RAM單元從0到5初始化成0。然后由于寄存器X設(shè)置成0100H,就直接通過(guò)CALL main進(jìn)入C的main()函數(shù)。 圖4顯示的是main()函數(shù)和中斷服務(wù)函數(shù),main()函數(shù)對(duì)應(yīng)的代碼就是一個(gè)無(wú)限的循環(huán),而中斷服務(wù)函數(shù)就一條指令,即中斷返回指令。
通過(guò)分析,可以看出用C語(yǔ)言編程時(shí),比匯編語(yǔ)言編程時(shí),就是多出了一段啟動(dòng)代碼。
|