1. 程式人生 > >STM32不同外部晶振時工程的配置問題

STM32不同外部晶振時工程的配置問題

遇到的問題:

同樣的串列埠配置程式碼在一種407開發板上能正常輸出,但是換到另一種407開發板上後就出現亂碼,檢查串列埠輸出波形後發現,電平轉換晶片沒有問題,但是波特率卻有問題。

問題原因:

   經過故障排查發現出現上述問題的原因是兩種STM32F407使用的外部晶振的頻率不一樣,前者使用的是25MHZ的晶振,而後者卻是使用的8MHZ的晶振,如果程式碼未經更改而直接用在後者身上,就會出現上述串列埠亂碼的情況,而且後者的每bite位的週期就是前者的三倍左右。

解決辦法:

    方法一:

因為 STM32F407的庫檔案中預設晶振值為25MHz,若外接晶振8MHz。所以:

1.首先需要修改"Option for target 'xxx'"中的Target -> Xtal(Mhz)處的值(改為8MHz)。此處修改影響Debug時觀察到的時鐘數值。

2.stm32f4xx.h預設25M外部晶振(HSE):

#if !defined  (HSE_VALUE)

#defineHSE_VALUE    ((uint32_t)25000000) /*!<Value of the External oscillator in Hz25000000 */

#endif /* HSE_VALUE*/

如果改為8M或其他值,需要修改此巨集定義。 

為了儘量保持官方韌體庫的完整性,可在stm32f4xx_conf.h中新增程式碼

#if defined (HSE_VALUE)

/* Redefine the HSE value;it's equal to 8 MHz on the STM32F4-DISCOVERY Kit*/

#undef HSE_VALUE

#define HSE_VALUE   ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */

#endif /* HSE_VALUE */

注:但PLL_M定義在system_stm32f4xx.c中的,此方法對其不可用,親測。

3. 開啟檔案 "system_stm32f4xx.c" ,搜尋”PLL_M",修改預設PLL_M的引數:

/*************************PLL Parameters *************************************/

/* PLL_VCO = (HSE_VALUEor HSI_VALUE / PLL_M) * PLL_N */

#define PLL_M      25

#define PLL_N      336

/* SYSCLK = PLL_VCO /PLL_P */

#define PLL_P      2

/* USB OTG FS, SDIO andRNG Clock =  PLL_VCO / PLLQ */

#define PLL_Q      7

/******************************************************************************/

同樣改為8M的話,PLL_M也應該改為8.(假設最後的時鐘值不變)。 
PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N = 
25/25*336 = 336M (8/8*336=336M) 
SYSCLK = PLL_VCO / PLL_P = 
336 / 2 = 168M 預設是168M時鐘。

方法二:(目前找到的最好解決方法,若有更好的方法,歡迎前來交流

1.首先需要修改"Option for target 'xxx'"中的Target -> Xtal(Mhz)處的值(改為12MHz)。此處修改影響Debug時觀察到的時鐘數值。


2. 在"Option for target 'xxx'"中的C/C++-> Define處新增

HSE_VALUE=8000000, 巨集


在這裡修改HSE的值,然後依然要修改"system_stm32f4xx.c"檔案中的PLL_M,否則,在115200以上波特率下,首位元組字元是亂碼。親測。(修改stm32f4xx.h裡面的值不是不可以,但是感覺修改裡面的東西不是很好,畢竟都是庫來的,以後呼叫的時候也不用想著這個問題。但是,現在尚未找到更好的解決辦法

3. 開啟檔案 "system_stm32f4xx.c" ,搜尋”PLL_M",修改預設PLL_M的引數:

/*************************PLL Parameters *************************************/

/* PLL_VCO = (HSE_VALUEor HSI_VALUE / PLL_M) * PLL_N */

#define PLL_M      25

#define PLL_N      336

/* SYSCLK = PLL_VCO /PLL_P */

#define PLL_P      2

/* USB OTG FS, SDIO andRNG Clock =  PLL_VCO / PLLQ */

#define PLL_Q      7

/******************************************************************************/