编辑: hyszqmzc | 2016-12-28 |
// At this stage the HSI is used as system clock HAL_Init();
/* Configure the System clock source, PLL Multiplier and Divider factors, AHB/APBx prescalers and Flash settings */ SetSysClock();
// Update the SystemCoreClock variable. SystemCoreClockUpdate();
// reset serial next time it is called, now that system clock is set stdio_uart_inited = 0;
} SetSysClock 和SystemCoreClockUpdate 是在 mbed_sdk_init()中被调用的,调用时间在 RAM 初始化之后,main 之前. 5) 在 Retarget.cpp 中也可以看到: // mbed_main is a function that is called before main() // mbed_sdk_init() is also a function that is called before main(), but unlike // mbed_main(), it is not meant for user code, but for the SDK itself to perform // initializations before main() is called. extern C WEAK void mbed_main(void);
extern C WEAK void mbed_main(void) { } extern C WEAK void mbed_sdk_init(void);
extern C WEAK void mbed_sdk_init(void) { } #if defined(TOOLCHAIN_ARM) extern C int $Super$$main(void);
extern C int $Sub$$main(void) { mbed_sdk_init();
mbed_main();
return $Super$$main();
} #elif defined(TOOLCHAIN_GCC) extern C int __real_main(void);
extern C int __wrap_main(void) { mbed_sdk_init();
mbed_main();
return __real_main();
} #elif defined(TOOLCHAIN_IAR) // IAR doesn'
t have the $Super/$Sub mechanism of armcc, nor something equivalent // to ld'
s --wrap. It does have a --redirect, but that doesn'
t help, since redirecting // '
main'
to another symbol looses the original '
main'
symbol. However, its startup // code will call a function to setup argc and argv (__iar_argc_argv) if it is defined. // Since mbed doesn'
t use argc/argv, we use this function to call our mbed_main. extern C void __iar_argc_argv() { mbed_sdk_init();
mbed_main();
} #endif 6) 在 serial_api.c 中可以找到了串口的初始化函数:void serial_init(serial_t *obj, PinName tx, PinName rx),它在 serialBase.app 中被调用. 7) 在 startup_stm32f030x8.S 中,来看一下复位之后的运行代码: ;
Reset handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main IMPORT SystemInit LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP 8) 重要的事情来了,我们要研究一下程序运行的顺序,在单步运行和断点的帮助下,我们可以看到程序的运行情况: A. 复位后,从 LDR R0, =SystemInit 先调用 void SystemInit(void)进行初始化配置,此时时钟源仍然为 8MHz. B. 往下跑,先进入了 serial_init()进行串口的初始化,波特率为默认为 9600,基于 8MHz 的配置. C. 接下来,进入 mbed_sdk_init()开始初始化,调用 SetSysClock()和SystemCoreClockUpdate()将系统时钟 配置为 48MHz. D. 系统时钟的改变之后没有对串口进行重新初始化,直接进入了 main()函数运行代码,造成 UART 的波特率 不对的情况.
3 3
3 3. . . .问题解决 问题解决 问题解决 问题解决 从两个工作主频分别使用两种方法来解决这个问题. 1) 设置工作主频为 8MHz.在 mbed_overrides.c 文件,此处已经将 SystemCoreClock 设置成 8000000,如下: // This function is called after RAM initialization and before main. void mbed_sdk_init() { /* Configure the Cube driver */ SystemCoreClock = 8000000;
// At this stage the HSI is used as system clock HAL_Init();
/* Configure the System clock source, PLL Multiplier and Divider factors, AHB/APBx prescalers and Flash settings */ SetSysClock();
// Update the SystemCoreClock variable. SystemCoreClockUpdate();
// reset serial next time it is called, now that system clock is set stdio_uart_inited = 0;