天天看點

stm32f4xx标準外設固件庫(By King先生)

原文網址:http://www.cnblogs.com/King-Gentleman/p/4369381.html 

STM32F4的相關資料:http://www.stmcu.org/document/list/index/category-523

一、标準固件庫簡介

本文下載下傳的是STM32F4xx_DSP_StdPeriph_Lib_V1.5.0,其檔案夾如下圖所示:

stm32f4xx标準外設固件庫(By King先生)

      其中Project檔案夾為各個開發環境(MDK-ARM、EWARM、TrueSTUDIO)的模闆工程,Utilities檔案夾為官方評估闆的标準固件庫應用例程,而真正的标準固件庫在Libraries檔案夾中。在Libraries檔案夾中:CMSIS檔案夾主要包含于核心相關的檔案;STM32F4xx_StdPeriph_Driver檔案夾為STM32F4xx處理器外設相關的底層驅動。

      以下為固件庫移植時CMSIS檔案夾中的重要源檔案:

core_cm4.h         :核心功能的定義,比如NVIC相關寄存器的結構體和Systick配置。在CMSIS/Include中

core_cmFunc.h    :核心核心功能接口頭檔案。在CMSIS/Include中

core_cmInstr.h    :包含一些核心核心專用指令。在CMSIS/Include中

core_cmSimd.h   :包含與編譯器相關的處理。在CMSIS/Include中

stm32f4xx.h        :包含了stm32f4的寄存器結構體的定義(類似于c51的reg52.h)。在CMSIS\Device\ST\STM32F4xx\Include中

system_stm32f4xx.h         :system_stm32f4xx.c的頭檔案。在CMSIS\Device\ST\STM32F4xx\Include中

system_stm32f4xx.c         :stm32f4的系統時鐘配置。在CMSIS\Device\ST\STM32F4xx\Source\Templates中

startup_stm32f40_41xxx.s:啟動檔案:設定SP的初始值;設定PC的初始值;設定中斷向量表的位址;配置時鐘;設定堆棧;調用main。

                                         這個 啟動檔案先調用system_stm32f4xx.c裡面的systeminit()在調用main()之前。

                                         在CMSIS\Device\ST\STM32F4xx\Source\Templates\arm中。

        對于STM32F4xx_StdPeriph_Driver,其重要源檔案為:

stm32f4xx_ppp.h:外設頭檔案。這裡的ppp隻是一個代碼,在實際上是具體的外設名字,如ADC,DMA等。在實際使用時根據所需的外設選擇性移植。

                            在STM32F4xx_StdPeriph_Driver\inc中

stm32f4xx_ppp.c:外設源檔案。這裡的ppp隻是一個代碼,在實際上是具體的外設名字,如ADC,DMA等。在實際使用時根據所需的外設選擇性移植。

                           在STM32F4xx_StdPeriph_Driver\src中

stm32f4xx_conf.h:外設驅動配置檔案。通過修改該檔案中所包含的外設頭檔案,使用者啟動或禁用外設驅動。

                            此外,在此檔案夾打開宏定義USE_FULL_ASSERT,通過預處理啟 用或禁用标準外設庫運作時的故障檢測。

                            在Project\STM32F4xx_StdPeriph_Templates中。

stm32f4xx_it.h    :頭檔案。包括所有中斷處理程式原型。在Project\STM32F4xx_StdPeriph_Templates中。

stm32f4xx_it.c    :中斷源程式模闆,中斷函數的名稱要與啟動檔案中中斷向量表的名稱一緻。在Project\STM32F4xx_StdPeriph_Templates中。

      此外,對于stm32f4的标準外設固件庫,在CMSIS檔案夾中還有相應的DSP庫:DSP_Lib和Lib。DSP_Lib主要為DSP函數庫的執行個體和源碼;Lib為編譯好的,且對于不同核心的STM32系列MCU所使用的lib檔案。

二、标準固件庫移植過程中的注意事項(這裡以僅以Keil-MDK為例)

1、在stm32f4xx.h檔案中選擇晶片以及宏定義USE_STDPERIPH_DRIVER。

stm32f4xx标準外設固件庫(By King先生)
#if !defined(STM32F40_41xxx) && !defined(STM32F427_437xx) && !defined(STM32F429_439xx) && !defined(STM32F401xx) && !defined(STM32F411xE) && \ !defined(STM32F446xx)
    #define STM32F40_41xxx       /*!< STM32F405RG, STM32F405VG, STM32F405ZG, STM32F415RG, STM32F415VG, STM32F415ZG,  
                                      STM32F407VG, STM32F407VE, STM32F407ZG, STM32F407ZE, STM32F407IG, STM32F407IE, 
                                      STM32F417VG, STM32F417VE, STM32F417ZG, STM32F417ZE, STM32F417IG and STM32F417IE Devices */

  /* #define STM32F427_437xx */  /*!< STM32F427VG, STM32F427VI, STM32F427ZG, STM32F427ZI, STM32F427IG, STM32F427II,  
                                      STM32F437VG, STM32F437VI, STM32F437ZG, STM32F437ZI, STM32F437IG, STM32F437II Devices */

  /* #define STM32F429_439xx */  /*!< STM32F429VG, STM32F429VI, STM32F429ZG, STM32F429ZI, STM32F429BG, STM32F429BI,  
                                      STM32F429NG, STM32F439NI, STM32F429IG, STM32F429II, STM32F439VG, STM32F439VI, 
                                      STM32F439ZG, STM32F439ZI, STM32F439BG, STM32F439BI, STM32F439NG, STM32F439NI,
                                      STM32F439IG and STM32F439II Devices */

  /* #define STM32F401xx */      /*!< STM32F401CB, STM32F401CC,  STM32F401RB, STM32F401RC, STM32F401VB, STM32F401VC  
                                      STM32F401CD, STM32F401RD, STM32F401VD, STM32F401CExx, STM32F401RE and STM32F401VE Devices */

  /* #define STM32F411xE */      /*!< STM32F411CD, STM32F411RD, STM32F411VD, STM32F411CE, STM32F411RE and STM32F411VE Devices */
  
  /* #define STM32F446xx */      /*!< STM32F446MC, STM32F446ME, STM32F446RC, STM32F446RE, STM32F446VC, STM32F446VE, STM32F446ZC 
                                      and STM32F446ZE Devices */
