- 基于ARM Cortex-M3的STM32系列嵌入式微控制器應(yīng)用實(shí)踐
- 彭剛 秦志強(qiáng)編著
- 1681字
- 2018-12-27 16:01:42
1.3 創(chuàng)建工程和執(zhí)行程序
你編寫和執(zhí)行的第一個(gè)C語言程序?qū)⒏嬖VSTM32微控制器,讓它發(fā)送一條消息給PC機(jī)或筆記本電腦。
任務(wù)四 你的第一個(gè)工程
雙擊Keil u Vision3的圖標(biāo),啟動(dòng)Keil uVision3程序,你會得到圖1.10所示的Keil u Vision3的IDE主界面。IDE表示Integrated Development Environment,即集成開發(fā)環(huán)境。Keil提供了包括C編譯器、宏匯編、連接器、庫管理及一個(gè)功能強(qiáng)大的仿真調(diào)試器在內(nèi)的完整開發(fā)方案,通過一個(gè)集成開發(fā)環(huán)境(u Visoin)將這些部分組合在一起,其軟件開發(fā)邏輯結(jié)構(gòu)如圖1.11所示。掌握這一軟件的使用,對于進(jìn)行單片機(jī)或ARM系統(tǒng)開發(fā)者來說是十分必要的,如果你使用C語言編程,那么Keil是你的不二之選,即使不使用C語言而僅用匯編語言編程,其方便易用的集成環(huán)境、強(qiáng)大的軟件仿真調(diào)試工具也會令你事半功倍。

圖1.10 Keil uVision3的IDE主界面

圖1.11 Keil軟件開發(fā)邏輯結(jié)構(gòu)圖
集成開發(fā)環(huán)境
早期的程序設(shè)計(jì)各個(gè)階段都要用不同的軟件來進(jìn)行處理,如先用字處理軟件編輯源程序,然后用鏈接程序進(jìn)行函數(shù)、模塊連接,再用編譯程序進(jìn)行編譯,開發(fā)者必須在幾種軟件間來回切換操作。現(xiàn)在的編程開發(fā)軟件將編輯、編譯、調(diào)試等功能集成在一個(gè)桌面環(huán)境中,這樣就大大方便了用戶。這就是集成開發(fā)環(huán)境(簡稱IDE)。IDE是一個(gè)用于程序開發(fā)的應(yīng)用程序,一般包括代碼編輯器、編譯器、調(diào)試器和圖形用戶界面工具等一體化的開發(fā)軟件服務(wù)套件。所有具備這一特性的軟件或者軟件套件(組)都可以叫做集成開發(fā)環(huán)境。比如,微軟的Visual Studio.Net系列,可以稱為C++、VB、C#等語言的集成開發(fā)環(huán)境。
通過用Project菜單中的New Project命令建立項(xiàng)目文件(工程文件),過程如下:
(1)創(chuàng)建HelloRobot文件夾,將提供的library文件夾,stm32f10x_heads.h文件和HelloRobot.h文件復(fù)制到此目錄下。library文件夾里面的文件是STM32庫文件。
(2)單擊Project,會出現(xiàn)圖1.12所示的畫面,然后選擇New u Vision Project,彈出Create New Project對話框,找到剛才建立好的HelloRobot目錄,如圖1.13所示。

圖1.12 Keil uVision3工程菜單畫面

圖1.13 Create New Project對話框
(3)雙擊HelloRobot文件夾,在文件名中輸入工程文件名:HelloRobot(可不用加后綴名),保存在此目錄下,如圖1.14所示。之后單擊“保存”出現(xiàn)圖1.15所示的窗口。

圖1.14 創(chuàng)建HelloRobot工程

圖1.15 Select Device for Target ‘Target 1’ 對話框
(4)這里要求選擇芯片的類型,雙擊STMicroelectronics,在彈出的下拉菜單中選擇STM32F103xx(與教學(xué)開發(fā)板一致),就會出現(xiàn)相關(guān)介紹信息。例如選擇STM32F103VB,如圖1.16所示。看看選擇不同的STM32F103xx單片機(jī),所顯示的資源有哪些不同。

