- 嵌入式技術與應用開發項目教程(STM32版)
- 郭志勇
- 5765字
- 2020-01-16 14:07:17
1.1 任務1 新建一個基于STM32固件庫的工程模板
任務要求
建立一個基于V3.5版本固件庫的Keil μVision4工程模板,方便以后每次新建工程時,可以直接復制使用該模板。
1.1.1 新建基于STM32固件庫的Keil μVision4工程模板
本書使用的是Keil μVision4版本。Keil μVision4源自德國的Keil公司,集成了業內最領先的技術,包括μVision4集成開發環境與RealView編譯器,支持Arm 7、Arm 9和最新的Cortex-M3核處理器,可以自動配置啟動代碼,集成了Flash燒寫模塊,具備強大的Simulation設備模擬、性能分析等功能。
1. 新建工程模板目錄
下面介紹怎樣建立基于V3.5版本固件庫的工程模板目錄,以后新建工程時,可以直接復制使用該模板。
(1)先在計算機的某個盤符下新建一個STM32_Project目錄,作為基于STM32固件庫的工程模板目錄。
(2)在STM32_Project工程模板目錄下,新建USER、CORE、OBJ以及STM32F10x_FWLib 4個子目錄,如圖1-1所示。

圖1-1 工程STM32_Project模板目錄
其中,CORE用來存放核心文件和啟動文件;OBJ用來存放編譯過程文件以及hex文件;STM32F10x_FWLib用來存放ST公司(意法半導體公司)官方提供的庫函數源碼文件;USER除了用來存放工程文件,還用來存放主函數文件main.c,以及system_stm32f10x.c、STM32F10x.s等文件。另外,很多人喜歡把子目錄“USER”取名為“Project”,將工程文件都保存到“Project”子目錄下面,也是可以的。
(3)把官方固件庫“Libraries\STM32F10x_StdPeriph_Driver”下面的src和inc子目錄復制到子目錄STM32F10x_FWLib下面,如圖1-2所示。

圖1-2 STM32F10x_FWLib子目錄
其中,src存放的是固件庫的“.c”文件,inc存放的是其對應的“.h”文件。每個外設都對應一個“.c”文件和一個“.h”頭文件。
(4)把官方固件庫里相關的啟動文件復制到CORE文件夾里面。
把官方固件庫“Libraries\CMSIS\CM3\CoreSupport”下面的core_cm3.c和core_cm3.h文件復制到子目錄CORE下面;把“Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm”下面的startup_stm32f10x_ld.s文件復制到CORE文件夾下面,如圖1-3所示。

圖1-3 CORE子目錄
注意
本項目采用STM32F103R6芯片,該芯片的FLASH大小是32KB,屬于小容量產品,所以啟動文件使用startup_stm32f10x_ld.s文件。若采用其他容量的芯片,可以使用startup_stm32f10x_md.s或startup_stm32f10x_hd.s啟動文件。
(5)先把官方固件庫“Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x”下面的stm32f10x.h、system_stm32f10x.c、system_stm32f10x.h文件復制到子目錄USER下面,然后把官方固件庫“Project\STM32F10x_StdPeriph_Template”下面的stm32f10x_conf.h、stm32f10x_it.c、stm32f10x_it.h文件復制到子目錄USER下面,如圖1-4所示。

圖1-4 USER子目錄
通過前面幾個步驟,就把需要的官方固件庫相關文件復制到了工程目錄模板“STM32_Project”下面。在以后的任務中,直接復制工程模板目錄,然后修改成需要的名字即可使用。
2. 新建Keil μVision4工程模板
在建立工程之前,先在計算機的某個盤符下新建一個子目錄“任務1 STM32_Project工程模板”;然后把工程目錄模板“STM32_Project”復制到“任務1 STM32_Project工程模板”子目錄里面,并修改工程目錄模板名為“STM32_Project工程模板”。
(1)運行Keil μVision4軟件。第一種方法是雙擊桌面上的Keil μVision4圖標;第二種方法是單擊桌面左下方的“開始”→“程序”→“Keil μVision4”,進入Keil μVision4集成開發環境,如圖1-5所示。

圖1-5 Keil μVision4集成開發環境
(2)單擊Project->New uVision Project,如圖1-6所示。

圖1-6 新建工程
然后把目錄定位到“STM32_Project工程模板\USER”下面,我們的工程文件都保存在這里。將工程命名為“STM32_Project”,單擊“保存”按鈕,如圖1-7所示。

