概述
Windows下使用Keil MDK5进行 STM32F401 的开发和编译, 配合ST-LINK工具进行烧录, 使用硬件抽象库HAL.
STM32F401硬件环境和连接
略, 与SPL环境相同
STM32F4 硬件抽象库 STM32F4xx_HAL_Driver
直接下载 STM32CubeF4 MCU 固件开发包
- 前往 https://github.com/STMicroelectronics/STM32CubeF4
- 点击
Code -> Download ZIP
- 文件比较大, 有接近300M, 解压备用
当前版本是v1.26.2, 还在继续更新.
ST硬件抽象库HAL结构说明
STM32CubeF4\Drivers 目录结构
├─BSP
├─CMSIS
│ ├─Core
│ │ ├─Include
│ │ └─Template
│ ├─Core_A
│ │ ├─Include
│ │ └─Source
│ ├─Device # 设备文件, 需要
│ │ └─ST
│ │ └─STM32F4xx
│ │ ├─Include
│ │ ├─Source
│ │ │ └─Templates
│ │ │ ├─arm
│ │ │ ├─gcc
│ │ │ └─iar
│ │ └─_htmresc
│ ├─docs
│ ├─DSP
│ ├─Include # 头文件, 需要
│ ├─Lib
│ │ ├─ARM
│ │ ├─GCC
│ │ └─IAR
│ ├─NN
│ ├─RTOS
│ └─RTOS2
└─STM32F4xx_HAL_Driver # 外设库, 需要
├─Inc
│ └─Legacy
├─Src
│ └─Legacy
└─_htmresc
按步骤手工创建项目
先组织好库文件和目录, 然后创建项目
创建目录并填充文件
以下以名称为test001
的项目为例
- 创建工作目录 test001
- 在工作目录下创建 Drivers, User 2个目录
- 从解压后的标准外设库中, 复制 Drivers\CMSIS 目录到 Drivers, CMSIS 这个目录下只需要保留 Device 和 Include 这两个目录, 其他目录不需要
- 复制 Drivers\STM32F4xx_HAL_Driver 整个目录到 Drivers
- User
- 复制 Projects\STM32F401-Discovery\Templates\Src 下面的 stm32f4xx_hal_msp.c stm32f4xx_it.c 到这个目录
- 复制 Projects\STM32F401-Discovery\Templates\Inc 下面的 stm32f4xx_hal_conf.h stm32f4xx_it.h 到这个目录
- 添加用户代码
完成后的目录结构是这样的
test001>
├─Drivers
│ ├─CMSIS
│ │ ├─Device
│ │ │ └─ST
│ │ │ └─STM32F4xx
│ │ │ ├─Include
│ │ │ ├─Source
│ │ │ │ └─Templates
│ │ │ └─_htmresc
│ │ └─Include
│ └─STM32F4xx_HAL_Driver
│ ├─Inc
│ ├─Src
│ └─_htmresc
└─User
在Keil uVision5中创建项目
-
Project -> New uVision Project
, 选择工作目录 test001, 使用名称test001, 保存 - 在弹出的对话框中, 选择芯片型号, STM32F401CCU6 选择芯片型号STM32F401CCUx, STM32F401CDU6 选择 STM32F401CDUx
- 在后续的 Manage Run-Time Enviroment 对话框中什么都不选, 因为会在项目里自己管理库文件
配置项目
在上面的步骤完成后, Keil MDK中就会显示一个项目的初始结构, 目录为 Project:test001, 以及一个 Target1
修改 Target 名称以及添加源文件
在菜单中点击 Project -> Manage -> Project Items
, 或者直接在图标栏中点击红黄绿品字形的图标, 在弹出的对话框中
- 修改 project targets 名称为 test001, 这个可以随便改
- 编辑并添加 Groups, 最终会有以下 Groups
- CMSIS
- StdPeriph_Driver
- Startup
- User
对每个group, 添加的文件为
- CMSIS
- 添加 Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c
- StdPeriph_Driver
- 添加 Drivers\STM32F4xx_HAL_Driver\src 下面的所有C文件, 除了以 _template.c 结尾的那几个
- Startup
- (F401CCU6)添加 Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm 下面的 startup_stm32f401xc.s 文件
- (F401CDU6)添加 Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm 下面的 startup_stm32f401xe.s 文件
- (F407VET6)添加的是 startup_stm32f407xx.s
- User
- 添加下面的C文件
修改项目包含路径
在菜单中点击Project -> Options for Target 'test001'
, 或者直接在图标栏中点击configure target option
图标, 在弹出的对话框中
- 定位到c/c++标签页
- Define: 这个是编译参数, 写入 USE_HAL_DRIVER 这里不需要指定 STM32F401xC/STM32F401xE , 从下面的编译命令中可以看到MDK已经自动指定了
- Include Paths: 这里是头文件的包含路径, 如果按上面的目录结构组织的项目, 可以直接复制下面的配置
.\Drivers\CMSIS\Include;.\Drivers\CMSIS\Device\ST\STM32F4xx\Include;.\Drivers\STM32F4xx_HAL_Driver\Inc;.\User
在下面的 compiler control string 中可以查看完整的命令行
--c99 --gnu -c --cpu Cortex-M4.fp -g -O0 --apcs=interwork --split_sections -I ./Drivers/CMSIS/Include -I ./Drivers/CMSIS/Device/ST/STM32F4xx/Include -I ./Drivers/STM32F4xx_HAL_Driver/Inc -I ./User
-I./RTE/_stm32f401hal001
-IC:/Keil_v5/ARM/PACK/Keil/STM32F4xx_DFP/2.15.0/Drivers/CMSIS/Device/ST/STM32F4xx/Include
-IC:/Keil_v5/ARM/CMSIS/Include
-D__UVISION_VERSION="525" -DSTM32F401xC -DUSE_HAL_DRIVER
-o .\Objects\*.o --omf_browse .\Objects\*.crf --depend .\Objects\*.d
STM32F401CCU6/STM32F401CDU6 示例代码
下面的例子, 使用开发板自带的led灯(PC13)实现间隔1秒的亮灭效果.
在User目录下创建 main.h 和 main.c, 注意通过Keil MDK创建的时候, 要注意文件位置, 默认是放到项目根目录的, 这里要改到User目录下.
main.c
#include "main.h"
#define LED_PIN GPIO_PIN_13 // 指定PIN
#define LED_GPIO_PORT GPIOC // 指定IO
#define LED_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() // 指定启用时钟的IO
void LED_Init(void);
static void SystemClock_Config(void);
static void Error_Handler(void);
int main(void)
{
HAL_Init();
/* Configure the System clock to have a frequency of 84 MHz */
//SystemClock_Config();
LED_Init();
while (1)
{
HAL_GPIO_TogglePin(LED_GPIO_PORT, LED_PIN);
HAL_Delay(1000);
}
}
void LED_Init(void) {
LED_GPIO_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct);
}
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
}
static void Error_Handler(void)
{
/* User may add here some code to deal with this error */
while(1)
{
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
while (1)
{
}
}
#endif
main.h
#ifndef __MAIN_H
#define __MAIN_H
#include "stm32f4xx_hal.h"
#endif /* __MAIN_H */
编译
按F7执行编译
烧录
在菜单中点击Project -> Options for Target 'test001'
, 或者直接在图标栏中点击configure target option
图标, 在弹出的对话框中
- 定位到 Debug 标签页
- Use 选择 ST-Link Debuger, 点击Settings
- 如果 Debug Adapter 里是空白没有显示ST-LINK/V2, 去windows设备管理器看下设备是否正常
- 切换到 Flash Download 标签, 勾选Reset and Run
- 点击 Download 按钮, 或者按F8, 进行烧录
其他
- 如果不能从丝印判断自己开发板芯片的型号, 可以用STM32 ST-LINK Utility连上查看
- 开发包中的例子. 在官方库的压缩包里, 包含着这个版本各个外设功能的代码例子, 可以直接参考.