圖1.16 CPU型號選擇窗口
(5)按OK確定,出現(xiàn)圖1.17所示窗口。詢問是否加載啟動(dòng)代碼,在這里選擇“否”,不加載(后面將會手工裝載啟動(dòng)代碼:cortexm3_macro.s,stm32f10x_vector.s,而不用系統(tǒng)提供的默認(rèn)啟動(dòng)代碼)。選擇“否”后將出現(xiàn)圖1.18所示窗口,此時(shí)項(xiàng)目文件,即工程文件就創(chuàng)建好了。

圖1.17 是否加載啟動(dòng)代碼提示窗口

圖1.18 目標(biāo)工程窗口
啟動(dòng)代碼
啟動(dòng)代碼(Bootloader)是嵌入式系統(tǒng)啟動(dòng)時(shí)常見的一小段代碼,類似于啟動(dòng)計(jì)算機(jī)時(shí)的BIOS,一般用于完成CPU的初始化工作和自檢。其他常見的啟動(dòng)代碼比如ARM9嵌入式系統(tǒng)中的UBoot或Vivi等。同一型號的CPU啟動(dòng)代碼會隨著開發(fā)板的設(shè)計(jì)不同而略有不同。
STM32這兩個(gè)啟動(dòng)代碼主要完成處理器的初始化工作。其中,啟動(dòng)文件cortexm3_macro.s的作用:定義Cortex-M3宏指令操作,這些宏指令操作可供用戶在C中調(diào)用。如在C文件中有必要使用匯編指令和這些宏指令做預(yù)處理時(shí),只要直接在C代碼中使用EXPORT后面的宏指令操作就可以了(類似于在C中嵌入?yún)R編的操作);啟動(dòng)文件stm32f10x_vector.s的作用:初始化堆棧,定義程序啟動(dòng)地址、中斷向量表和中斷服務(wù)程序入口地址,以及系統(tǒng)復(fù)位啟動(dòng)時(shí),從啟動(dòng)代碼跳轉(zhuǎn)到用戶main函數(shù)入口地址。
查看HelloRobot目錄,你會發(fā)現(xiàn)HelloRobot.uv2工程文件。另外,opt文件是關(guān)于工程開發(fā)環(huán)境的參數(shù)配置和選項(xiàng)設(shè)置文件(Option File)。plg文件是編譯日志文件(Compile Log File),存放編譯器的編譯結(jié)果,編譯時(shí)采用的命令參數(shù),已經(jīng)編譯后得到的錯(cuò)誤和警告信息。
項(xiàng)目文件(工程文件)
在當(dāng)今的應(yīng)用軟件開發(fā)中,一個(gè)軟件系統(tǒng)是由工程文件組成,工程文件包含若干個(gè)程序文件、頭文件、甚至庫文件。類似一本書,有目錄和各個(gè)章節(jié);或者像一個(gè)公司,有好多部門。uv2文件是51、STM32等單片機(jī)或者ARM的Keil項(xiàng)目文件(工程文件),打開它就打開了這個(gè)工程,即與應(yīng)用程序相關(guān)的全部文件和相應(yīng)的設(shè)置。它包括的文件有頭文件、源文件、匯編文件、庫文件、配置文件等。這些文件的有關(guān)信息就保存在稱為“工程”的文件中,每次保存工程時(shí),這些信息都會被更新。在Keil中使用工程文件來管理構(gòu)成應(yīng)用程序的所有文件,而且編譯生成的可執(zhí)行文件是與項(xiàng)目文件(工程文件)同名。
任務(wù)五 你的第一個(gè)程序
項(xiàng)目文件創(chuàng)建后,這時(shí)只有一個(gè)框架,緊接著需要向項(xiàng)目文件中添加程序文件內(nèi)容。Keil uVision支持C語言程序。可以是已經(jīng)建立好的程序文件,也可以是新建的程序文件。如果是建立好了的程序文件,則直接用后面的方法添加;如果是新建立的程序文件,則先將程序文件.c存盤后再添加。
首先,先添加啟動(dòng)代碼(匯編文件):cortexm3_macro.s,stm32f10x_vector.s。右鍵單擊“Source Group 1”,單擊“Add Files to Group‘Source Group 1’”,如圖1.19所示。

圖1.19 添加文件
在彈出的對話框中選擇文件類型,然后選中兩個(gè)啟動(dòng)代碼,單擊“Add”按鈕添加進(jìn)工程文件中,再單擊“Close”關(guān)閉此對話框,如圖1.20所示。

