3. BSP包代碼的修改
在C:FreescaleFreescale_MQX_4_0mqxsourcepspcortex_m文件夾里的psp_cpudef.h文件中可以找到支持Kinetis K10/K20/K30/K40/K50/K60/K70等相關(guān)芯片的PSP宏定義,例如支持K10DN512的宏定義為:
#define PSP_CPU_MK10DN512Z (PSP_CPU_NUM(PSP_CPU_ARCH_ARM_CORTEX_M4, PSP_CPU_GROUP_KINETIS_K1X, 2))
同時在該文件中還可以找到所有Freescale指定PSP處理器支持包所支持內(nèi)核的宏定義,如ColdFire,PPC,Cortex-A5,Cortex-A8等。
在本文中,我們創(chuàng)建的是針對K10DN512的BSP開發(fā)包,所以需要用上述的宏定義,將user_config.h文件中的MQX_CPU定義
#define MQX_CPU PSP_CPU_MK60DN512Z
修改為:
#define MQX_CPU PSP_CPU_MK10DN512Z
此時點擊編譯按鈕會出現(xiàn)錯誤提示,如下圖5所示。
圖5. 頭文件錯誤
出現(xiàn)這個錯誤是由于在C:FreescaleFreescale_MQX_4_0mqxsourcepspcortex_mkinetis.h中找不到頭文件MK10DZ10.h,需要從以下的IAR安裝目錄中尋找:
C:Program FilesIAR SystemsEmbedded Workbench 6.5armincFreescale
然后將該文件拷貝到C:FreescaleFreescale_MQX_4_0mqxsourcepspcortex_mcpu中進(jìn)行編譯。
編譯仍有錯誤出現(xiàn),如下圖6所示。
這個錯誤主要是由于移植使用的是K60的BSP包,因此里面含有以太網(wǎng)ENET部分和USB部分的代碼,而在K10芯片中是沒有這些功能模塊的,在IAR IDE Workspace工作臺環(huán)境下,需要將外圍I/O驅(qū)動(Peripheral IO Drivers)中的ENET和USB等文件夾刪除,同時將K10DN512 BSP Files文件夾中的 init_usb.c和init_enet.c文件刪除。另外在K10DN512 BSP Files中,由于在MQX安裝目錄C:FreescaleFreescale_MQX_4_0mqxsourcespK10DN512 文件下的init_gpio.c和bsp.h中初始化了ent和usb部分的,需要打開這兩個文件,找到_bsp_ent_io_init和bsp_usb_io_init的代碼部分,然后直接進(jìn)行刪除。此時再進(jìn)行編譯,則應(yīng)該沒有錯誤出現(xiàn)了。
圖6以太網(wǎng)及USB相關(guān)的文件編譯錯誤
下一步需要修改的,是系統(tǒng)的時鐘設(shè)置。針對K60DN512, MQX默認(rèn)的外部時鐘是50MHz。 對于K20系列MQX默認(rèn)的外部時鐘是8MHz,如果目標(biāo)板的時鐘和默認(rèn)的外部時鐘不一樣,則需要重新配置。例如,如果這里選擇25MHz的無源晶體作為外接時鐘,那么就需要修改bsp_cm.h中的時鐘設(shè)置,將CPU_XTAL_CLK_HZ的時鐘修改為25MHz。當(dāng)然根據(jù)實際項目設(shè)計有時也需要配置不同的總線時鐘頻率,內(nèi)核時鐘頻率等,可以參照如下的代碼對bsp_cm.h中的宏定義進(jìn)行相應(yīng)的修改:
#define CPU_BUS_CLK_HZ 48000000U /*初始化總線時鐘頻率為48MHz*/
修改為
#define CPU_BUS_CLK_HZ 50000000U /*初始化總線時鐘頻率為50MHz*/
#define CPU_CORE_CLK_HZ 96000000U /* 初始化內(nèi)核、系統(tǒng)時鐘頻率為96MHz */
修改為
#define CPU_CORE_CLK_HZ 100000000U /* 初始化內(nèi)核、系統(tǒng)時鐘頻率為100MHz */
#define CPU_CLOCK_CONFIG_NUMBER 0x03U /* 定義時鐘配置的個數(shù),時鐘配置有0,1和2,共3種可以選擇*/
#define CPU_BUS_CLK_HZ_CLOCK_CONFIG0 48000000U /*在時鐘配置0中的總線時鐘頻率為48MHz */
修改為
#define CPU_BUS_CLK_HZ_CLOCK_CONFIG0 50000000U /*在時鐘配置0中的總線時鐘頻率為50MHz */
#define CPU_CORE_CLK_HZ_CLOCK_CONFIG0 96000000U /* 在時鐘配置0中的內(nèi)核、系統(tǒng)時鐘頻率為96MHz*/
修改為
#define CPU_CORE_CLK_HZ_CLOCK_CONFIG0 100000000U /* 在時鐘配置0中的內(nèi)核、系統(tǒng)時鐘頻率為100MHz*/
#define CPU_XTAL_CLK_HZ 50000000U /* 外部晶體或者振蕩器的時鐘頻率為50MHz*/
修改為
#define CPU_XTAL_CLK_HZ 25000000U /* 外部晶體或者振蕩器的時鐘頻率為25MHz*/
相應(yīng)的,對于使用的時鐘配置0或者1或者2也需要修改,如果目標(biāo)配置使用的是時鐘配置0,可以參照如下代碼修改。如果不使用時鐘配置1或者2,則不需要做修改。
/* 在時鐘配置0中的CPU時鐘頻率 */
#define CPU_CLOCK_CONFIG_0 0x00U /* 時鐘配置0的定義 */
修改內(nèi)核時鐘頻率,默認(rèn)的是96MHz,改為100MHz。
#define CPU_CORE_CLK_HZ_CONFIG_0 100000000UL /* 內(nèi)核時鐘頻率為100MHz*/
修改總線時鐘頻率,默認(rèn)是48MHz,修改為50MHz。
#define CPU_BUS_CLK_HZ_CONFIG_0 50000000UL /* 總線時鐘頻率為50MHz*/
修改Flash時鐘頻率,默認(rèn)是24MHz,修改為25MHz。
#define CPU_FLASH_CLK_HZ_CONFIG_0 25000000UL /* FLASH時鐘頻率為25MHz*/
#define CPU_PLL_FLL_CLK_HZ_CONFIG_0 100000000UL /* PLL/FLL時鐘頻率為100MHz*/
#define CPU_OSCER_CLK_HZ_CONFIG_0 50000000UL
/*在時鐘配置0中的系統(tǒng)OSC 外部參考時鐘 */
手工書寫代碼相對繁瑣,更方便的方法是使用Freescale的Processor Expert 工具,根據(jù)硬件的需要來設(shè)置時鐘,生成的如下的代碼。通過PE工具來對CPU和各種外設(shè)進(jìn)行設(shè)置,只需了解它的原理和用法,而不用把精力花在了解寄存器的具體細(xì)節(jié)上。打開PE后,參照圖7的配置進(jìn)行設(shè)置,點擊Project-》Generator Processor Expert Code即可生成代碼。記住重新修改配置后需要點擊Project-》Clean,清掉上次生成的代碼,然后再執(zhí)行生成代碼的操作。
void __pe_initialize_hardware(void)
{
_bsp_watchdog_disable();
/* 關(guān)閉 WDOG 模塊 */
WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520);
WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928);
WDOG_STCTRLH = WDOG_STCTRLH_STNDBYEN_MASK | WDOG_STCTRLH_WAITEN_MASK | WDOG_STCTRLH_STOPEN_MASK | WDOG_STCTRLH_ALLOWUPDATE_MASK | WDOG_STCTRLH_CLKSRC_MASK;
/* 系統(tǒng)時鐘初始化 */
/* SIM_SCGC5: PORTA=1 */
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV2(0x01) | SIM_CLKDIV1_OUTDIV3(0x03) |
SIM_CLKDIV1_OUTDIV4(0x03); /* 更新系統(tǒng)預(yù)分頻器 */
SIM_SOPT1 &= (uint32_t)~(uint32_t)(SIM_SOPT1_OSC32KSEL_MASK);
PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));
PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));
/*切換到FBE 模式*/
OSC_CR = OSC_CR_ERCLKEN_MASK;
SIM_SOPT2 &= (uint32_t)~(uint32_t)(SIM_SOPT2_MCGCLKSEL_MASK);
MCG_C2 = (MCG_C2_RANGE(0x02) | MCG_C2_EREFS_MASK);
MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x05) | MCG_C1_IRCLKEN_MASK);
MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
MCG_C5 = MCG_C5_PRDIV(0x07);
MCG_C6 = MCG_C6_VDIV(0x08);
while((MCG_S & MCG_S_OSCINIT_MASK) == 0x00U) { /*判斷晶振是否運行?*/
}
評論
查看更多