圖1-7 保存新建工程
(3)接下來彈出選擇芯片“Select Device Target‘Target1’”對話框,本項目使用的是STM32F103R6芯片,選擇STMicroelectronics下面的STM32F103R6即可。如果使用的是其他系列的芯片,選擇相應的型號就可以了,如圖1-8所示。

圖1-8 選擇芯片型號
(4)單擊OK按鈕,彈出對話框“Copy STM32 Startup Code to project…”,詢問是否添加啟動代碼到我們的工程中,這里選擇“否”,因為我們使用的ST固件庫文件已經包含了啟動文件,如圖1-9所示。

圖1-9 是否添加啟動代碼對話框
啟動代碼是一段和硬件相關的匯編代碼,是必不可少的!這段代碼具體如何工作,我們不必太關心。
現在我們就可以看到新建工程后的界面,如圖1-10所示。

圖1-10 新建工程后的界面
3. 新建組和添加文件到STM32_Project工程模板
建好STM32_Project工程后,下面介紹如何在STM32_Project工程下新建USER、CORE、OBJ和STM32F10x_FWLib組,并添加文件到相應的組中。
(1)在圖1-10中,通過快捷工具欄(或File菜單)的按鈕新建一個文件,并保存為main.c,主文件main.c一定要放在USER組里面。在該文件中輸入如下代碼:
#include "stm32f10x.h" int main(void) { while(1) { ; } }
“#include"stm32f10x.h"”語句是一個“文件包含”處理語句。stm32f10x.h是STM32開發中最為重要的一個頭文件,就像C51單片機的reg52.h頭文件一樣,在應用程序中是至關重要的,通常包括在主文件中。這里的main()函數是一個空函數,方便以后添加需要的代碼。
注意
stm32f10x.h是ST公司V3.5及以后版本統一使用的庫函數頭文件,也就是把V2.0版本的stm32f10x_lib.h頭文件換成了stm32f10x.h頭文件,規范了代碼,不需要再包含那么多的頭文件了。使用高版本編譯,將找不到stm32f10x_lib.h。
(2)在USER組里面,打開STM32_Project工程,然后在Project窗格的Target1上單擊鼠標右鍵,選擇Manage Components選項,如圖1-11所示。

圖1-11 調出Manage Components
(3)彈出圖1-12所示Components Environment and Books對話框。

圖1-12 Components Environment and Books對話框
(4)先把Project Targets欄下的Target1修改為STM32_Project,把Groups欄下的Source Group1刪除。然后在Groups欄(中間欄)單擊新建按鈕(也可以雙擊下面的空白處),新建USER、CORE和STM32F10x_FWLib組,如圖1-13所示。

圖1-13 新建的組
(5)往USER、CORE和STM32F10x_FWLib組里面添加我們需要的文件。
先選中Groups欄下的STM32F10x_FWLib,然后單擊Add Files按鈕,定位到工程目錄的STM32F10x_FWLib/src子目錄。把里面的所有文件都選中(組合鍵Ctrl+A),然后單擊Add按鈕,最后單擊Close按鈕,就可以看到Files欄下面出現了我們添加的所有文件,如圖1-14所示。

圖1-14 STM32F10x_FWLib組里添加的文件
用同樣的方法,添加CORE子目錄里面的core_cm3.c和startup_stm32f10x_ld.s文件,添加USER子目錄里面的main.c、stm32f10x_it.c和system_stm32f10x.c文件。
這樣,需要添加的文件都添加到工程里面了,最后單擊OK按鈕,退出Components Environment and Books對話框。這時,會發現在Target樹下多了三個組名和其中添加的文件,如圖1-15所示。

圖1-15 完成新建組和添加文件的工程
注意
? 為方便后面使用,我們把所有外設的庫文件都添加進工程了,不用每次增加外設時都要再添加相應的庫文件,這樣做的壞處就是當工程太大時,編譯速度全變慢;
? 本任務只用了GPIO,所以可以只添加stm32f10x_gpio.c,其他的不用添加。
4. 工程配置與編譯
到此為止,新建的基于STM32的Keil μVision4工程就已經基本完成了。接下來進行工程配置和編譯。
(1)單擊工具欄的“Target Options…”按鈕,彈出“Options for Target 'Leddl'”對話框,選擇C/C++選項卡,添加要編譯文件的路徑。這個步驟非常重要,務必添加正確的路徑,否則編譯會出現錯誤。C/C++選項卡配置界面如圖1-16所示。

