STM32系列微控制器開發工具與應用——keil

STM32微處理器基於ARM核,所以很多基於ARM嵌入式開發環境都可用於STM32開發平臺。開發工具都可用於STM32開發。選擇合適的開發環境可以加快開發進度,節省開發成本。本章將先對STM32常用的開發工具Keil MDK和IAR EWARM進行簡單介紹,然後結合STM32_SK仿真評估板和STM32F103C的開發板講解STM32片上資源使用,最後給出一個基於STM32的數據採集器的應用實例。

5.1 Keil MDK介紹
Keil是德國知名軟件公司Keil(現已併入ARM 公司)開發的微控制器軟件開發平臺,是目前ARM內核單片機開發的主流工具。Keil提供了包括C編譯器、宏彙編、連接器、庫管理和一個功能強大的仿真調試器在內的完整開發方案,通過一個集成開發環境(uVision)將這些功能組合在一起。uVision當前最高版本是uVision3,它的界面和常用的微軟VC++的界面相似,界面友好,易學易用,在調試程序,軟件仿真方面也有很強大的功能。因此很多開發ARM應用的工程師,都對它十分喜歡。

5.1.1 開發過程及集成開發環境簡介
1. Keil的軟件開發週期

使用Keil來開發嵌入式軟件,開發週期和其他的平臺軟件開發週期是差不多的,大致有以下幾個步驟:
1. 創建一個工程,選擇一塊目標芯片,並且做一些必要的工程配置。
2. 編寫C或者彙編源文件。
3. 編譯應用程序。
4. 修改源程序中的錯誤。
5. 聯機調試。
下面這種結構圖完整描述了Keil開發軟件的整個過程。


2. uVision3 集成開發環境
uVision3 IDE是一款集編輯,編譯和項目管理於一身的基於窗口的軟件開發環境。uVision3集成了C語言編譯器,宏編譯,鏈接/定位,以及HEX文件產生器。uVision3具有如下特性:
 功能齊全的源代碼編輯器,
 用於配置開發工具的設備庫,
 用於創建工程和維護工程的項目管理器,
 所有的工具配置都採用對話框進行,
 集成了源碼級的仿真調試器,包括高速CPU和外設模擬器,
 用於往Flash ROM下載應用程序的Flash編程工具,
 完備的開發工具幫助文檔,設備數據表和用戶使用嚮導。
uVision3具有良好的界面風格,下圖是一個典型的調試時的窗口。


 工程區:用於訪問文件組和文件,調試是可以查看CPU寄存器。
 輸出窗口:顯示編譯結果,以便快速查找錯誤的地方,同時還是調試命令輸入輸出窗口,也可以用於顯示查找結果。
 內存窗口:顯示指定地址內村裏的內容。
 查看和調用棧窗口:用於查看和修改變量的值,並且現實當前函數調用樹。
 代碼窗口:用於查看和編輯源文件。
 外設對話框:檢查微控制的片上外設的狀態。

3. ULINK USB-JTAG接口適配器
ULINK USB-JTAG是一個用於連接PC USB口和開發板JTAG口的小硬件適配器。通過ULINK你可以在真實的目標板上創建,下載和測試嵌入式應用。ULINK支持如下操作:
 下載目標程序。
 檢查內存和寄存器。
 單步運行程序。
 插入多個斷點。
 實時運行程序
 燒寫FLASH存儲器


5.1.2 工程管理
在項目開發中,並不是僅有一個源程序就行了,還要爲這個項目選擇CPU(Keil支持數百種CPU,而這些CPU的特性並不完全相同),確定編譯、彙編、連接的參數,指定調試的方式,有一些項目還會有多個文件組成等,爲管理和使用方便,Keil使用工程(Project)這一概念,將這些參數設置和所需的所有文件都加到一個工程中,只對工程而不是對單一的源程序進行編譯(彙編)和連接等操作。下面我們就以一個簡單的例子HelloWorld來講解如何建立工程和配置工程。在這個例子裏,我們將實現開發板上的LED1閃爍,本例使用STM32F103C開發板爲目標板。

