建立相關文件夾如圖所示

FWLIB放官方固件庫文件,HARDWARE放自己編寫的.C,.H文件,USER放主函數文件,工程,啟動文件等。
1,首先,打開 MDK(以下將 MDK5 簡稱為 MDK)軟件。然后點擊 Project---New uVision Project ,然后保存在USER文件夾下,工程名自取。
2,選擇 STMicroelectronics--STM32F4 Series--STM32F407--STM32F407ZGT6(如果使用的是其他系列的芯片,選擇相應的型號就可以了,特別注意: 一定要安裝對應的器件 pack
才會顯示這些內容哦!!)。
3,點擊 OK, MDK 會彈出 Manage Run-Time Environment 對話框 。這是 MDK5 新增的一個功能,在這個界面,我們可以添加自己需要的組件,從而方便構建開發環境,不過這里我們
不做介紹。所以在圖 3.2.4 所示界面,我們直接點擊 Cancel,即可。得到如圖所示界面:

4,到這里,我們還只是建了一個框架,還需要添加啟動代碼,以及.c 文件等。這里我們先介紹一下啟動代碼: 啟動代碼是一段和硬件相關的匯編代碼。 是必不可少的! 這代碼主要作用如
下:
1、堆棧(SP)的初始化;
2、初始化程序計數器(PC);
3、設置向量表異常事件的入口地址;
4、調用 main 函數。感興趣的朋友可以自己去分析這部分代碼。
ST 公司為 STM32F40x 和 STM32F41x 系列的 STM32F4 提供了一個共同的啟動文件,名字為: startup_stm32f40_41xxx.s。 我們開發板使用的是 STM32F407ZGT6, 屬於 STM32F40x 系列
里面的,所以直接使 startup_stm32f40_41xxx.s 這個啟動文件即可。 不過這個啟動文件,我們做了一點點修改,具體是 Reset_Handler 函數,該函數修改后代碼如下:
Reset_Handler PROC EXPORT Reset_Handler [WEAK] ;IMPORT SystemInit ;寄存器代碼,不需要在這里調用 SystemInit 函數, ;故屏蔽掉,庫函數版本代碼,可以留下 ;不過需要在外部實現 SystemInit 函數,否則會報錯. IMPORT __main LDR R0, =0xE000ED88 ;使能浮點運算 CP10,CP11 LDR R1,[R0] ORR R1,R1,#(0xF << 20) STR R1,[R0] ;LDR R0, =SystemInit ;寄存器代碼,未用到,屏蔽 ;BLX R0 ;寄存器代碼,未用到,屏蔽 LDR R0, =__main BX R0 ENDP
這段代碼,我們主要加入了開啟 STM32F4 硬件 FPU 的代碼,以使能 STM32F4 的浮點運算單元。其中, 0xE000ED88 就是協處理器控制寄存器(CPACR)的地址,該寄存器的第 20~23
位用來控制是否支持浮點運算,這里我們全設置為 1,以支持浮點運算。關於 CPACR 寄存器的詳細描述,見《STM32F3 與 F4 系列 Cortex M4 內核編程手冊.pdf》第 4.6.1 節。另外,寄存器
版本,我們還屏蔽了 SystemInit 函數的調用,如果是庫函數版本,可以取消這個函數的注釋,並在外部實現 SystemInit 函數。
特別注意:我們在匯編代碼里面使能了 FPU,所以在 MDK 里面,我們也要設置使用 FPU,否則可能代碼會無法運行,設置方法如下:選擇 Options for Target ‘Target1’ ,打開 Target 選
項卡,在 Code Generation 里面,選擇 Use FPU,如圖 所示:

這樣, MDK 編譯生成的代碼,就可以直接使用硬件 FPU 了,其實就 2 個步驟: 1,設置CPACR 寄存器 20~23 位全為 1,使能硬件 FPU。 2,設置 MDK 選型,選擇 Use FPU。另外,
圖 中, MDK 默認 STM32F4 外部晶振為 12M,我們板子用的 8M,所以這里設置為 8Mhz。修改后的這個啟動文件 startup_stm32f40_41xxx.s 拷貝到剛剛新建的USER文件夾里面。
5,在圖中,我們找到 Target1--Source Group1--雙擊--設置打開文件類型為 Asm Source file--選擇 startup_stm32f40_41xxx.s--點擊 Add,如圖所示:

添加完后,我們得到如圖所示的界面:

