KEIL5环境下利用HAL库开发STM32项目_工程搭建方法

KEIL5环境下利用HAL库开发STM32项目_工程搭建方法

【摘要】本文主要讲述在KEIL5环境下,如何搭建基于HAL库的STM32项目模板工程,全篇以STM32F103ZE芯片为例进行讲解,并对工程中主要的几个关键文件作用进行了阐述,适合入门级别同学参考借鉴。

步骤

  1. 准备工作

    • 创建工程根目录。在电脑某磁盘根目录下建立Template文件夹,后面所建立的工程都可以放在这个文件夹下面,当然名字可以任取,避免使用中文路径。
    • 新建 4 个子文件夹(CORE , HALLIB, OBJ 和 USER/Project )。这些文件夹名字实际上是可以任取的,这样取名只是为了方便识别。
    • 下载HAL 库开发包。建议去 ST 官网下载,因为我们以STM32F1 系列芯片讲解,所以我下载的是STM32CubeF1 包:STM32Cube_FW_F1_V1.8.6
    • 下载安装KEIL开发环境。我安装的是Keil uvision5
  2. 创建空壳工程

    • 打开 Keil,点击菜单 Project –>New Uvision Project ,然后将目录定位到刚才建立的文件夹 Template 之下的 USER/Project 子目录, 工程取名为 Template 之后点击保存, 工程文件就都保存到Project 文件夹下面。
    • 接下来会出现一个选择 Device 的界面,就是选择我们的芯片型号,这里我们定位到STMicroelectronics 下面的 STM32F103ZE(实际型号根据你自己的来)。需要注意的是,如果找不到你要的芯片型号,那就需要安装对应的器件 pack 。
    • 点击 OK, MDK 会弹出 Manage Run-Time Environment 对话框,这里可以添加自己需要的组件,从而方便构建开发环境,这里不做介绍,直接点击 Cancel 。
    • 此时,可以回到USER/Project文件夹下,多出了很多KEIL自动创建的文件及文件夹。
      • Template.uvprojx :工程文件,非常关键,不能删除。MDK5.23
        生成的工程文件是以.uvprojx 为后缀的。
      • DebugConfig 文件夹 :存储KEIL的调试配置文件
      • Listings 和 Objects 文件夹 :存储 MDK 编译过程的中间件
  3. 向工程目录添加HAL库等必需文件

    • A. 将 STM32CubeF1 包里的外设驱动源文件复制到我们的工程目录文件夹
      • 打开\STM32Cube_FW_F1_V1.8.6\Drivers\STM32F1xx_HAL_Driver 下面,将目录下面的 Src,Inc 文件夹复制到我们刚才建立的 HALLIB 文件夹。每个外设对应一个.c 文件和一个.h 头文件,可以根据项目需要选择其中部分文件,也可以全部复制过去。
    • B. 将 STM32CubeF1 包里的启动文件以及编译器头文件复制到我们的工程目录文件夹
      • 打开STM32Cube_FW_F1_V1.8.6\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\arm,找到需要的启动文件 startup_stm32f103xe.s ,并复制到CORE目录。 具体根据你使用的芯片型号选择。
      • 打开STM32Cube_FW_F1_V1.8.6\Drivers\CMSIS\Include,将里面的4个头文件: cmsis_armcc.hcmsis_armclang.hcmsis_compiler.hcore_cm3.h 复制到 CORE 目录
    • C. 将 STM32CubeF1 包里的芯片相关头文件复制到我们的工程目录文件夹
      • 打开STM32Cube_FW_F1_V1.8.6\Drivers\CMSIS\Device\ST\STM32F1xx\Include, 将里面的 3 个文件stm32f1xx.hsystem_stm32f1xx.hstm32f103xe.h 复制到 USER 目录
      • 打开STM32Cube_FW_F1_V1.8.0\Projects\STM3210E_EVAL\Templates\Inc 目录,将stm32f1xx_it.hstm32f1xx_hal_conf.h 和``main.h`这3个头文件复制到USER 目录
      • 打开STM32Cube_FW_F1_V1.8.0\Projects\STM3210E_EVAL\Templates\Src 目录,将 system_stm32f1xx.cstm32f1xx_it.c, stm32f1xx_hal_msp.cmain.c 复制到 USER 目录
  4. 将复制过来的文件加入到KEIL工程

    • 打开刚刚创建的KEIL空工程,右键点击 Target1,选择 Manage Project Items, 可以在 Project Targets 栏,将默认的Target 名字修改为 Template
    • 在 Groups 栏删掉默认的 Source Group1,并新建4个Groups: USER, USER\Drivers, CORE,和 HALLIB,然后点击 OK。
    • 选中对应的组名,点击Add Files…,依次为各组添加源文件
      • 选择HALLIB,然后点击右边的 Add Files,定位到我们刚才建立的目录\HALLIB\Src 下面,将里面所有的文件选中(Ctrl+A),然后点击 Add,然后 Close。需要说明的是,对于我们写代码,如果只用到了其中的某个外设,我们可以不用全部添加,只选择用到的外设库文件即可。
      • 选择CORE 分组,定位到我们刚才建立的目录CORE ,将里面所有的文件选中(Ctrl+A),然后点击 Add,然后 Close。注意,默认添加的时候文件类型为.c, 添加.h 头文件和 startup_stm32f103xe.s 启动文件的时候,你需要选择文件类型为 All files 才能看得到这些文件。
      • 选择USER 分组,定位到我们刚才建立的目录USER,将里面所有的.c 文件:main.cstm32f1xx_hal_msp.cstm32f1xx_it.csystem_stm32f1xx.c 四个文件添加进来。
      • USER\Drivers主要存放后期我们自己写的驱动文件(调试串口驱动、时钟配置文件、延时函数等),目前暂无文件添加。添加完所有文件到工程中之后,我们点击 OK 按钮。
  5. 设置头文件存放路径

    • 点击魔术棒,选中C/C++选项卡,点击Include Paths栏右侧三个点标志,将工程目录下所有存放了头文件的目录全部添加进去。例如:\CORE, \USER\ ,HALLIB\Inc等。
  6. **添加全局宏定义标识符 **

    • 点击魔术棒之后,进入 C/C++选项卡,然后在 Define 输入框连输入: USE_HAL_DRIVER,STM32F103xE
  7. 编译工程

    • 点击魔术棒之后,进入Output 选项卡。勾上“Create HEX File” 选项和 Browse Information 选项。 Create HEX File 选项选
      上是要求编译之后生成 HEX 文件。 而 Browse Information 选项选上是方便我们查看工程中的一些函数变量定义等。
    • 编辑main函数,之后编译工程,可以看到在工程的USER\Project\Objects里生成了对应的hex文件,将其下载到开发板即可。
  8. 关键文件介绍

    1. HAL库相关头文件

      1. sm32f1xx_hal.c:包含 HAL 通用 API(比如 HAL_Init,HAL_DeInit,HAL_Delay 等)。
      2. stm32f1xx_hal.h :HAL 的头文件,我们在编写任意文件前,首先要包含的就是该头文件
      3. stm32f1xx_hal_conf.h :HAL 的配置文件,主要用来选择使能何种外 设以及一些时钟相关参数设置。其本身应该 被客户代码所包含。
      4. stm32f1xx_hal_def.h :包含 HAL 的通用数据类型定义和宏定义
    2. 中断相关

      1. stm32f1xx_it.c :中断服务函数定义,而这些函数定义除了 Systick 中断服务函数SysTick_Handler 外基本都是空函数,没有任何控制逻辑。我们可以去掉这两个文件,然后把中断服务函数写在工程中的任何一个可见文件中。
      2. stm32f1xx_it.h :主要是一些中断服务函数的声明
    3. 芯片头文件

      1. stm32f1xx.h :它是所有 stm32f1 系列的顶层头文件。使用 STM32F1 任何型号的芯片,都需要包含这个头文件。 因为 stm32f1 系列芯片型号非常多, ST 为每种芯片型号定义了一个特有的片上外设访问层头文件,stm32f1xx.h 顶层头文件会根据工程芯片型号,来选择包含对应芯片的片上外设访问层头文件。 例如,我们在 C/C++选项卡里面输入的全局宏定义标识符中就包含了标识符 STM32F103xx,所以我们的工程就会自动包含头文件 stm32f103xx.h
      2. stm32f103xx.h :是 stm32f103 系列芯片通用的片上外设访问层头文件,里面主要是一些结构体和宏定义标识符,主要作用是寄存器定义声明以及封装内存操作。
    4. 系统初始化文件

      1. system_stm32f1xx.c :定义了系统初始化函数 SystemInit 以及系统时钟更新函数systemCoreClockUpdate。SystemInit 函数的作用是进行时钟系统的一些初始化操作以及中断向量表偏移地址设置,但它并没有设置具体的时钟值,这是与标准库的最大区别(在使用标准库的时候, SystemInit 函数会帮我们配置好系统时钟配置相关的各个寄存器)。在启动文件startup_stm32f103xx.s 中会设置系统复位后,直接调用 SystemInit 函数进行系统初始化。 SystemCoreClockUpdate 函数是在系统时钟配置进行修改后,调用这个函数来更新全局变量 SystemCoreClock 的值,变量 SystemCoreClock 是一个全局变量,开放这个变量可以方便我们在用户代码中直接使用这个变量来进行一些时钟运算。
      2. system_stm32f1xx.h :声明了系统初始化函数 SystemInit 以及系统时钟更新函数 SystemCoreClockUpdate
    5. MCU 级别硬件初始化文件

      1. stm32f1xx_hal_msp.c :MSP,全称为 MCU support package,函数名字中带有 MspInit 的函数,它们的作用是进行 MCU 级别硬件初始化设置,并且它们通常会被上一层的初始化函数所调用,这样做的目的是为了把MCU相关的硬件初始化剥夺出来,方便用户代码在不同型号的MCU上移植。 该文件定义了两个函数 HAL_MspInit 和 HAL_MspDeInit。这两个函数分别被文件 stm32f1xx_hal.c 中的 HAL_Init 和 HAL_DeInit 所调用。 HAL_MspInit 函数的主要作用是进行 MCU 相关的硬件初始化操作。例如我们要初始化某些硬件,我们可以硬件相关的初始化配置写在 HAL_MspInit 函数中。这样的话,在系统启动后调用了 HAL_Init之 后 , 会自动调用硬件初始化函数 。
    6. 启动文件

      1. startup_stm32f103xe.s :STM32 系列所有芯片工程都会有一个.s 启动文件。对于不同型号的 stm32 芯片启动文件也是不一样的。 作用主要是进行堆栈的初始化,中断向量表以及中断函数定义等。启动文件有一个很重要的作用就是系统复位后引导进入 main 函数

        ; Reset handler
        Reset_Handler PROC
        EXPORT Reset_Handler [WEAK]
        IMPORT __main
        IMPORT SystemInit
        LDR R0, =SystemInit
        BLX R0
        LDR R0, =__main
        BX R0
        ENDP
        
        • 开发板接通电源或按下复位键之后,就会跳到Reset_Handler中断处理函数处执行,这几行代码的作用是在系统启动之前,首先调用 SystemInit 函数进行系统初始化,然后引导进入 main 函数执行用户代码。
### Keil 5HAL 的使用方法 #### 1. 安装与环境搭建 为了在 Keil 5 中使用 STM32HAL ,首先需要完成开发环境的配置。这通常涉及以下几个方面: - **安装 Keil MDK**:确保已正确安装最新版本的 Keil MDK 软件[^3]。 - **下载 CubeMX 工具**:ST 提供的 STM32CubeMX 是用于生成初始化代码的重要工具。它能够自动生成基于 HAL 项目框架,并支持多种 IDE 和编译器集成,包括 Keil MDK[^1]。 #### 2. 使用 CubeMX 配置项目 通过 STM32CubeMX 进行项目配置是 HAL 使用的起点。以下是具体流程: - 打开 STM32CubeMX 并创建新工程,选择目标 MCU 型号(如 STM32F103ZET6)。 - 在 Pinout & Configuration 页面中设置 GPIO、时钟以及其他外设参数。 - 利用 Clock Configuration 功能调整系统时钟树结构,这是 HAL 正常运行的基础之一[^2]。 - 导出针对 Keil MDK 的工程项目文件夹,该过程会自动包含必要的 HAL 头文件和源码。 #### 3. 初始化 LED 控制示例 以下是一个简单的点亮 LED 的程序实现: ```c #include "stm32f1xx_hal.h" void SystemClock_Config(void); static void MX_GPIO_Init(void); int main(void) { HAL_Init(); // 初始化HAL SystemClock_Config(); // 配置系统时钟 MX_GPIO_Init(); // 初始化GPIO while (1) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // 切换PA5引脚状态 HAL_Delay(500); // 延时500ms } } // 系统时钟配置函数 void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) { Error_Handler(); } } // GPIO初始化函数 static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin : PA5 */ GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出模式 GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // 设置初始低电平 } ``` 上述代码展示了如何利用 HAL 函数 `HAL_GPIO_TogglePin` 来控制指定端口上的 LED 状态切换。 #### 4. 编译调试 将导出的项目导入至 Keil MDK 后即可开始编译测试。注意检查链接选项中的路径是否指向正确的 HAL 目录以及启动文件位置。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leon_George

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值