5.1.2.1 新建工程
點擊菜單“Project”,選擇“New uVision Project”,這是將會出現一個對話框,要求給將要建立的工程起一個名字。
選擇你要保存的路徑,輸入工程文件的名字,這裏我們就叫HelloWorld,uVision3工程文件的後綴爲“.uv2”,然後點擊“Save”。 這時會彈出一個對話框要求你選擇目標設備的型號。


你可以根據你使用的處理器來選擇,如果您所使用的處理器型號在列表中找不到,也可以找一款與您使用的相兼容的型號來代替。這裏我們選擇STM32F103C8,如圖所示,右邊一欄是對這個芯片的基本的說明,然後點擊“OK”。


有些芯片會提供啓動代碼,我們這個時候點擊“Yes”,到此一個工程就建立好了。

5.1.2.2 配置工程
工程建立好了之後,還要對工程進行進一步的設置,以滿足要求。
首先用鼠標右鍵(注意用右鍵)點擊左邊工程窗口的“Target 1”,會出現一個菜單,選擇“Options for Target 'Target 1'”(也可以通過點擊工程窗口的Target 1”,然後使用菜單“Project”->“Options for Target 'Target 1'”),即出現工程配置的對話框,如下圖所示:


這個對話框很複雜,而且根所選擇的芯片有關,這裏共有10個頁面,絕大多數選擇默認配置即可,下面將對一些需要注意的配置簡單介紹一下。
1. Output標籤頁的設置


Select Folder for Objects:選擇編譯之後的目標文件存儲在哪個目錄裏,默認位置爲工程文件的目錄裏。
Name of Executable:生成的目標文件的名字,缺省是工程的名字。
Create Executable:生成OMF以及HEX文件。OMF文件名同工程文件名但沒有帶擴展名。
Debug Information:用於Debug版本,生成調試信息,否則的話無法進行單步調試。
Create Batch File:生成用於實現整個編譯過程的批處理文件,使用這個文件可以脫離IDE對省程序進行編譯。
Create Hex File:這個選項默認情況下未被選中,如果要寫片做硬件實驗就必須選中該項。這一點是初學者易疏忽的,在此特別提醒注意一定要要選中,否則編譯之不生成Hex文件。
Big Endian:編碼格式,與CPU相關,如果CPU採用的是Big Endian編碼則勾選上。
Browse Information:產生用於在源文件快速定位的信息。
Create Library:生成lib庫文件,默認不選。
在我們剛剛新建的HelloWorld工程中,更改了三個地方,在工程目錄下新建了一個Output目錄保存目標文件,以避免和源文件混在一起。另外選中了Create Hex File和Browse Information,如上圖所示。
2. C/C++標籤頁的設置


Include Paths:指定頭文件的查找路徑,可以添加多個。
這裏我們所有的選擇保持默認選擇就可以了。
3. Debug標籤頁的設置


左邊是對應uVision3的模擬環境,右邊是針對仿真器,這裏選擇右邊的ULINK Cortex Debugger仿真器爲例進行說明。
如果已經將ULINK仿真器連接到你的電腦,點擊“Settings”你將進入ARM Target Driver Setup 界面。


ULINK - JTAG/SWD Adapter:
Serial No:列出了當前連接到主機的所有ULINK適配器的串號,你可以通過列表選擇要使用的ULINK適配器。
ULINK Version,Device Family以及Firmware Version分別列出了當前選擇的ULINK適配器的版本,設備家族和固件版本。
SWJ,Port:根據和開發板接口的類型選擇端口,有JTAG和SW兩種,勾選SWJ表示支持兩種方式。
Max Clock:指定和開發板的最高通信時鐘。
JTAG Device Chain:顯示當前通過適配器連接上的開發板。
Automatic Detection:自動監測,選擇系統將自動檢測連接上的開發板,建議使用。
Manual Configuration:手動配置,通過手動設置ID CODE,Device Name和IR len等屬性來查找設備。
Debug:
Cache Options:
 Cache Code:通知調試器已經下載的程序代碼不會改變,選中的話uVision將不會從目標系統讀取程序代碼。
 Cache Memory:決定調試程序期間程序停止運行的時候,是否更新存儲器顯示。