圖1-16 C/C++選項卡配置界面
(2)單擊Include Paths最右邊的方塊按鈕,彈出添加路徑的Folder Setup對話框,然后把STM32F10x_FWLib\inc、CORE和USER子目錄都添加進去。此操作是為了設定編譯器的頭文件包含路徑,在以后的任務中會經常用到,如圖1-17所示。

圖1-17 添加所要編譯文件的路徑
在這里,還需要在C/C++選項卡配置界面中,填寫“STM32F10X_LD,USE_STDPERIPH_DRIVER”到Define輸入框里,如圖1-18所示。

圖1-18 配置一個全局的宏定義
之所以要填寫“STM32F10X_LD,USE_STDPERIPH_DRIVER”,是因為V3.5版的庫函數在配置和選擇外設時,是通過宏定義來選擇的,所以需要配置一個全局的宏定義變量,否則工程編譯會出錯。若使用中容量芯片,就把STM32F10X_LD修改為STM32F10X_MD;若使用大容量芯片,就修改為STM32F10X_HD。
(3)設置完C/C++選項卡配置界面后,單擊OK按鈕,在“Options for Target 'Leddl'”對話框中,選擇Output選項卡。先選中Greate HEX File選項;再單擊“Select Folder for Objects…”按鈕,在彈出的對話框中選中OBJ子目錄,單擊OK按鈕。以后工程編譯的HEX文件以及垃圾文件就會放到OBJ子目錄里面,保持了工程簡潔不亂,如圖1-19所示。

圖1-19 配置Output選項卡
(4)單擊OK按鈕,退出“Options for Target'Target 1'”對話框,然后單擊工具欄的Rebuild按鈕,對工程進行編譯。若編譯發生錯誤,要進行分析檢查,直到編譯正確為止,如圖1-20所示。