圖1.20 添加啟動(dòng)代碼
文件添加到項(xiàng)目文件中去后,這時(shí)“Source Group 1”的前面將出現(xiàn)一個(gè)“+”號。單擊“+”,展開“Source Group 1”目錄,如圖1.21所示。

圖1.21 加入啟動(dòng)文件后的工程
這時(shí)可以添加已經(jīng)建立好的程序文件,如圖1.22所示。如果是新建立的程序文件,則先將程序文件.c存盤后再添加。

圖1.22 加入啟動(dòng)文件后的工程
單擊按鈕(或通過“File→New”操作)為該項(xiàng)目新建一個(gè)C語言程序文件。將該例程鍵入到Keil uVision IDE的編輯器中,并以文件名HelloRobot.c保存。
例程:HelloRobot.c
#include "stm32f10x_heads.h" #include "HelloRobot.h" int main(void) { BSP_Init(); // 開發(fā)板初始化 USART_Configuration(); // 串口1(USART1)初始化 printf("Hello Robot!\n"); while (1); }
將文件保存在項(xiàng)目文件夾HelloRobot中,在文件類型中填寫.c(這里.c為文件擴(kuò)展名,表示此文件類型為C語言源文件),如圖1.23所示。

圖1.23 C語言源文件保存對話框
下一步就是添加該文件到目標(biāo)工程項(xiàng)目了,其具體添加過程如下。
(1)單擊“+”,展開“Source Group 1”目錄,然后右鍵單擊“Source Group 1”,在出現(xiàn)的菜單下選擇“Add File To Group ‘Source Group 1’”,如圖1.24所示。出現(xiàn)Add Files to Group Source‘Group1’對話框。在該對話框中選擇需要添加的程序文件:HelloRobot.c,單擊Add按鈕,把所選文件添加到項(xiàng)目文件中。一次可添加多個(gè)文件。

圖1.24 添加文件
(2)程序文件添加到項(xiàng)目文件中去后,如圖1.25所示(注意:圖中顯示的文件名是剛才輸入的文件名)。

圖1.25 添加C語言文件到目標(biāo)工程中
雙擊源文件即可顯示源文件的編輯界面,如圖1.26所示。

圖1.26 源文件的編輯界面
下面來產(chǎn)生下載需要的可執(zhí)行文件。圖1.27表示編譯的幾種方式,圖1.27(a)的“Translate current file”表示僅編譯當(dāng)前源文件;圖1.27(b)的“Build target”表示編譯整個(gè)工程文件,編譯時(shí)僅編譯修改了的或新的源文件;圖1.27(c)的“Rebuild all target files”表示重新編譯整個(gè)工程文件,工程中的文件不管是"否修改,編譯時(shí)都將重新編譯。

圖1.27 編譯工程文件的幾種方式
一般地,我們單擊Keil uVision IDE快捷工具欄中的,編譯整個(gè)工程文件,如圖1.28所示。Keil的C編譯器根據(jù)要生成的目標(biāo)文件類型對目標(biāo)工程項(xiàng)目中的C語言源文件進(jìn)行編譯。編譯過程中,可以觀察到源文件中有沒有錯(cuò)誤產(chǎn)生,如果沒有錯(cuò)誤產(chǎn)生,在IDE主窗口的下面出現(xiàn)“0 Error(s),0 Warning(s)”提示信息,表明已成功生成了可執(zhí)行文件,并存儲在HolloRobot目錄中。

圖1.28 編譯過程的輸出信息
查看HelloRobot目錄,你會發(fā)現(xiàn)生成了HelloRobot.axf文件。ax(f arm excute file)是ARM芯片使用的文件格式,它包含bin代碼外,還包括了調(diào)試信息。與axf文件相似,單片機(jī)系統(tǒng)開發(fā)經(jīng)常也會用到hex文件,hex文件包括地址信息,可直接用于燒寫或下載。
如要產(chǎn)生可執(zhí)行的.hex文件,需要對目標(biāo)工程“Target 1”進(jìn)行編譯設(shè)置,右鍵單擊“Target 1”,選擇“Option for target ‘Target 1’”。單擊“Output”,選擇其中的“Create HEX File”,如圖1.29所示,單擊OK按鈕確定,關(guān)閉設(shè)置窗口。