Download Options:
 Verify Code Download:比較目標存儲器和調試器上的應用程序的內容。
 Download to Flash:將代碼下載到所有的存儲器區域,如果不選中,調試器不會把代碼下載到Flash Download Setup中制定的存儲器地址範圍。
Misc Options:
 Use Reset at Startup:選中的時候,調試器在開始調試的時候會發起一次CPU復位。 
Load Application at Startup:將Output標籤中指定的可執行文件導入到調試器的起始地址。
Run to Main:開始調試時執行到Main函數入口暫停執行。
Initialization File:指定一個包含一組調試命令的文件,這組命令是調試器開始工作或者調試函數在調試期間要使用的。
Restore Debug Session Settings:使用上一次調試過程對Breakpoints,Watchpoints,Memory Display和Toolbox(如果這些項被選中的話)。
Driver DLL – Parameter:由Device Database設置的目標驅動DLL,不要修改。
Dialog DLL – Parameter:由Device Database設置的對話框DLL,不要修改。
這裏我們修改了兩個地方,選中了Use ULINK和Run to Main,對ULINK的設置進行了一些調整,具體的設置圖5.11所示。
4. Utilities標籤頁的設置


Configure Flash Menu Command
 Use Target Driver for Flash Programming:列表選擇和調試接口一致的驅動。Init File的設置也和前面調試設置一致。點擊Settings將進入Flash Download Setup界面。


Download Function:定義了Flash燒寫的時候進行的操作。
 Erase Full Chip:前面三項要選一,燒寫程序之前擦除整個Flash存儲器。
 Erase Sectors:燒寫程序之前擦除程序要使用的扇區。
 Do not Erase:不進行擦除操作
 Program:使用當前uVision工程的程序燒寫ROM。
 Verify:驗證Flash ROM的內容和當前工程中的程序一致。
 Reset and Run:在燒寫和驗證完成之後復位開發板並且運行程序。
RAM for Algorithm:指定用於燒寫程序的RAM區域,通常是微控制器上的一段片上空間。
 Start:起始地址。
 Size:大小。
可以通過點擊Add添加,點擊Add你將看到如下的選擇列表,可以根據你選用的芯片選擇合適的,也可以自己手動添加。


 Use External Tool for Flash Programming:使用第三方的工具進行Flash下載。
 Command:要使用的Flash燒寫工具的命令文件(通常是一個.exe文件)。
 Arguments:傳遞給Flash燒寫工具的參數。
 Run Independent:當選中的時候,uVision不等待Flash燒寫完成。不選中的時候uVision要等待Flash燒寫完成並且在輸出窗口顯示燒寫結果。
在HelloWorld裏面修改了Flash Download Setup,具體的設置如上圖所示。到此工程設置就結束了。

5.1.2.3 打開工程
通過菜單“Project”->“Open Project”來打開一個現有工程,這時將彈出一個打開文件對話框讓我們選擇要打開的工程文件。
選擇你要打開的工程的路徑,然後點擊“Open”打開工程。我們還可以和打開其他文件一樣,找到一個後綴爲“uv2”的uVision3工程文件,直接雙擊,Windows會自動調用uVision3打開這個文件,前提是你電腦已經安裝了uVision3並且和“uv2”文件建立了關聯。