至此,我們就可以開始編寫自己的代碼了。
由於上面我們還沒有任何代碼在工程里面,這里我們把系統代碼 COPY 過來(即 SYSTEM文件夾的代碼,該文件夾由 ALIENTEK 提供,可以在光盤任何一個實例的工程目錄下找到,不過不要
拷貝錯了! 不要把庫函數代碼的系統文件夾拷貝到寄存器代碼里面用,反之亦然! 這些代碼在任何 STM32F40x/STM32F41x 的芯片上都是通用的,可以用於快速構建自己的工程)。
SYSTEM 文件夾下包含了 delay、 sys、 usart 等三個文件夾。分別包含了 delay.c、 sys.c、 usart.c及其頭文件。通過這 3 個 c 文件,可以快速的給任何一款 STM32F4 構建最基本的框架。使用
起來是很方便的。 具體可以百度學習一下。
6,然后在 Target 目錄樹上點擊右鍵--Manage Project Items, 彈出如圖 所示對話框:

在上面對話框的中間欄,點新建(用紅圈標出) 按鈕(也可以通過雙擊下面的空白處實現),新建 USER 和 SYSTEM 兩個組。 然后點擊 Add Files 按鈕,把 SYSTEM 文件夾三個子文件夾里
面的: sys.c、 usart.c、 delay.c 加入到 SYSTEM 組中。注意: 此時 USER 組下還是沒有任何文件, 得到如圖所示的界面:

點擊 OK,退出該界面返回 IDE。 這時,我們在 Target1 樹下發現多了 2 個組名,就是我們剛剛新建的 2 個組。如圖 所示:

7,接着,我們新建一個 test.c 文件,並保存在 USER 文件夾下。 然后雙擊 USER 組,會彈出加載文件的對話框,此時我們在 USER 目錄下選擇 test.c 文件,加入到 USER 組下。 得到如圖
所示的界面:

至此,我們就可以開始編寫我們自己的代碼了。 我們在 test.c 文件里面輸入如下代碼:
#include "sys.h" #include "usart.h" #include "delay.h" int main(void) { u8 t=0; Stm32_Clock_Init(336,8,2,7);//初始化時鍾為 168Mhz delay_init(168); //初始化延時函數 uart_init(84,115200); //串口初始化為 115200 while(1) { printf("t:%d\r\n",t); delay_ms(500); t++; } }
如果我們此時編譯的話, 生成的過程文件,還是會存放在 USER 文件夾下,所以,我們先設置輸出路徑,再編譯。 點擊 (Options for Target 按鈕),彈出 Options for Target’ Target 1’
對話框,選擇 Output 選項卡--選中 Create Hex File(用於生成 Hex 文件,后面會用到)--點擊Select Folder for Objects--找到 OBJ 文件夾--點擊 OK。
接着,再設置 Listings 文件路徑,在上文的基礎上,打開 Listing 選項卡--點擊 Select Folder for Listings--找到 OBJ 文件夾--點擊 OK。
8,現在我們再次點擊 (Options for Target 按鈕),彈出 Options for Target’ Target 1’ 對話框,選擇 C/C++選項卡,如圖 所示: 
這里特別提醒大家: 圖中 1 處設置的 STM32F40_41xxx 宏,是為了兼容低版本的 MDK(比如 MDK4/MDK3 等)才添加的, MDK5 在你選擇器件的時候,就會內部定義這個宏,因此在
MDK5 下面,這里不設置也是可以的。但是為了兼容低版本的 MDK,我們還是將這個宏添加進來。
圖中 2 處是編譯器優化選項,有-O0~-O3 四種選擇(default 則是-O2),值越大,優化效果越強,但是仿真調試效果越差。這里我們選擇-O0 優化,以得到最好的調試效果,方便開發代
碼,在代碼調試結束后,大家可以選擇-O2 之類的優化,得到更好的性能和更少的代碼占用量。
圖中 3 處, One ELF Section per Function 主要是用來對冗余函數的優化。通過這個選項,可以在最后生成的二進制文件中將冗余函數排除掉,以便最大程度地優化最后生成的二進制代
碼,所以,我們一般勾選上這個,這樣可以減少整個程序的代碼量。
然后在 Include Paths 處(4 處),點擊 5 處的按鈕。在彈出的對話框中加入 SYSTEM 文件夾下的 3 個文件夾名字,把這幾個路徑都加進去(此操作即加入編譯器的頭文件包含路徑, 后
面會經常用到)。如圖 所示:

點擊 OK 確認,回到 IDE,此時再點擊 按鈕,(bulid)編譯一次,發現沒錯誤了,得到如圖 所示的界面:

因為我們之前選擇了生成 Hex 文件,所以在編譯的時候, MDK 會自動生成 Hex 文件(圖中圈出部分),這個文件在 OBJ 文件夾里面,串口下載的時候,我們就是下載這個文件到
STM32F4 里面的,這個在后面的程序下載一節會介紹。
這里有的朋友編譯后,可能會出現一個警告: warning: #1-D last line of file ends without anewline。這個警告是在告訴我們,在某個 C 文件的最后,沒有輸入新行,我們只需要雙擊這個
警告,跳轉到警告處,然后在后面輸入多一個空行就好了。
至此,一個完整的 STM32F4 開發工程在 MDK5 下建立了。 接下來我們就可以進行代碼下載和仿真調試了。
關於代碼,其實就是配置系統時鍾,開啟外設時鍾,配置外設,功能代碼,一般就是這樣的流程
**************************************************************************************************
文本美化,主要是設置一些關鍵字、注釋、數字等的顏色和字體。 前面我們在介紹 MDK5新建工程的時候看到界面如圖 3.2.23 所示,這是 MDK 默認的設置, 可以看到其中的關鍵字和
注釋等字體的顏色不是很漂亮,而 MDK 提供了我們自定義字體顏色的功能。我們可以在工具條上點擊扳手圖樣 (配置對話框)彈出如圖 所示界面:

在該對話框中,先設置 Encoding 為:Chinese GB2312(Simplified),然后設置 Tab size 為: 4。以更好的支持簡體中文(否則,拷貝到其他地方的時候,中文可能是一堆的問號),同時 TAB
間隔設置為 4 個單位。然后,選擇: Colors&Fonts 選項卡,在該選項卡內,我們就可以設置自己的代碼的子體和顏色了。由於我們使用的是 C 語言,故在 Window 下面選擇: C/C++ Editor Files
在右邊就可以看到相應的元素了。如圖 示:

然后點擊各個元素修改為你喜歡的顏色(注意雙擊,且有時候可能需要設置多次才生效,MDK 的 bug),當然也可以在 Font 欄設置你字體的類型,以及字體的大小等。設置成之后,點
擊 OK, 就可以在主界面看到你所修改后的結果 。
這就比開始的效果好看一些了。 字體大小,則可以直接按住: ctrl+鼠標滾輪,進行放大或者縮小,或者也可以在剛剛的配置界面設置字體大小。
細心的讀者可能會發現,上面的代碼里面有一個 u8,還是黑色的,這是一個用戶自定義的關鍵字,為什么不顯示藍色(假定剛剛已經設置了用戶自定義關鍵字顏色為藍色)呢?這就又
要回到我們剛剛的配置對話框了,單這次我們要選擇 User Keywords 選項卡,同樣選擇: C/C++Editor Files,在右邊的 User Keywords 對話框下面輸入你自己定義的關鍵字

圖 3.3.5 中我定義了 u8、 u16、 u32 等 3 個關鍵字,這樣在以后的代碼編輯里面只要出現這三個關鍵字,肯定就會變成藍色。點擊 OK,再回到主界面,可以看到 u8 變成了藍色了
快速定位函數/變量被定義的地方 :右鍵

快速注釋與快速消注釋 :

**************************************************************************
串口只能下載代碼,並不能實時跟蹤調試,而利用調試工具,比如 JLINK、 ULINK、 STLINK等就可以實時跟蹤程序, 從而找到你程序中的 bug, 使你的開發事半功倍。這里我們以 JLINK
V8 為例,說說如何在線調試 STM32F4。
JLINK V8 支持 JTAG 和 SWD, 同時 STM32F4 也支持 JTAG 和 SWD。所以,我們有 2 種方式可以用來調試, JTAG 調試的時候,占用的 IO 線比較多,而 SWD 調試的時候占用的 IO 線
很少,只需要兩根即可。
JLINK V8 的驅動安裝比較簡單, 我們在這里就不說了。在安裝了 JLINK V8 的驅動之后,我們接上 JLINK V8,並把 JTAG 口插到 ALIENTEK 探索者 STM32F4 開發板上,打開之前
新建的工程, 點擊 ,打開 Options for Target 選項卡,在 Debug 欄選擇仿真工具為 J-LINK/J-TRACE Cortex,如圖 所示:

上圖中我們還勾選了 Run to main(),該選項選中后, 只要點擊仿真就會直接運行到 main 函數, 如果沒選擇這個選項,則會先執行 startup_stm32f40_41xxx.s 文件的 Reset_Handler,再跳到
main 函數。
然后我們點擊 Settings,設置 J-LINK 的一些參數,如圖 4.2.2 所示:

圖 中,我們使用 J-LINK V8 的 SW 模式調試,因為我們 JTAG 需要占用比 SW 模式多很多的 IO 口,而在 ALIENTEK 探索者 STM32F4 開發板上這些 IO 口可能被其他外設用到,可
能造成部分外設無法使用。所以,我們建議大家在調試的時候,一定要選擇 SW 模式。Max Clock,可以點擊 Auto Clk 來自動設置, 圖 中我們設置 SWD 的調試速度為 10Mhz,這里,如果你
的 USB 數據線比較差,那么可能會出問題,此時, 你可以通過降低這里的速率來試試。
單擊 OK,完成此部分設置,接下來我們還需要在 Utilities 選項卡里面設置下載時的目標編程器,如圖 所示:

圖中, 我們直接勾選 Use Debug Driver,即和調試一樣,選擇 JLINK 來給目標器件的FLASH 編程, 然后點擊 Settings,設置如圖所示:

這里 MDK5 會根據我們新建工程時選擇的目標器件,自動設置 flash 算法。我們使用的是STM32F407ZGT6, FLASH 容量為 1M 字節, 所以 Programming Algorithm 里面默認會有 1M 型
號的 STM32F4xx FLASH 算法。 特別提醒: 這里的 1M flash 算法,不僅僅針對 1M 容量的STM32F4,對於小於 1M FLASH 的型號,也是采用這個 flash 算法的。 最后, 選中 Reset and Run
選項,以實現在編程后自動運行, 其他默認設置即可。設置完成之后,如上圖 所示。
在設置完之后,點擊 OK,然后再點擊 OK,回到 IDE 界面,編譯一下工程。 然后點擊:
(開始/停止仿真按鈕),開始仿真(如果開發板的代碼沒被更新過,則會先更新代碼(即下載
代碼),再仿真, 你也可以通過按 load按鈕,只下載代碼,而不進入仿真。 特別注意:開發板上的 BOOT0和 BOOT1 都要設置到 GND,否則代碼下載后不會自動運行的!), 如圖所示:

因為我們之前勾選了 Run to main()選項,所以,程序直接就運行到了 main 函數的入口處。另外,此時 MDK 多出了一個工具條, 這就是 Debug 工具條,這個工具條在我們仿真的時候是
非常有用的,下面簡單介紹一下 Debug 工具條相關按鈕的功能。 Debug 工具條部分按鈕的功能如圖 所示:

復位:其功能等同於硬件上按復位按鈕。相當於實現了一次硬復位。 按下該按鈕之后, 代碼會重新從頭開始執行。
執行到斷點處:該按鈕用來快速執行到斷點處,有時候你並不需要觀看每步是怎么執行的,而是想快速的執行到程序的某個地方看結果,這個按鈕就可以實現這樣的功能,前提是你在查
看的地方設置了斷點。
停止運行:此按鈕在程序一直執行的時候會變為有效,通過按該按鈕,就可以使程序停止下來,進入到單步調試狀態。
執行進去: 該按鈕用來實現執行到某個函數里面去的功能,在沒有函數的情況下,是等同於執行過去按鈕的。
執行過去:在碰到有函數的地方,通過該按鈕就可以單步執行過這個函數,而不進入這個函數單步執行。
執行出去:該按鈕是在進入了函數單步調試的時候,有時候你可能不必再執行該函數的剩 余部分了,通過該按鈕就直接一步執行完函數余下的部分,並跳出函數,回到函數被調用的位
置。
執行到光標處:該按鈕可以迅速的使程序運行到光標處,其實是挺像執行到斷點處按鈕功能,但是兩者是有區別的,斷點可以有多個,但是光標所在處只有一個。
匯編窗口:通過該按鈕,就可以查看匯編代碼,這對分析程序很有用。
堆棧局部變量窗口:通過該按鈕, 顯示 Call Stack+Locals 窗口,顯示當前函數的局部變量及其值,方便查看。
觀察窗口: MDK5 提供 2 個觀察窗口(下拉選擇),該按鈕按下,會彈出一個顯示變量的窗口, 輸入你所想要觀察的變量/表達式,即可查看其值, 是很常用的一個調試窗口。
內存查看窗口: MDK5 提供 4 個內存查看窗口(下拉選擇), 該按鈕按下,會彈出一個內存查看窗口,可以在里面輸入你要查看的內存地址,然后觀察這一片內存的變化情況。是很常
用的一個調試窗口
這里stlink與jlink其實用法是一樣的,選着對應的選項即可。
