版本:Keil V5.26.2.0 STM32CubeMX 5.0.0
具我目前了解有2种方式,一种是使用STM32CubeMX,另一种是使用keil mdk创建。使用STM32CubeMX生成的工程最后也需要使用keil or IAR等其它IDE打开使用,当然使用keil mdk 创建STM32L4工程也需要调用STM32CubeMX来生成一些初始化代码。在给F4开发时可以选择“Classic”而不是“STM32CubeMX”创建代码,使用“Classic”则自己创建初始化代码,可使用CMSIS-Driver,没有STM32CubeMX生成的软件框架。keil5使用STM32CubeMX生成代码的软件架构如图所示:
1.创建uVi工程 Project-->New uVision Project...,创建工程名和设置工程路径
2.选择目标设备,以选择STM32L431CBT6设备为例。
3.选择完后会显示 Run-Time Environment Manager 窗口,选择 Device 中的 STM32Cube HAL中的驱动文件,以选择USART为例,勾选后Output窗口会提示缺少相应的依赖,点击Resolve后,系统自己勾选上相应的依赖。
4.选择完毕后,点击OK按钮会自动打开一个对话框来启动STM32CubeMX。点击启动按钮
5.配置相应的引脚和时钟等其它设置
配置时钟,可以选择HSE或者LSE,时钟树很形象,一看便知
6.生成代码
7.等待代码生成结束。Keil会自动显示更新工程窗口,选择OK确认更新
8.在生成的代码结构中,STM32CubeMX在项目中创建了一个名为“STM32CubeMX:Common Sources”的源组。这个组包含三个文件,其中包含允许插入用户定义的C代码的用户专用部分。
main.c 文件包含了HAL_Init()函数代码,配置和初始化了System Clock和Usart等使用到的外设。
stm32l4xx_it.c包含生成的中断处理程序。STM32CubeMX NVIC设置中的“Generate IRQ Handler”列允许控制是否应该生成中断处理函数调用。可以选择不生成中断函数。
在对比一些我们之前的Run-Time Environment Manager 窗口,系统为工程自动勾选上了一些相关依赖
9.接下来编译代码,不带RTOS的裸机工程就创建好了。
MDK中有丰富的中间件,包括RTX、File System、GUI、RL_TCPNet、RL_USB等其它中间件。其中自带的RTX实时操作系统丰富好用。RTX是ARM大佬针对自己Cortex系列内核开发出来的一套RTOS,对其做过特殊优化。中断切换速度是优于其它RTOS的。下面以使用RTX为例如何添加RTOS库到工程中。
在基于上面的裸机工程中,我做一些代码改变。
1.关闭SVC、Pend、SysTick中断。可以在Run-Time Environment Manager 窗口中,打开STM32CubeMX。
选择NVIC配置,关闭中断代码生成,然后再重新生成代码。注意:STM32CubeMX会弹出打开工程,选择不打开。
更新工程代码后,可以查看stm32l4xx_it.c文件是否还有SVC、Pend、SysTick中断函数。
在Run-Time Environment Manager 窗口中选择RTOS2
然后打开main.c文件,在USER CODE 包含里面,包含并添加cmsis_os2.h头。
/* USER CODE BEGIN Includes */
#include "RTE_Components.h"
#ifdef RTE_Compiler_EventRecorder
#include "EventRecorder.h"
#endif
#include "cmsis_os2.h"
extern void app_main (void* arg);
/* USER CODE END Includes */
更改HAL_GetTick()函数
/* USER CODE BEGIN 0 */
uint32_t HAL_GetTick (void) {
static uint32_t ticks = 0U;
uint32_t i;
if (osKernelGetState () == osKernelRunning) {
return ((uint32_t)osKernelGetTickCount ());
}
/* If Kernel is not running wait approximately 1 ms then increment and return auxiliary tick counter value */
for (i = (SystemCoreClock >> 14U); i > 0U; i--) { __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); }
return ++ticks; }
/* USER CODE END 0 */
添加一个任务函数
/* USER CODE BEGIN 2 */
#ifdef RTE_Compiler_EventRecorder
EventRecorderInitialize(EventRecordAll, 1);
#endif
SystemCoreClockUpdate();
osKernelInitialize(); // Initialize CMSIS-RTOS
osThreadNew(app_main, NULL, NULL); // Create application main thread
osKernelStart();
/* USER CODE END 2 */
创建一个app_main.c源文件,添加任务代码
#include "cmsis_os2.h" // ::CMSIS:RTOS2
void app_main (void const* arg) {
while(1) {
osDelay(1000);
}
}
编译工程,带RTOS的工程就创建好啦!当然也可以使用STM32CubeMX中的FreeRTOS。其实MDK也有FreeRTOS软件包,被封装成了CMSIS_RTOS2,目的是统一RTOS接口,方便用户使用MDK平台更容易迁移代码。另外不建议使用CMSIS-RTOS,此版本Keil不再维护支持。