5.1.3 編寫源程序
選擇菜單“File”->“New”或者點擊工具欄的新建文件按鈕,即可在項目窗口的右側打開一個新的文本編輯窗口,在該窗口可以輸入程序代碼。
需要說明的是,源文件就是一般的文本文件,不一定使用Keil軟件編寫,可以使用任意文本編輯器編寫,而且Keil的編輯器對漢字的支持不好,建議使用UltraEdit之類的編輯軟件進行源程序的輸入。
每一個程序至少有一個原型爲int main(void)的主函數,這是程序的入口地址,程序將從這裏開始運行。此外,我們還需要對開發板做一些時鐘和中斷方面的初始化工作,這些工作將在函數RCC_Configuration和NVIC_Configuration中完成。源文件的代碼清單如下所示。
#include "stm32f10x_lib.h"
GPIO_InitTypeDef GPIO_InitStructure;
void Delay (vu32 nCount);
/******************************************************************************* Function Name : main
* Description : 主程序
* Input : None
* Output : None
* Return : None
******************************************************************************/
int main (void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init (GPIOB, &GPIO_InitStructure);
while (1)
{
GPIO_WriteBit (GPIOB, GPIO_Pin_9,
(BitAction)(1-GPIO_ReadOutputDataBit (GPIOB, GPIO_Pin_9)));
Delay (1000000);
}
}
void Delay (vu32 nCount)
{
for (; nCount != 0; nCount--);
}
代碼編輯完成之後,我們可以保存源文件,選擇菜單“File”->“Save”或者點擊工具欄的保存文件按鈕,可以用來保存源文件。
這時會出現一個保存文件的文件對話框,選擇你要保存的路徑,輸入文件名HelloWorld.c。注意一定要輸入擴展名,如果是c程序文件擴展名爲.c,如果是彙編文件擴展名爲.s,習慣.asm的也可以存儲爲.asm。註解說明文件可以保存爲.txt的擴展名。
源文件編輯完成之後我們還需要將源文件加入到工程中,工程建好之後,在工程窗口的文件頁中,將會出現“Target 1”,前面有個“+”號,點擊“+”號展開,可以看到下一層的“Source Group 1”,我們需要向這個裏面加入源文件,點擊“Source Group 1”使其反白顯示,然後,點擊鼠標右鍵,出現一個下拉菜單,如下圖如示。


選中其中的“Add file to Group ‘Source Group 1’”,出現一個對話框,要求尋找源文件,如下圖所示。


注意,該對話框下面的“文件類型”默認爲C source file(*.c),我們可以通過調整這個來選擇過濾我們想要格式的文件,從而幫助我們快速查找文件。如果是彙編文件,就選擇“asm source file”;如果是目標文件,選擇“Object file”;如果是庫文件,選擇“Library file”。最後點擊“Add”,也可以雙擊要添加的文件進行加入。注意:點擊“Add”之後,窗口不會消失,如果要添加多個文件,可以不斷添加,添加完畢此時再點擊“Close”關閉該窗口。初學者時常誤認爲操作沒有成功而再次雙擊同一文件或者再次點擊“Add”,這時會出現如下的對話框。


在這裏我們把剛新建的HelloWorld.c添加進去,文件添加進去之後,我們點擊“Source Group 1”前面的“+”號,就會發現我們剛剛添加的文件HelloWrold.c已在其中了,雙擊文件名,即在代碼區打開該源程序文件。
除了添加文件,我們還可以添加新的Group,操作和添加文件類似,出現下拉菜單之後我們選擇“New Group”,這時就會在工程窗口看到新加的Group。對Group和添加文件的操作我們還可以通過點擊工具欄上的彩色品字按鈕進入“Components,Environment and Books”窗口,如下圖所示。


雙擊列表中的項可以對該項進行重命名操作,點擊空白處可以添加新的項,虛方框按鈕也可以添加新的項,紅叉表示刪除選中的項,上下箭頭用於調整當前選中項在列表中的位置,“Add Files”可以添加新的源文件,操作過程和前面添加文件的操作是一樣的。

5.1.4 編譯程序
程序代碼寫好之後就進入編譯程序階段,可以通過菜單,工具欄和浮動菜單多種方式來發起編譯過程,也可以通過批處理文件進行,關於這個批處理文件在Output標籤頁的設置中提到過。


紅線圈起來的區域就是對應的菜單編譯命令和工具欄編譯命令。各命令的含義如下:
 Clean target:清除編譯結果。
 Build target:編譯被修改的文件並且編譯應用程序。
 Rebuild all target files:重新編譯所有的源文件並且編譯應用程序。
 Batch Build:通過前面輸出的批處理文件進行編譯。
 Translate **.*:編譯某個源文件,**.*代表要編譯的源文件。
 Stop build:只有編譯進行過程中這一項纔有效。
