stm32標準外設庫使用詳解


     stm32標準外設庫是stm32全系列芯片的外設驅動,有了它可以大大加速我們開發stm32。
    首先從st公司的網站下載最新的stm32標準外設庫,寫本文時最新的版本是V3.5.0。

    解壓該zip文件,得到如下文件夾和文件
STM32F10x_StdPeriph_Lib_V3.5.0\
   _htmresc
   Libraries
   Project
   Utilities
   Release_Notes.html
   stm32f10x_stdperiph_lib_um.chm


    其中Libraries包含庫的源代碼,Project包含stm32各個外設的使用範例和一個工程模板,Utilities是使用st公司評估板的例子,stm32f10x_stdperiph_lib_um.chm教我們怎麼用標準外設庫。

工程目錄結構
    既然準備使用32位單片機,應該是個不小項目,因此工程目錄也應該做個規劃。這裏我推薦一下我所使用的目錄結構。假設工程名字叫template,建一個名爲template的文件夾,該目錄下有個3個固定文件夾doc,src,include,doc用來存放工程相關的資料文件,src放源代碼,在src下每個功能模塊一個文件夾,include放各個模塊都要使用的公共頭文件。output放編譯輸出文件,內含兩個子文件夾obj和list。

template\
   doc
   src
   include
   output\obj
             \list
      
整理庫代碼
    由於Libraries下的CMSIS文件夾中很多代碼是和編譯器及芯片相關的,導致文件夾多且深度大,不利於工程維護,實際上一個項目往往是用固定的編譯器和芯片,因此有必要對庫進行整理。
    在src下建立libstm32目錄
    1. 把Libraries\STM32F10x_StdPeriph_Driver\下的內容拷貝到libstm32目錄下
    2. 在libstm32目錄下建立cmsis文件夾,把Libraries\CMSIS\CM3\CoreSupport\下的core_cm3.c,core_cm3.h;Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\下的stm32f10x.h,system_stm32f10x.c,system_stm32f10x.h拷貝到cmsis文件夾中。
    3. 根據你所選的芯片類型將Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm\下對應的啓動文件拷貝到cmsis文件夾中。這裏我拷貝的是startup_stm32f10x_hd.s(大容量型stm32芯片的啓動文件)。

   下面對該庫文件做個簡單介紹:
    Libraries\STM32F10x_StdPeriph_Driver\下的內容很好理解就是stm32的各個外設模塊驅動代碼。
    misc.h和misc.c是和CM3內核有關的NVIC和SysTick的驅動代碼。   
    Libraries\CMSIS下是什麼呢?cmsis英文全稱:Cortex Microcontroller Software Interface Standard,是Cortex系列處理器硬件抽象層,可以理解爲cortex內核的軟件接口。
    core_cm3.c, core_cm3.h
    它們的目錄名爲CoreSupport,說明這兩個文件是CM3內核支撐文件,其他使用CM3內核的芯片也可以用,不一定是stm32。這兩個文件用來獲取設置CM3內核,配置一些內核寄存器。
    stm32f10x.h, system_stm32f10x.c, system_stm32f10x.h和startup_stm32f10x_hd.s在DeviceSupport目錄下,說明這幾個文件是和具體的芯片有關的,也就是stm32芯片的支撐文件。其中stm32f10x.h是標準外設庫的入口,使用標準外設庫的代碼中必須包含該頭文件。system_stm32f10x.c, system_stm32f10x.h這兩個文件提供函數用來初始化stm32芯片,配置PLL、系統時鐘和內置flash接口。startup_stm32f10x_hd.s是大容量型stm32芯片的啓動文件。
    
建立工程   
    使用keil MDK(我使用4.12版)在template目錄下建立工程,工程名爲template。選一個stm32系列的芯片,哪一個都無所謂(我選的是STM32F101RC,因爲我的板子就是用這個芯片),接下來要注意的是當彈出是否拷貝啓動代碼到工程文件夾時要選No,因爲標準外設庫裏已經有啓動代碼了。
    將UV4中project window裏的頂層目錄名改爲template,並將第一個group名改爲libstm32。把libstm32目錄下所有.c和.s文件加載到工程裏的libstm32。
    在src下建立一個init目錄用來放置系統初始化代碼。把Project\STM32F10x_StdPeriph_Template\下的stm32f10x_it.c拷貝到init文件夾中,stm32f10x_it.h,stm32f10x_conf.h拷貝到include文件夾中。
    stm32f10x_it.c,stm32f10x_it.h是中斷服務程序文件。stm32f10x_conf.h是標準外設庫的配置文件,對於工程中不需要的外設,可以註釋掉裏面的包含的頭文件。這裏我建議先僅留下stm32f10x_gpio.h,stm32f10x_rcc.h,misc.h,用到什麼再打開什麼,這樣編譯起來快一點,當然也可都留着。