#endif

/* Old STM32F40XX definition, maintained for legacy purpose */
#ifdef STM32F40XX
  #define STM32F40_41xxx
#endif /* STM32F40XX */

/* Old STM32F427X definition, maintained for legacy purpose */
#ifdef STM32F427X
  #define STM32F427_437xx
#endif /* STM32F427X */

/*  Tip: To avoid modifying this file each time you need to switch between these
        devices, you can define the device in your toolchain compiler preprocessor.
  */

#if !defined(STM32F40_41xxx) && !defined(STM32F427_437xx) && !defined(STM32F429_439xx) && !defined(STM32F401xx) && !defined(STM32F411xE) && \ !defined(STM32F446xx)  
 #error "Please select first the target STM32F4xx device used in your application (in stm32f4xx.h file)"
#endif

#if !defined  (USE_STDPERIPH_DRIVER)
/**
 * @brief Comment the line below if you will not use the peripherals drivers.
   In this case, these drivers will not be included and the application code will 
   be based on direct access to peripherals registers 
   */
    #define USE_STDPERIPH_DRIVER 
#endif /* USE_STDPERIPH_DRIVER */      
stm32f4xx标準外設固件庫(By King先生)

2、根據實際的外部晶振修改stm32f4xx.h檔案中預設的系統外部晶振時鐘HSE_VALU。在本例中使用了16MHz的外部晶振,是以設為16000000。

stm32f4xx标準外設固件庫(By King先生)
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx)  || defined(STM32F429_439xx) || defined(STM32F401xx)  || defined(STM32F411xE)
 #if !defined  (HSE_VALUE) 
  #define HSE_VALUE    ((uint32_t)16000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#elif defined(STM32F446xx)
 #if !defined  (HSE_VALUE) 
  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F411xE */
/**
 * @brief In the following line adjust the External High Speed oscillator (HSE) Startup 
   Timeout value 
   */
#if !defined  (HSE_STARTUP_TIMEOUT) 
  #define HSE_STARTUP_TIMEOUT    ((uint16_t)0x05000)   /*!< Time out for HSE start up */
#endif /* HSE_STARTUP_TIMEOUT */   

#if !defined  (HSI_VALUE)   
  #define HSI_VALUE    ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */         
stm32f4xx标準外設固件庫(By King先生)

3、修改system_stm32f4xx.c檔案中PLL_M,PLL_Q,PLL_N和PLL_P。

    對于STM32F40_41xxx,系統時鐘為168MHZ,一般隻需修改PLL_M的值,PLL_N預設為336(若主時鐘為168MHz則N值預設336,若主時鐘為180MHz則N值預設360),PLL_P預設為2,PLL_Q預設為7。

stm32f4xx标準外設固件庫(By King先生)
/************************* PLL Parameters *************************************/
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx)
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M      16
#elif defined (STM32F446xx)
#define PLL_M      8
#elif defined (STM32F411xE)

#if defined(USE_HSE_BYPASS)
#define PLL_M      8    
#else  
#define PLL_M      16
#endif /* USE_HSE_BYPASS */

#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx */  

/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
#define PLL_Q      7

#if defined(STM32F446xx)
/* PLL division factor for I2S, SAI, SYSTEM and SPDIF: Clock =  PLL_VCO / PLLR */
#define PLL_R      7
#endif /* STM32F446xx */ 

#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx)
#define PLL_N      336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      2
#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx || STM32F446xx */

#if defined(STM32F401xx)
#define PLL_N      336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      4
#endif /* STM32F401xx */

#if defined(STM32F411xE)
#define PLL_N      400
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      4   
#endif /* STM32F411xx */

/******************************************************************************/      
stm32f4xx标準外設固件庫(By King先生)
stm32f4xx标準外設固件庫(By King先生)
#if defined(STM32F40_41xxx)
  uint32_t SystemCoreClock = 168000000;
#endif /* STM32F40_41xxx */

#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx)
  uint32_t SystemCoreClock = 180000000;
#endif /* STM32F427_437x || STM32F429_439xx || STM32F446xx */

#if defined(STM32F401xx)
  uint32_t SystemCoreClock = 84000000;
#endif /* STM32F401xx */

#if defined(STM32F411xE)
  uint32_t SystemCoreClock = 100000000;
#endif /* STM32F401xx */      
stm32f4xx标準外設固件庫(By King先生)

4、若需要使用FPU,則還需要在system_stm32f4xx.c中的SystemInit函數開頭添加相關語句,并在keil工程配置中選擇use FPU(Use Single Precision)

注意:__FPU_PRESENT == 1在stm32f4xx.h中已預設設定,__FPU_USED == 1在core_cm4.h中已預設設定。

/* FPU settings ------------------------------------------------------------
     * If no this settings,it maybe enter HardFault_Handler() interrupt when mdk complier chose "Use FPU"(or "Use Single Precision") to use FPU instruction. */
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif      

繼續閱讀