通過在工程窗口“Target 1”上點擊右鍵,也可以彈出相應的編譯菜單,各命令含義和上面一致。


現在就讓我們來編譯我們的“HelloWorld”,如下圖所示,編譯的結果會在輸出窗口顯示。


很遺憾,有不少錯誤,也許你早就發現我們的代碼中使用了很多我們沒有定義的而且也不屬於標準C的一些函數,沒錯這就是ST固件庫給我們提供的函數,我們要做的就是把固件庫添加到我們的工程中,和其他的開發環境一下,我們可以直接添加固件庫的源文件和工程一起編譯,也可以通過添加已經編譯好的靜態連接庫(*.lib)文件。這裏我們以後者爲例,這些庫在我們安裝好Keil開發環境的時候已經提供了,路徑一般在你安裝目錄下的ARM\RV31\LIB\中,例如我這裏的路徑是D:\Keil\ARM\RV31\LIB\ST。這裏我們將添加一個新的Group,取名爲FWLIB。然後將庫文件添加到這個Group中,具體的操作過程可以參照編寫源程序章節。添加庫之後我們再次編譯。

問題解決了,當出現“0 Error(s), 0 Warning(s)”的時候也就意味着我們的程序已經通過了語法檢查,有時候一些Warning也不影響程序執行,但是我們要慎重對待,仔細分析每一個Warning。如果是源程序中有語法錯誤或者警告,我們可以通過雙擊輸出窗口的該行,快速定位到出錯的位置。

5.1.5 調試程序
編譯通過只是說明我們的代碼沒有語法錯誤,至於源程序中存在的其他錯誤,必須通過調試才能發現並解決,事實上,除了極簡單的程序以外,絕大部分的程序都要通過反覆調試才能得到正確的結果,因此,調試是軟件開發接下來我們需要運行我們的程序來驗證是否達到了預期的目的。也就是程序調試,程序調試往往是程序開發過程中最難的階段,尤其是對一些比較大型的程序。下面我們就來看看uVision3對調試的支持。

5.1.5.1 常用的調試命令
在對工程成功進行彙編、連接之後,按Ctrl+F5或者使用菜單Debug->Start/Stop Debug Session即可進入調試狀態。進入調試狀態後,界面與編輯狀態相比有明顯的變化,Debug才單項中原來不能用的命令現在已經可以使用了,工具欄會多出一個用於運行和調試的工具欄,如下圖所示,Debug菜單上的大部分命令可以在此找到對應的快捷按鈕。


常用的Debug菜單命令如下所示:
 Start/Stop Debug Session:開始或者停止調試。
 Run:一直執行下一個活動的斷點。
 Step:單步執行。
 Step Over:過程單步執行,即將一個函數作爲一個語句來執行。
 Step out of current Function:跳出當前的函數。
 Run to Cursor line:執行到光標所在的行。
 Stop Running:停止運行。
 Breakpoints:打開斷點對話框。
 Insert/Remove Breakpoint:在當前行插入/刪除一個斷點。
 Enable/Disable Breakpoint:激活當前行的斷點或者使斷點無效。
 Disable All Breakpoints:使程序中所有的斷點都無效。
 Kill all Breakpoints:刪除程序中所有的斷點。


學習程序調試,必須明確兩個重要的概念,即單步執行與全速執行。全速執行是指一行程序執行完了以後緊接着執行下一行程序,中間不停止,這樣程序執行的速度就很快,並可以看到該段程序執行的總體效果,即最終結果正確還是錯誤,但如果程序有錯,則難以確認錯誤出現在哪些程序行。單步執行是每次執行一行程序,執行完該行程序執行完以後即停止,等待命令執行下一行程序,此時我們可以觀察該行程序執行完以後得到的結果,是否與我們寫程序行所想要得的結果相同,藉此可以找到程序中問題所在。程序調試中,這兩種運行方式都要用到,要靈活應用,可以大大提高調試效率。
在調試窗口中,我們可以看到一個黃色的調試箭頭,指向了當前執行到的程序行。

