第一次在這發博文,先上一篇乾貨,記錄瞭如何在MDK下新建一個STM32L系列的工程,雖然事情比較低端,可是加了一些本身的思考,算做記錄。php
以前都是研究例程或者在官方模板工程上改的程序,沒有新建過工程。編程
昨晚試了下新建工程成功了,可是今天早上打開工程文件發現MDK報錯說文件不能讀取,猜想多是虛擬機異常退出致使的。因而從新建了個,加深了下對環境的理解。步驟以下。ide
準備好庫文件函數
能夠去ST官網http://www.st.com或者官方社區http://www.stmcu.org下載。大力推薦後者,軟硬件文檔和庫都很是齊全,歸類有序。很多型號的芯片還有中文文檔。 工具
庫文件說明解壓下載來的zip,獲得的文件或文件夾以下。測試
幾個關鍵的簡單說明一下:ui
文件夾Libraries:庫的本體,編程的時候只要這個文件夾裏面的內容就能夠了。
spa
文件夾Project:官方例程,很是全。可是我只能看看,由於沒有和這個例程配套的評估板。3d
文件夾Utilities:開發板相關的庫函數。有2種評估板,淘寶都要2k多一塊,嚇尿了,相比之下我買的STM32L-Discovery,80不到還自帶ST-Link,簡直不要錢。╮(╯▽╰)╭調試
CHM文件STM32l1xx...:幫助文檔,挺有用的。其中大部份內容是根據庫中的代碼註釋自動生成的。
點擊菜單Project ->New μVision Project,先選擇路徑。由於想研究一下DMA,因此我把工程新建在C:\L\test\DMA\下,以前有把庫文件夾Library也拷貝到test這個目錄下。
以後在彈出的對話框中選擇CPU型號。
這裏要說一下,我最先用的是MDK4.1,版本太舊,沒有L系列的CPU能夠選擇,只好更新。可是更新到MDK4.7以後有一個盜版的JLINK用不了,無奈啊。如今和學長2人用1個JLINK不方便。買了ST-Link還在路上,ST-Link只支持ST公司的MCU。
個人Discovery開發板上的MCU是152RB。
導入啓動文件而後會彈出一個對話框,問要不要導入啓動文件,這裏選擇是。
這個文件實際上是根據不一樣型號的MCU選出來的,分爲Medium-Density,Medium-Density Plus,High-Density3種。152RB屬於Medium-Density,能夠看到自動導入的文件是以md結尾。
使用Manage Component功能添加文件此時能夠看到Project窗口中有一個Target叫Target1,其中有一個源文件組叫Source Group 1,這麼原生態的必須改掉!
能夠在Project窗口的Target上點右鍵選擇Manage Component進入,或者直接點工具欄上品字形的圖標進入該功能。這個功能能夠方便地添加、刪除、修改Target及Target下的Source Groupe以及每一個Group下的文件。
這裏把Target叫作DMA,3個組,其中StartUp中含有這個啓動文件,另外2個組仍是空的。
而後,
在StartUp組中添加/Libraries/CMSIS/Device/STSTM32L1xx/Source/Templates/目錄下的system_stm32l1xx.c文件;
在STM32L1xx_StdPeriph_Drive組中添加須要用到的驅動文件,我暫時只添加了rcc和gpio這2個文件;
在User中添加新建的空文件main.c。
添加完成的Project窗口後以下圖。
include stm32l1xx.h幫助文檔是這樣寫的:
第一件事MDK剛幫咱們作好,接下來第二件事就是include這個entry point文件了。
直接在main.c裏面include之,根據要求還要依照咱們的MCU類型,定義一個宏STM32L1XX_MD,下一步會講。
這時候問題來了,MDK如何知道去×××這個文件呢?詳見下一步。
使用Target Option功能配置include path和宏這個功能能夠在Project Window的Target上點右鍵選擇Target Option,或者點擊工具欄上的快捷圖標或者按快捷鍵Alt+F7進入。
其中有好多標籤,下面據我所知說一下。
Device:選擇硬件,若是建工程的時候選錯了或者要換硬件,能夠在這裏進行。
Target:不太清楚幹啥用的,沒管過。
Output:選擇輸出的Obj等文件的設置,能夠選擇輸出路徑,新建一個會文件夾會比較清爽。另外若是要生成HEX文件的話也在這裏選。
Listing:Lis文件的設置,也能夠新建個文件夾來存放。
User:這裏能夠定義一些在編譯的時候用戶要額外作的事情,好比能夠調用個外部指令生成BIN文件之類的,都在這裏寫指令。
C/C++:include Path就在這裏選擇,除了工程的當前目錄,還須要在庫中選擇3個,詳見下圖。另外還需定義兩個宏,上一步提到的STM32L1XX_MD和USE_STDPERIPH_DRIVER。這第二個宏要定義了才能用標準庫,具體下一步會講。
Asm:彙編代碼相關,沒管過。
Linker:連接相關,沒管過。
Debug:調試相關的選項,默認用的是模擬器。須要根據本身的環境選擇相應的在線調試工具。詳見後文。
Utilities:燒錄相關選項,也要配置,後文細說。
此時編譯的話是通不過的,會報函數沒定義的Error。
打開stm32l1xx.h這個所謂的entry point,在6315行到6317行能夠看到如下代碼:
#ifdef USE_STDPERIPH_DRIVER #include "stm32l1xx_conf.h" #endif
上一步定義的這個宏,做用其實只是多include一個叫作stm32l1xx_conf.h的文件。而坑爹的是,這個文件在庫函數裏面是沒有的,要本身寫!
萬幸,在評估板的例程裏面,這個文件都是有的,果斷複製了一個過來到個人目錄下。打開一看,除了include文件,也就定義了一個用來檢驗參數類型是否符合要求的assert宏而已。
使用Target Option功能配置Debug和Utilities環境這個時候在main.c裏面加一個mian函數作入口,其實已經能夠編譯成功了,以下圖。可是要燒錄到板子上或者是在線調試的話,還須要配置。
在Target Option的Debug標籤,根據環境選擇合適的調試工具。默認是左邊的模擬器,我用的是ST-Link。點擊ST-Link邊上的Setting按鈕,對ST-Link的進行配置,要配成SW模式,配置成功的話能夠看到Device信息,以下圖。
和Debug相似,在Utilities標籤,選擇根據環境選擇合適的下載工具以及Flash Size。Flash Size的話,建議查閱芯片的Datasheet來肯定。STM32的話,由芯片型號STM32L1xx以後的第二個字母體現,我用的是B,表示128k,以下圖。
不出意外,到此爲止一個工程已經新建完畢。寫了幾行代碼,開了時鐘,配置了GPIO口,而後循環讓PB6這個口無腦跳變。
#include "stm32l1xx.h" #include "system_stm32l1xx.h" #include "stm32l1xx_rcc.h" #include "stm32l1xx_gpio.h" void LED_Init(void); int main() { uint8_t led_f = 0; SystemInit(); LED_Init(); while(1) { if(led_f == 0){GPIO_SetBits(GPIOB,GPIO_Pin_6); led_f =1;} else{GPIO_ResetBits(GPIOB,GPIO_Pin_6); led_f =0;} } } void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); }
燒到板子裏,reset一按,燈亮了。接上示波器看到下圖,說明確實在跳變。
順便,這裏的跳變週期和佔空比,和指令數有關,具體要研究system_stm32l1xx.c中的函數了。
若是須要特定的佔空比和頻率的話,可使用STM32定時器TIM的PWM輸出功能。