圖1.29 設(shè)置目標(biāo)工程的編譯輸出文件類型
再次單擊Keil uVision IDE快捷工具欄中的,Keil的C編譯器開始根據(jù)要生成的目標(biāo)文件類型對目標(biāo)工程項(xiàng)目中的C語言源文件進(jìn)行編譯。這時(shí)HelloRobot目錄中,你會發(fā)現(xiàn)生成了HelloRoBot.hex文件。
任務(wù)六 下載可執(zhí)行文件到教學(xué)開發(fā)板
將ULink下載工具的一端通過USB線連接到電腦USB口上,另一端連接到教學(xué)開發(fā)板上的JTAG口上。接好后,按圖1.30(a)~(c)所示過程依次配置,安裝ULink驅(qū)動(dòng)。

圖1.30 ULink下載工具驅(qū)動(dòng)的安裝
將ULink和教學(xué)開發(fā)板連接好,打開教學(xué)開發(fā)板電源開關(guān)。單擊Project下的Options for Target(工程屬性),彈出“Options for Target”對話框。或者單擊“Flash”菜單下的“Configure Flash Tools”,按照如圖1.31(a)~(f)所示進(jìn)行配置。

圖1.31 ULink下載配置

圖1.31 ULink下載配置(續(xù))

圖1.31 ULink下載配置(續(xù))
這樣ULink下載工具就配置好了。如圖1.32所示,單擊圖標(biāo)(或通過“Flash→Download”操作),程序就開始下載了,下載結(jié)束如圖1.33所示。

圖1.32 程序下載

圖1.33 程序下載結(jié)束
下載時(shí),先擦除上次Flash存儲器中的程序,再將剛才編譯好的程序下載,最后經(jīng)校驗(yàn)無誤后,下載結(jié)束。此時(shí),按教學(xué)開發(fā)板的Reset復(fù)位鍵,下載的程序開始運(yùn)行。
Flash存儲器
Flash是存儲芯片的一種,通過特定的程序可以修改里面的數(shù)據(jù)。Flash存儲器又稱閃存,它結(jié)合了ROM和RAM的長處,不僅具備電子可擦除可編程(EEPROM)的性能,還不會斷電丟失數(shù)據(jù),同時(shí)可以快速讀取數(shù)據(jù)(NVRAM的優(yōu)勢)。U盤和MP3里用的就是這種存儲器。嵌入式系統(tǒng)以前一直使用ROM(EPROM)作為它們的存儲設(shè)備,20世紀(jì)90年代中期開始,F(xiàn)lash全面代替了ROM(EPROM)在嵌入式系統(tǒng)中的地位,用做存儲程序代碼或者Bootloader及操作系統(tǒng),現(xiàn)在則直接當(dāng)U盤使用。
目前Flash主要有兩種:NOR Flash和NAND Flash。NOR Flash的讀取和我們常見的SDRAM的讀取是一樣的,用戶可以直接運(yùn)行裝載在NOR Flash里面的代碼,這樣可以減少SRAM的容量,從而節(jié)約了成本。NAND Flash沒有采取內(nèi)存的隨機(jī)讀取技術(shù),它的讀取是以一次讀取一塊的形式來進(jìn)行的,通常是一次讀取512字節(jié),采用這種技術(shù)的Flash比較廉價(jià)。用戶不能直接運(yùn)行NAND Flash上的代碼,因此使用NAND Flash的嵌入式系統(tǒng)開發(fā)板除了使用NAND Flash以外,還做上了一塊小的NOR Flash來運(yùn)行啟動(dòng)代碼。
一般小容量的用NOR Flash,因?yàn)槠渥x取速度快,多用來存儲操作系統(tǒng)等重要信息,而大容量的用NAND Flash,最常見的NAND Flash應(yīng)用是嵌入式系統(tǒng)采用的DOC(Disk On Chip)和我們通常用的“閃盤”,可以在線擦除。目前市面上的Flash主要來自Intel,AMD,F(xiàn)ujitsu和Mxic,而生產(chǎn)NAND Flash的主要廠家有Samsung和Toshiba及Hynix。
SRAM存儲器
SRAM是英文Static RAM的縮寫,它是一種具有靜止存取功能的內(nèi)存,不需要刷新電路即能保存它內(nèi)部存儲的數(shù)據(jù)。而DRAM(Dynamic Random Access Memory)每隔一段時(shí)間,要刷新充電一次,否則內(nèi)部的數(shù)據(jù)即會消失,因此SRAM具有較高的性能,訪問速度快。但是SRAM也有它的缺點(diǎn),即價(jià)格高、集成度較低、功耗較大,相同容量的DRAM內(nèi)存可以設(shè)計(jì)為較小的體積,但是SRAM卻需要很大的體積。SRAM只用來存儲變量數(shù)據(jù)和提供給堆棧來使用。在嵌入式系統(tǒng)中,F(xiàn)lash的容量一般要大于SRAM的容量,如STM32F103VB芯片,其Flash容量為128K,SRAM容量為20K;STM32F103VE芯片,其Flash容量為512K,SRAM容量為64K。其他,8/16位單片機(jī)、ARM9或ARM11等嵌入式系統(tǒng)也是如此。
當(dāng)生成的可執(zhí)行文件大于Flash存儲空間時(shí),則不能被下載到Flash中。如果出現(xiàn)類似下面的錯(cuò)誤,則表示生成的可執(zhí)行文件大于Flash存儲空間:
Error: L6406W: No space in execution regions with .ANY selector matching Section .text(***.o).
這時(shí),可以對程序進(jìn)行優(yōu)化,例如,減小緩存尺寸,減少全局變量,少定義尺寸大的數(shù)組而多用指針等方法。此外,合理調(diào)整RealView MDK的編譯和鏈接配置,也可以減小生成的可執(zhí)行文件大小。比如,在鏈接腳本中指定代碼的存儲布局,將代碼段、只讀數(shù)據(jù)段、可讀寫數(shù)據(jù)段分別存放,以減小生成的可執(zhí)行文件大小。常有下面3種解決方法。
(1)使用微庫:在圖1.31(a)所示的對話框中選中“USE MicroLib”,以使代碼減少。
(2)修改鏈接腳本:在“Options For Target”對話框的“Linker”頁面,將Use Memory Layout from Target Dialog前面的復(fù)選框勾上,如圖1.34所示。然后在“Target”頁面(圖1.31(a)所示的對話框)中修改存儲空間中只讀部分(Read/Only Memory Areas)和可讀寫部分(Read/Write Memory Areas)的起始和大小,一般來說加大只讀部分大小(該部分存放程序中的指令),而減小可讀寫部分的大小(該部分存放堆棧、局部變量等)。