使用stm32標準外設庫
    事實上,stm32標準外設庫的使用在stm32f10x_stdperiph_lib_um.chm中的How to use the Library一節中已有說明,下面我把其中的步驟羅列一下:
1. 根據所選芯片,把Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm中的啓動代碼加到工程中,這一步在上面已經做過了。
2. 在stm32f10x.h的66-73行,根據所選芯片類型,去掉相應註釋,這裏我去掉STM32F10X_HD行的註釋(大容量型stm32芯片)。
3. 去掉105行的USE_STDPERIP
H_DRIVER註釋,啓用stm32標準外設庫。
4. 在system_stm32f10x.c的110-115行,根據所選芯片主頻,去掉相應註釋,默認SYSCLK_FREQ_72MHz註釋已去掉,如果你的芯片主頻是72MHz,就不用做修改了,這裏我的芯片是36MHz,註釋SYSCLK_FREQ_72MHz,去掉SYSCLK_FREQ_36MHz註釋。

跑馬燈程序
   現在可以使用stm32標準外設庫了,下面以一個簡單的跑馬燈程序說明。

在init目錄下建立main.c作爲系統入口。

在src下建立一個bsp目錄用來放置板級支持代碼,建立led.c,led.h。

代碼如下:
led.h

  1. <span style="font-size:18px;">#ifndef _LED_H_  
  2. #define _LED_H_  
  3.   
  4. #include <stdint.h>  
  5.   
  6. #define LED_0     0  
  7. #define LED_1     1  
  8. #define LED_2     2  
  9.   
  10. void led_init(void);  
  11. void led_on(uint32_t n);  
  12. void led_off(uint32_t n);  
  13.   
  14. #endif  
  15.   
  16. </span>  

 

led.c

  1. <span style="font-size:18px;">#include "stm32f10x.h"  
  2. #include "led.h"  
  3.   
  4. void led_init(void)  
  5. {  
  6.  GPIO_InitTypeDef GPIO_InitStructure;  
  7.    
  8.  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);  
  9.  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;  
  10.  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
  11.  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;  
  12.  GPIO_Init(GPIOC, &GPIO_InitStructure);  
  13. }  
  14.   
  15. void led_on(uint32_t n)  
  16. {  
  17.  switch (n)  
  18.  {  
  19.   case LED_0:  
  20.    GPIO_SetBits(GPIOC, GPIO_Pin_6);  
  21.    break;  
  22.   case LED_1:  
  23.    GPIO_SetBits(GPIOC, GPIO_Pin_7);  
  24.    break;  
  25.   case LED_2:  
  26.    GPIO_SetBits(GPIOC, GPIO_Pin_8);  
  27.    break;  
  28.   default:  
  29.    break;  
  30.  }  
  31. }  
  32.   
  33. void led_off(uint32_t n)  
  34. {  
  35.  switch (n)  
  36.  {  
  37.   case LED_0:  
  38.    GPIO_ResetBits(GPIOC, GPIO_Pin_6);  
  39.    break;  
  40.   case LED_1:                              
  41.    GPIO_ResetBits(GPIOC, GPIO_Pin_7);  
  42.    break;  
  43.   case LED_2:  
  44.    GPIO_ResetBits(GPIOC, GPIO_Pin_8);  
  45.    break;  
  46.   default:  
  47.    break;  
  48.  }  
  49. }</span>  

 

根據不同的板子需要對該代碼中的管腳進行修改,但結構是一樣的。

main.c

  1. <span style="font-size:18px;">#include "led.h"  
  2.   
  3. static void delay(uint32_t ms)  
  4. {  
  5.  uint32_t count = 8000;  
  6.  while (ms--)  
  7.  {  
  8.   while (count--);  
  9.   count = 8000;  
  10.  }  
  11. }  
  12.   
  13. int main(void)  
  14. {  
  15.  led_init();  
  16.    
  17.  for (;;)  
  18.  {  
  19.   led_on(LED_0);  
  20.   led_off(LED_1);  
  21.   led_off(LED_2);  
  22.   delay(1000);  
  23.   
  24.   led_off(LED_0);  
  25.   led_on(LED_1);  
  26.   led_off(LED_2);  
  27.   delay(1000);  
  28.   
  29.   led_off(LED_0);  
  30.   led_off(LED_1);  
  31.   led_on(LED_2);   
  32.   delay(1000);  
  33.  }  
  34. }  
  35. </span>  


 

    在project中建立init,bsp組,並將各種代碼加入。在工程的Options中,c/c++選項卡的Include Paths中添加.\include;.\src\libstm32\cmsis;.\src\libstm32\inc;.\src\bsp;。 
    Output選項卡Select Folder for Objects中選.\output\obj。
    Listing選項卡Select Folder for Listings中選.\output\list。
    Debug選項卡選use ULINK Cortex Debugger, Run to main()打鉤,這一步大家可以根據自己手上的仿真器做不同選擇。
    編譯運行


轉載請註明出處:http://blog.csdn.net/lbl1234

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