圖1-20 工程編譯
對工程進行第一次編譯時,單擊工具欄的Rebuild按鈕。不管工程的文件有沒有編譯過,Rebuild都會對工程中的所有文件重新進行編譯并生成可執行文件,因此重編譯時間較長。若只編譯工程中上次修改的文件,單擊工具欄的Build
按鈕即可。
另外,在主文件main.c代碼的最后一定要加上一個回車,否則編譯會有警告信息。
注意
? 基于STM32的Keil μVision4工程已經完成了,可將其作為開發的工程模板。以后開發項目時直接復制使用,再把編寫的主文件和其他文件添加進來就可以了,這為以后的開發工作帶來了極大方便。
1.1.2 認識STM32固件庫
ST公司為了方便用戶開發程序,提供了一套豐富的STM32固件庫。什么是固件庫呢?在STM32應用程序開發中,固件庫與寄存器有什么區別和聯系呢?
1. STM32固件庫開發與寄存器開發的關系
從51單片機開發轉入STM32開發時,由于我們習慣了51單片機的寄存器開發方式,突然要使用STM32固件庫開發,會不知道如何下手。下面通過一個簡單的例子來說明STM32固件庫到底是什么,與寄存器開發有什么關系?
在51單片機開發中,我們若想控制某些I/O端口的狀態,就會直接操作寄存器,如:
P2=0x0fe;
而在STM32的開發中,我們同樣也可以直接操作寄存器,如:
GPIOx->BRR = 0x00fe;
由于STM32有數百個寄存器,初學者要想很快地掌握每個寄存器的用法,并能正確使用,是非常困難的。
于是ST公司推出了官方的STM32固件庫,將這些寄存器的底層操作封裝起來,提供一整套接口(API)供開發者調用。在大多數場合下,開發人員不需要知道操作的是哪個寄存器,只需要知道調用哪些函數即可。
上面的例子直接操作STM32的BRR寄存器,可以實現電平控制。STM32固件庫封裝了一個函數:
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { GPIOx->BRR = GPIO_Pin; }
這時,開發人員就不需要操作BRR寄存器了,知道如何使用GPIO_ResetBits()函數就可以了。另外,通過固件庫的函數名字,我們就能知道這個函數的功能是什么,該怎么使用。
2. STM32固件庫與CMSIS標準
STM32固件庫是函數的集合,固件庫函數的作用是向下與寄存器直接打交道,向上提供用戶調用函數的接口(API)。那么對這些函數有什么要求呢?這就涉及一個CMSIS標準的基礎知識。
Arm是一個做芯片標準的公司,它負責的是芯片內核的架構設計,而TI、ST等公司并不是做標準的,只是一個芯片公司,它們根據Arm公司提供的芯片內核標準來設計自己的芯片。芯片雖然由芯片公司設計,但是內核卻要服從Arm公司提出的Cortex-M3內核標準。芯片公司每賣出一片芯片,需要向Arm公司交納一定的專利費。
所以,所有Cortex-M3芯片的內核結構都是一樣的,只是在存儲器容量、片上外設、端口數量、串口數量以及其他模塊上有所區別,芯片公司可以根據自己的需求理念來設計這些資源。同一家公司設計的多種Cortex-m3內核芯片的片上外設也會有很大的區別,如STM32F103RBT和STM32F103ZET在片上外設方面就有很大的區別。
為了保證不同芯片公司生產的Cortex-M3芯片能在軟件上基本兼容,Arm公司和芯片生產商共同提出了一套標準——CMSIS標準( Cortex Microcontroller Software Interface Standard),即“Arm Corte微控制器軟件接口標準”。ST官方庫(STM32固件庫)就是根據這套標準設計的,CMSIS共分3個基本功能層。
(1)核內外設訪問層:Arm公司提供的訪問,定義處理器內部寄存器地址以及功能函數。
(2)中間件訪問層:定義訪問中間件的通用API,由Arm公司提供。
(3)外設訪問層:定義硬件寄存器的地址以及外設的訪問函數。
CMSIS向下負責與內核和各個外設直接打交道,向上負責提供實時操作系統用戶程序調用的函數接口。如果沒有CMSIS標準,那么各個芯片公司就會設計自己喜歡的風格的庫函數,而CMSIS標準就是要強制規定,芯片生產公司的庫函數必須按照CMSIS這套規范來設計。
另外,CMSIS還對各個外設驅動文件的文件名字規范化、函數名字規范化等做了一系列規定。比如前面用到的GPIO_ResetBits函數,其名字是不能隨便定義的,必須遵循CMSIS規范。
又如,在我們使用STM32芯片時,首先要進行系統初始化。CMSIS就規定系統初始化函數名必須為SystemInit,所以各個芯片公司設計自己的庫函數時,都必須用SystemInit對系統進行初始化。
1.1.3 STM32固件庫關鍵子目錄和文件
STM32固件庫是不斷完善升級的,目前存在多個不同的版本,本書使用的是V3.5版本的固件庫(目前最新版本)。STM32固件庫的目錄結構如圖1-21所示。

圖1-21 STM32固件庫目錄結構
從圖1-21可以看出,解壓后的STM32F10x_StdPeriph_Lib_V3.5.0目錄下包含了STM32固件庫的全部文件。
其中,Release_Notes.html文件是關于該庫文件相比之前版本有何改動,stm32f10x_stdperiph_lib_um.chm文件是固件庫的英文幫助文檔,在開發過程中,這個文檔會經常用到。
1. STM32固件庫關鍵子目錄
STM32固件庫關鍵子目錄主要有Libraries和Project。另外,_htmresc子目錄里是ST的圖標,Utilities子目錄是官方評估板的一些對應源碼,跟開發完全無關。
(1)Libraries子目錄
Libraries子目錄下面有CMSIS子目錄和STM32F10x_StdPeriph_Driver子目錄,這兩個子目錄包含固件庫核心的所有子文件夾和文件,主要包含大量的頭文件、源文件和系統文件,是開發必須使用的。Libraries的目錄結構如圖1-22所示。

