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
/******************************************************************************/