最近受产能影响,S**32单片机又涨价了,再好用也用不起。不过国产的雅*力单片机,规格之高,远超s**32,他们没有M0 M3内核,直接就上M4内核。对应如下:421---stM0 415--M3 401--M4 虽然421对应M0内核,但主频达到了120MHz。他的时钟可以通过一个图形工具 进行配置成48MHz 72Mhz ,关键是价格很便宜。
1.keiL添加:Keil.AT32F4xx_DFP.1.3.7.pack 安装包
首先,碰到第一个问题是ststick时钟和定时器定时不准确,原来我们使用的内部晶振,所以要配置成内部晶振,在雅*力官网上有类似s**32 clubmx图形配置工具来配置他的时钟树。可以配置成和s**32M3内核72M的时钟频率。
点击生成代码,生成PLL的配置文件,把他加到keill工程 并引用他的初始化
2. 打开system_at32f4xx.c文件,
找到并开启带_HSI结尾的宏定义就可以了。(_HSE结尾的就是外部晶振宏定义)在时钟树上配的多少M的频率,在下面的宏定义就要打开相应的频率。
#if defined (AT32F403xx) || defined (AT32F413xx) || \
defined (AT32F415xx) || defined (AT32F403Axx)|| \
defined (AT32F407xx) || defined (AT32F421xx)
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz 24000000 */
/* #define SYSCLK_FREQ_36MHz 36000000 */
/* #define SYSCLK_FREQ_48MHz 48000000 */
/* #define SYSCLK_FREQ_56MHz 56000000 */
/* #define SYSCLK_FREQ_72MHz 72000000 */
/* #define SYSCLK_FREQ_96MHz 96000000 */
/* #define SYSCLK_FREQ_108MHz 108000000 */
/* #define SYSCLK_FREQ_120MHz 120000000 */
/* #define SYSCLK_FREQ_24MHz_HSI 24000000 */
/* #define SYSCLK_FREQ_36MHz_HSI 36000000 */
/* #define SYSCLK_FREQ_48MHz_HSI 48000000 */
/* #define SYSCLK_FREQ_56MHz_HSI 56000000 */
/* #define SYSCLK_FREQ_72MHz_HSI 72000000 */
/* #define SYSCLK_FREQ_96MHz_HSI 96000000 */
/* #define SYSCLK_FREQ_108MHz_HSI 108000000 */
/* #define SYSCLK_FREQ_120MHz_HSI 120000000 */
#endif
3.时钟搞定了,就可以参考官方的Demo程序,进行BSP移植,很容易就上手写逻辑。
然后进行国产操作系统RT thread的移植
我们移植的是 Nano 版本 即内核版本 还有功能强大的标准版 号称小Linux操作系统
我们可以从官网下载安装文件,RT-Thread Nano 离线安装包下载,下载结束后双击文件进行安装
打开已经准备好的可以运行的裸机程序,将 RT-Thread 添加到工程。如下图,点击 Manage Run-Time Environment
在 Manage Rum-Time Environment 里 "Software Component" 栏找到 RTOS,Variant 栏选择 RT-Thread,然后勾选 kernel,点击 "OK" 就添加 RT-Thread 内核到工程了。
现在可以在 Project 看到 RT-Thread RTOS 已经添加进来了,展开 RTOS,可以看到添加到工程的文件:
中断与异常处理
RT-Thread 会接管异常处理函数 HardFault_Handler() 和悬挂处理函数 PendSV_Handler(),这两个函数已由 RT-Thread 实现,所以需要删除工程里中断服务例程文件中的这两个函数,避免在编译时产生重复定义。如果此时对工程进行编译,没有出现函数重复定义的错误,则不用做修改。
系统时钟配置
需要在 board.c 中实现 系统时钟配置(为 MCU、外设提供工作时钟)与 os tick 的配置 (为操作系统提供心跳 / 节拍)。
如下代码所示,用户需要在 board.c 文件中系统初始化和 OS Tick 的配置,用户需在 timer 定时器中断服务函数调用 rt_os_tick_callback function,cortex-m 架构使用 SysTick_Handler()
/* board.c *//* timer 定时器中断服务函数调用 rt_os_tick_callback function,cortex-m 架构使用 SysTick_Handler() */voidrt_os_tick_callback(void){rt_interrupt_enter();/* 进入中断时必须调用 */rt_tick_increase();/* RT-Thread 系统时钟计数 */rt_interrupt_leave();/* 退出中断时必须调用 */}/* cortex-m 架构使用 SysTick_Handler() */SysTick_Handler(){rt_os_tick_callback();}voidrt_hw_board_init(void){/*
* TODO 1: OS Tick Configuration
* Enable the hardware timer and call the rt_os_tick_callback function
* periodically with the frequency RT_TICK_PER_SECOND.
*//* 1、系统、时钟初始化 */HAL_Init();// 初始化 HAL 库SystemClock_Config();// 配置系统时钟SystemCoreClockUpdate();// 对系统时钟进行更新/* 2、OS Tick 频率配置,RT_TICK_PER_SECOND = 1000 表示 1ms 触发一次中断 */_SysTick_Config(SystemCoreClock/RT_TICK_PER_SECOND);/* Call components board initial (use INIT_BOARD_EXPORT()) */#ifdefRT_USING_COMPONENTS_INITrt_components_board_init();#endif#ifdefined(RT_USING_USER_MAIN)&&defined(RT_USING_HEAP)rt_system_heap_init(rt_heap_begin_get(),rt_heap_end_get());#endif}