圖1.34 代碼尺寸優(yōu)化:配置“Linker”頁面
(3)修改優(yōu)化級別:在“Options For Target”對話框的“C/C++”頁面,可使用編譯選項(xiàng)“-Ospace”進(jìn)行編譯,將著重對空間進(jìn)行優(yōu)化,讓編譯器自動(dòng)減小代碼大小。另外,還可以選更高的選優(yōu)化級別“Level 3(-O3)”,如圖1.35所示。Level 3的優(yōu)化等級最高,最適合下載到最終的產(chǎn)品芯片中,而Level 0為不優(yōu)化,這種模式最適合調(diào)試,因?yàn)樗粫?yōu)化掉代碼。在學(xué)習(xí)時(shí),使用“Level 0(-O0)”,以方便程序的調(diào)試。

圖1.35 代碼尺寸優(yōu)化:配置C/C++頁面
關(guān)于MicroLib
使用微庫,將以更精簡短小的C庫替代標(biāo)準(zhǔn)C庫,減小代碼大小。MicroLib是默認(rèn)C庫的備選庫。它主要用于內(nèi)存有限的嵌入式應(yīng)用程序中。這些應(yīng)用程序不在操作系統(tǒng)中運(yùn)行。
如果你發(fā)現(xiàn)在Keil RealView MDK中使用printf函數(shù),不能向串口輸出信息,或者今后發(fā)現(xiàn)可以軟件仿真,不能硬件仿真,注意要在圖1.31(a)中的設(shè)置對話框選中“USE MicroLib”。MicroLib提供了一個(gè)有限的stdio子系統(tǒng),它僅支持未緩沖的stdin、stdout和stderr。這樣,即可使用printf()來顯示應(yīng)用程序中的診斷消息。
要使用高級I/O函數(shù),就必須提供自己實(shí)現(xiàn)的以下基本函數(shù),以便與自己的I/O設(shè)備(如串口)配合使用。
為所有輸出函數(shù):fprintf()、printf()、fwrite()、fputs()、puts()、putc()和putchar()等需要實(shí)現(xiàn)fputc()函數(shù)。
為所有輸入函數(shù):fscanf()、scanf()、fread()、read()、fgets()、gets()、getc() 和getchar()等需要實(shí)現(xiàn)fgetc()函數(shù)。
由于MicroLib進(jìn)行了高度優(yōu)化,以使代碼變得很小。因此,MicroLib不完全符合ISO C99庫標(biāo)準(zhǔn),僅提供有限的支持,不具備某些ISO C特性。并且其他特性具有的功能比默認(rèn)C庫少,MicroLib與默認(rèn)C庫之間的主要差異是:
(1)MicroLib不支持IEEE 754關(guān)于二進(jìn)制浮點(diǎn)算法標(biāo)準(zhǔn),否則會產(chǎn)生不可預(yù)測的輸出的結(jié)果,如NaN、無窮大。
(2)MicroLib中不支持的轉(zhuǎn)換為%lc、%ls和%a。
(3)MicroLib進(jìn)行了高度優(yōu)化,以使代碼變得很小。
(4)MicroLib不支持與操作系統(tǒng)交互的所有函數(shù),如abort()、exit()、atexit()、clock()、time()、system()和getenv()。不能將main()聲明為帶參數(shù)的,并且不能返回內(nèi)容。
(5)不支持與文件指針交互的所有stdio函數(shù),否則將返回錯(cuò)誤。僅支持三個(gè)標(biāo)準(zhǔn)流:stdin、stdout和stderr。即不完全支持stdio,僅支持未緩沖的stdin、stdout和stderr。
(6)MicroLib不提供互斥鎖來防止非線程安全的代碼。
(7)MicroLib不支持寬字符或多字節(jié)字符串。如果使用這些函數(shù),則會產(chǎn)生鏈接器錯(cuò)誤。
(8)與stdlib不同,MicroLib不支持可選擇的單或雙區(qū)內(nèi)存模型。MicroLib只提供雙區(qū)內(nèi)存模型,即單獨(dú)的堆棧和堆區(qū)。
該你了!——比較一下這幾種優(yōu)化方法所生成的可執(zhí)行文件大小
任務(wù)七 用串口調(diào)試軟件查看單片機(jī)輸出信息
打開串口調(diào)試軟件,如圖1.36所示進(jìn)行設(shè)置。一般地,若臺式PC機(jī)(或筆記本電腦)有串口,則選擇串口“COM1”;若使用的臺式PC機(jī)(或筆記本電腦)沒有串口,則使用USB轉(zhuǎn)串口適配器,如圖1.7(b)所示。安裝好對應(yīng)的USB驅(qū)動(dòng)程序后,在“我的電腦”上右擊→屬性→硬件,查看“設(shè)備管理器”中的“端口(COM和LPT)”信息,如顯示“通信端口(COM5)”,則將串口號設(shè)為COM5即可。