圖1-22 Libraries目錄結構
CMSIS子目錄存放的是啟動文件。STM32F10x_StdPeriph_Driver子目錄存放的是STM32固件庫源碼文件,其下的inc子目錄存放的是stm32f10x_xxx.h頭文件,無須改動;src子目錄存放的是stm32f10x_xxx.c固件庫源碼文件。
每一個“.c”文件和一個相應的“.h”文件對應,這里的文件也是固件庫的核心文件,即每個外設對應一組文件。
(2)Project子目錄
Project子目錄下面有STM32F10x_StdPeriph_Examples和STM32F10x_StdPeriph_Template子目錄。
STM32F10x_StdPeriph_Examples子目錄存放的是ST官方提供的固件實例源碼,包含了幾乎所有STM32F10x外設的詳細使用源代碼。在以后的開發過程中,可以修改這個官方提供的參考實例,以快速驅動自己的外設。很多開發板的實例,也都參考了官方提供的例程源碼,這些源碼對以后的學習非常重要。
STM32F10x_StdPeriph_Template子目錄存放的是工程模板。
2. STM32固件庫的關鍵文件
在這里,我們著重介紹STM32固件庫Libraries子目錄下的幾個重要文件。
(1)core_cm3.c和core_cm3.h
core_cm3.c和core_cm3.h文件位于\Libraries\CMSIS\CM3\CoreSupport子目錄下面,分別是內核訪問層的源文件和頭文件,提供進入M3內核的接口。這兩個文件是由Arm公司提供的CMSIS核心文件,對所有M3內核的芯片都一樣,永遠都不需要修改。
(2)STM32F10x子目錄的3個文件
DeviceSupport和CoreSupport是同一級的,STM32F10x子目錄放在DeviceSupport子目錄下面。DeviceSupport\ST\STM32F10x子目錄主要存放一些啟動文件、比較基礎的寄存器定義以及中斷向量定義的文件。
在STM32F10x子目錄下面有3個文件:system_stm32f10x.c、system_stm32f10x.h以及stm32f10x.h文件,是外設訪問層的源文件和頭文件。
system_stm32f10x.c文件和對應的system_stm32f10x.h頭文件的功能,是設置系統和總線時鐘,其中有一個非常重要的SystemInit()函數,在系統啟動時都會被調用,用來設置系統的整個時鐘系統。這也就是不需要用戶配置時鐘,程序就能運行的原因。
stm32f10x.h文件相當重要,主要包含了STM32F10x系列所有外設寄存器的定義、位定義、中斷向量表、存儲空間的地址映射等。只要做STM32開發,就要查看這個文件相關的定義。打開這個文件時可以看到,里面有非常多的結構體以及宏定義。
(3)啟動文件
在STM32F10x子目錄下面還有一個startup子目錄,里面放的是啟動文件。在\startup\arm目錄下,我們可以看到8個以startup開頭的“.s”文件,如圖1-23所示。

圖1-23 startup子目錄結構
從圖1-23中可以看出,共有8個啟動文件,不同容量(容量是指FLASH的大小)的芯片,對應的啟動文件也不一樣。在stm32f 103系列芯片中,主要使用其中3個啟動文件。
? startup_stm32f10x_ld.s:適用于小容量產品,Flash≤32 KB;
? startup_stm32f10x_md.s:適用于中等容量產品,64 KB≤Flash≤128 KB;
? startup_stm32f10x_hd.s:適用于大容量產品,256 KB≤Flash。
本項目采用的是STM32F103R6芯片,其Flash容量是32 KB,屬于小容量產品,所以選擇startup_stm32f10x_ld.s啟動文件。
那么,啟動文件到底有什么作用呢?
啟動文件主要進行堆棧等的初始化、中斷向量表以及中斷函數定義,還要引導程序進入main函數。
(4)STM32F10x_StdPeriph_Template子目錄的3個文件
在Project\STM32F10x_StdPeriph_Template子目錄下有3個關鍵文件:stm32f10x_it.c、stm32f10x_it.h和stm32f10x_conf.h。
stm32f10x_it.c和stm32f10x_it.h是外設中斷函數文件,用來編寫中斷服務函數,用戶可以相應地加入自己的中斷程序代碼。
stm32f10x_conf.h是固件庫配置文件,有很多#include。在建立工程時,可以注釋掉一些不用的外設頭文件,只選擇固件庫使用的外設。
- ANSYS Workbench基礎教程與工程分析詳解
- 用Proteus可視化設計玩轉Arduino
- ABAQUS 2016有限元分析從入門到精通
- TinyML:基于TensorFlow Lite在Arduino和超低功耗微控制器上部署機器學習
- 嵌入式Qt實戰教程
- 51單片機逆向學習實戰教程(電子設計與嵌入式開發實踐叢書)
- DSP技術與應用實例
- 單片機原理與應用:基于Keil+Proteus
- STM32單片機全案例開發實戰
- 嵌入式軟件自動化測試
- 51單片機C語言編程一學就會
- 單片微型計算機原理及應用
- 51單片機工程師是怎樣煉成的:基于C語言+Proteus仿真
- 單片機應用技術實訓指導
- 嵌入式Linux軟硬件開發詳解:基于S5PV210處理器