5.1.5.2 斷點設置
程序調試時,有些程序行往往很難確認什麼時候能夠執行到,這類問題就不適合單步調試,這是我們需要使用程序調試中另一種非常重要的方法——斷點設置。斷點設置的方法有多種,常用的是在某一程序行設置斷點,設置好斷點之後可以全速運行程序,一旦執行到該程序行即停止,可在此觀察有關的變量值,以確定問題所在。設置斷點的命令請參考上一節常用調試命令介紹。一旦某一行被設置了斷點,我們可以在程序行的左端看到一個紅色方框(如圖5.24調試窗口圖所示),如果該斷點被禁用,方框將會變爲白色。
除了在某程序行設置斷點這一基本方法以外,uVision3還提供了多種設置斷點的方法,按Debug->Breakpoints,即出現一個對話框,該對話框用於對斷點進行詳細的設置,如下圖所示。


圖5.26中的Expression後的編輯框用於輸入表達式,該表達式用於確定程序停止運行的條件,功能強大,涉及到uVision3內置的一套調試算法,這裏不做詳細說明,請查閱相關幫助文檔。

5.1.5.3 調試窗口
前面講了調試的一些方法,裏面多次提到檢查程序的執行狀態。調試窗口就是用於查看程序執行狀態的。uVision3提供了多種調試窗口,如寄存器窗口,存儲器窗口,反彙編窗口,外設窗口等,下面將會一一作介紹。


1. 寄存器窗口
圖5.26是工程窗口寄存器頁的內容,寄存器頁包含了當前所有的工作寄存器和系統寄存器,每當程序中執行到對某個寄存器的操作時,該寄存器會反色顯示,用鼠標單擊然後按F2(鼠標連續單擊兩次),即可修改該值。
2. 存儲器窗口
存儲器窗口可以顯示系統中各種內存中的值,通過在Address後的編輯框中輸入“字母:數字”即可顯示相應內存值,其中字母C、D、I、X,分別代表代碼存儲空間、直接尋址的片內存儲空間、間接尋址的片內存儲空間、擴展的外部RAM單元值、鍵入C:0即可顯示從0開始的ROM單元中的值,即查看程序的二進制代碼。該窗口的顯示值可以以各種形式顯示,如十進制、十六進制、字符型等。改變顯示方式的方法是點鼠標右鍵,在彈出的快捷菜單中選擇。除了顯示,還可以修改內存中的值,如下圖所示。


3. 查看和調用棧窗口
這個窗口可以幫助我們查看當前調用樹的情況,我們還可以通過這個窗口查看和修改一些變量的值。鼠標停留在某個變量的時候點右鍵,在彈出的浮動菜單中選擇Add ***to Watch window,Local 窗口顯示當前一些局部變量的值,變量值的現實方式可以在十六進制和十進制之間切換,方式是在查看窗口點右鍵,在某個變量的Value欄用鼠標單擊然後按F2(鼠標連續單擊兩次),即可修改該值。如下圖所示。


4. 反彙編窗口
點擊View->Dissambly Window可以打開反彙編窗口,該窗口可以顯示反彙編後的代碼、源代碼和相應反彙編代碼的混合代碼,可以在該窗口進行在線彙編、利用該窗口跟蹤已找行的代碼、在該窗口按彙編代碼的方式單步執行。點擊鼠標右鍵,出現快捷菜單,如圖5.29所示,其中Mixed Mode是以混合方式顯示,Assembly Mode是以返回編碼方式顯示。


5. 外設窗口
爲了能夠比較直觀地瞭解單片機中各種外設的使用情況,uVison3提供了一個外圍接口對話框。通過Peripherals菜單,下拉菜單中的內容和你選擇的芯片有關,會列出你所選擇的芯片上所有的外設。選擇一項你可以進入查看或修改該外設的一些狀態。例如在這裏我們是通過GPIO中的PB9來控制LED閃爍,我們可以打開GPIOB的狀態對換框,如圖5.30所示。


現在我們可以調試我們的HelloWorld了。程序運行時,你將看到開發板上的L1不停閃爍。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章