圖1.36 串口調(diào)試軟件設(shè)置
單擊“連接”按鈕,串口連接成功,如圖1.37所示。如串口沒有連接成功,注意檢查串口連接線是否連接正確,并關(guān)掉其他串口調(diào)試軟件。

圖1.37 串口連接成功
這時(shí),你在接收區(qū)看到了什么?什么也沒有!為什么呢?因?yàn)楫?dāng)你把執(zhí)行文件成功地下載到單片機(jī)的那個(gè)時(shí)刻開始,程序就開始運(yùn)行了:單片機(jī)已經(jīng)向PC發(fā)送了信息。你錯(cuò)過了接收,再按一下教學(xué)開發(fā)板上的“Reset”按鍵,你將看到調(diào)試軟件上的接收區(qū)顯示了一條信息,如圖1.38所示。

圖1.38 串口調(diào)試終端顯示的信息
恭喜你!
如果串口調(diào)試終端可以顯示信息,則說明你的STM32開發(fā)環(huán)境都已成功建立,包括硬件連接和軟件配置。
HelloRobot.c是如何工作的?
例程中前兩行代碼是HelloRoBot.c所包含的頭文件:“stm32f10x_heads.h”和“HelloRobot.h”。這兩個(gè)頭文件在本書的后續(xù)章節(jié)和任務(wù)中都要用到,“stm32f10x_heads.h”文件主要包含STM32庫文件的定義,它在編譯過程中用來將程序需要用到的標(biāo)準(zhǔn)數(shù)據(jù)類型和一些標(biāo)準(zhǔn)函數(shù)、中斷服務(wù)函數(shù)等包括進(jìn)來,生成可執(zhí)行代碼。頭文件中可以嵌套頭文件,同時(shí)也可以直接定義一些常用的功能函數(shù)。
HelloRobot.h則包含了本例程中以及后面例程中都要用到的幾個(gè)重要函數(shù)的定義和實(shí)現(xiàn),在后面的章節(jié)中會進(jìn)一步講解,包括:
(1)數(shù)據(jù)結(jié)構(gòu)的定義;
(2)系統(tǒng)時(shí)鐘配置函數(shù):RCC_Configuration;
(3)GPIO模式配置函數(shù):GPIO_Configuration;
(4)中斷控制配置函數(shù):NVIC_Configuration;
(5)串口1配置函數(shù):USART_Configuration;
(6)將C語言printf庫函數(shù)輸出重定向到串口輸出函數(shù):fputc;
(7)開發(fā)板初始化函數(shù):BSP_Init;
(8)微秒延時(shí)函數(shù):delay_nus;
(9)毫秒延時(shí)函數(shù):delay_nms。
main函數(shù)的第一行語句是開發(fā)板初始化函數(shù):BSP_Init,用來配置系統(tǒng)時(shí)鐘、GPIO模式和中斷控制,分別是RCC_Configuration()、GPIO_Configuration()、NVIC_Configuration()。這幾個(gè)函數(shù)將在后面的章節(jié)講解。這行語句中“//”后的是注釋。注釋是一行會被編譯器忽視的文字,因?yàn)樽⑨屖菫榱私o人閱讀,編譯器不對其進(jìn)行編譯。
main函數(shù)的第二行語句是串口1初始化配置函數(shù):USART_Configuration,用來規(guī)定單片機(jī)串口是如何與PC通信的。串口配置函數(shù)將在后面的章節(jié)講解。第三行語句是printf函數(shù):它是單片機(jī)通過串口向PC機(jī)發(fā)送一條信息:Hello Robot!。
main函數(shù)的第四行語句是“while(1);”。編譯好后的可執(zhí)行文件是下載到單片機(jī)Flash存儲器上的,并且是從頭開始往下加載的。當(dāng)你把可執(zhí)行文件加載上去的時(shí)候,填滿了整個(gè)Flash空間嗎?當(dāng)然沒有!那么,當(dāng)程序執(zhí)行完printf函數(shù)之后,它還將向下繼續(xù)執(zhí)行,但后面的空間并沒有存放程序代碼,這時(shí)程序后會亂運(yùn)行,也就發(fā)生了“跑飛”現(xiàn)象。加上while(1);語句,讓程序一直停止在這里,就是為了防止程序跑飛。
C語言中的兩種文件
在教材各章節(jié)中,會多次使用以“#”號開頭的預(yù)處理命令,如包含命令#include,宏定義命令#define等。一般都放在源文件的前面,稱為預(yù)處理部分。所謂預(yù)處理是指在進(jìn)行編譯的第一遍掃描(詞法掃描和語法分析)之前所做的工作。預(yù)處理是C語言的一個(gè)重要功能,它由預(yù)處理程序負(fù)責(zé)完成。當(dāng)對一個(gè)源文件進(jìn)行編譯時(shí),將首先對源程序中的預(yù)處理部分作處理,處理完畢后再對源程序進(jìn)行編譯。
常用的預(yù)處理命令有:
(1)宏定義
在C語言源程序中允許用一個(gè)標(biāo)識符來表示一個(gè)字符串,稱為“宏”。“define”為宏定義命令,被定義為“宏”的標(biāo)識符稱為“宏名”。在編譯預(yù)處理時(shí),對程序中所有出現(xiàn)的“宏名”,都用宏定義中的字符串去代換,這稱為“宏代換”或“宏展開”。
(2)文件包含
文件包含是C預(yù)處理程序的另一個(gè)重要功能。文件包含命令的功能是把指定的文件插入該命令行位置取代該命令行,從而把指定的文件和當(dāng)前的源程序文件連成一個(gè)源文件。
在程序設(shè)計(jì)中,文件包含是很有用的。一個(gè)大的程序可以分為多個(gè)模塊,由多個(gè)程序員分別編程。有些公用的符號常量或宏定義等可單獨(dú)組成一個(gè)文件,在其他文件的開頭用包含命令包含該文件即可使用。這樣,可避免在每個(gè)文件開頭都去書寫那些公用量,從而節(jié)省時(shí)間,并減少出錯(cuò)。
包含命令中的文件名可以用雙引號(“”)括起來,也可以用尖括號(< >)括起來。使用尖括號表示在包含安裝軟件的目錄中去查找(這個(gè)目錄是安裝軟件時(shí),設(shè)置的安裝路徑),而不在源文件目錄去查找,一般是安裝路徑(如C:\Keil MDK***)下的Include目錄;使用雙引號則表示首先在當(dāng)前的源文件目錄中查找(即當(dāng)前的HelloRobot目錄),若未找到才到包含安裝軟件的目錄中去查找。用戶編程時(shí)可根據(jù)自己文件所在的目錄來選擇某一種命令形式。如“stm32f10x_heads.h”和“HelloRobot.h”2個(gè)文件表示在當(dāng)前源文件所在目錄。
一個(gè)include命令只能指定一個(gè)被包含文件,若有多個(gè)文件要包含,則需用多個(gè)include命令。文件包含允許嵌套,即在一個(gè)被包含的文件中又可以包含另一個(gè)文件。
任務(wù)八 做完實(shí)驗(yàn)關(guān)斷電源
把電源從教學(xué)開發(fā)板上斷開很重要,原因有幾點(diǎn):首先,如果系統(tǒng)在不使用時(shí)沒有消耗電能,電池可以用的更久;其次,在以后的學(xué)習(xí)中,你將在教學(xué)開發(fā)板上的面包板上搭建電路,搭建電路時(shí),應(yīng)使面包板斷電。如果是在教室,老師可能會有額外的要求,如斷開串口電纜,把教學(xué)開發(fā)板存放到安全的地方等。總之,你做完實(shí)驗(yàn)后最重要的一步是斷開電源。斷開電源比較容易,只要三位開關(guān)撥到左邊的0位即可,如圖1.9(a)所示。
提倡節(jié)約用電,實(shí)踐低碳生活。
通過創(chuàng)建第一個(gè)程序,你可能感覺到了學(xué)習(xí)基于ARM Cortex-M3內(nèi)核的STM32單片機(jī)不是很容易!確實(shí)不錯(cuò),要學(xué)好單片機(jī),還要有一定的C語言基礎(chǔ),嵌入式系統(tǒng)的開發(fā)確實(shí)是一項(xiàng)非常具有挑戰(zhàn)性的任務(wù)。即使是一個(gè)簡單的程序,也需要進(jìn)行大量的準(zhǔn)備,學(xué)習(xí)大量的計(jì)算機(jī)知識。萬事開頭難!
- FPGA嵌入式項(xiàng)目開發(fā)三位一體實(shí)戰(zhàn)精講
- 嵌入式Linux接口開發(fā)技術(shù)
- PIC單片機(jī)常用模塊與綜合系統(tǒng)設(shè)計(jì)實(shí)例精講
- 基于STM32的嵌入式系統(tǒng)設(shè)計(jì)與實(shí)踐
- 單片機(jī)技術(shù)及應(yīng)用(第2版)
- 單片機(jī)開發(fā)從入門到實(shí)踐
- 嵌入式系統(tǒng):基于項(xiàng)目的分析和設(shè)計(jì)
- 基于Quartus II的FPGA/CPLD設(shè)計(jì)實(shí)例精解
- 丹佛斯變頻器控制技術(shù)
- 高分辨率遙感影像變化檢測
- 單片機(jī)原理與應(yīng)用技術(shù)
- 單片機(jī)應(yīng)用系統(tǒng)設(shè)計(jì)技術(shù)
- GD32 MCU原理及固件庫開發(fā)指南
- 單片微機(jī)原理與應(yīng)用
- C51單片機(jī)高效入門(第2版)