在Keil MDK 5里面直接创建使用HAL库的STM32工程的方法(不使用STM32CubeMX)

本文使用的单片机为STM32F030C8。

【示例程序代码】

注:“= {0}”语句相当于原来标准库中的GPIO_StructInit函数。

全局变量和静态局部变量默认已经清零,所以不需要写“= {0}”。而普通局部变量默认值为随机值,所以必须要写“= {0}”。

#include <ctype.h>
#include <stm32f0xx.h>
#include <string.h>

UART_HandleTypeDef huart1;
static uint8_t uart_data;

#ifdef USE_FULL_ASSERT
void assert_failed(char *file, uint32_t line)
{
  printf("%s: file %s on line %d\r\n", __FUNCTION__, file, line);
  while (1);
}
#endif

int main(void)
{
  int i = 0;
  GPIO_InitTypeDef gpio = {0};
  
  HAL_Init();
  
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_USART1_CLK_ENABLE();
  
  gpio.Alternate = GPIO_AF1_USART1;
  gpio.Mode = GPIO_MODE_AF_PP;
  gpio.Pin = GPIO_PIN_9 | GPIO_PIN_10;
  gpio.Pull = GPIO_NOPULL;
  gpio.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOA, &gpio);
  
  huart1.Instance = USART1;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT;
  huart1.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
  huart1.Init.BaudRate = 115200;
  huart1.Init.Mode = UART_MODE_TX_RX;
  HAL_UART_Init(&huart1);
  printf("STM32F030C8 USART1\n");
  
  HAL_UART_Receive_IT(&huart1, &uart_data, 1);
  HAL_NVIC_EnableIRQ(USART1_IRQn);
  while (1)
  {
    printf("i=%d\n", i);
    i++;
    HAL_Delay(1000);
  }
}

/* UART接收函数 */
void USART1_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart1);
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (isprint(uart_data))
    printf("Received: %c\n", uart_data);
  else
    printf("Received: %#x\n", uart_data);
  
  // 继续接收下一个字符
  HAL_UART_Receive_IT(&huart1, &uart_data, 1);
}

/* HAL库里面的延时函数需要用到这个 */
void SysTick_Handler(void)
{
  HAL_IncTick();
}

/* 以下代码增加printf串口输出功能 (不用在项目属性中勾选Use MicroLIB) */
#pragma import(__use_no_semihosting)

struct __FILE
{
  int handle;
} __stdout, __stderr;

int fputc(int ch, FILE *fp)
{
  if (fp == stdout || fp == stderr)
  {
    if (ch == '\n')
      HAL_UART_Transmit(&huart1, (uint8_t *)"\r\n", 2, HAL_MAX_DELAY);
    else
      HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
  }
  return ch;
}

void _sys_exit(int returncode)
{
  while (1);
}

【方法一】直接在Keil工程里面勾选HAL库,不用自己手动添加库文件

(1)在Keil里面新建空白工程,选择要使用的单片机

(2)然后会弹出这个窗口。在这里面选择Device下面的Startup,然后右边的下拉菜单框中必须选择Standalone

这个窗口平时可以通过点击工具栏的绿色菱形打开。

(3)根据下方的Validation Output提示,勾选上所有的依赖项。还要选择好要用到的HAL库外设,如USART。

(4)工程建好后,就可以新建空白的main.c源文件,编写代码。

(5)代码编写好了之后,还必须要配置项目属性才能编译成功。在C/C++选项卡里面要加上USE_HAL_DRIVER。

图中的USE_FULL_ASSERT可以加,也可以不加。这个决定是否开启HAL警告输出。

(6)在Debug里面勾选Reset and Run,这样程序下载后就能自动开始运行,不用去按复位键。

 

【方法二】不在Manage Run-Time Environment窗口里面勾选HAL库,而是自己去网上下载HAL库的压缩包,然后手动把所有的库文件添加到工程里面

(1)建立工程时,什么都不要勾选,保证建立的是完全空白的工程。

(2)去ST的官网上下载HAL库的压缩包。

如STM32F0系列的HAL库压缩包的名称叫en.stm32cubef0.zip,下载地址是https://www.st.com/en/embedded-software/stm32cubef0.html

(3)在工程文件夹中建立STM32F0xx_HAL_Driver文件夹。

打开压缩包,将en.stm32cubef0.zip\STM32Cube_FW_F0_V1.11.0\Drivers\STM32F0xx_HAL_Driver文件夹里面的Inc和Src文件夹解压到刚才建立的STM32F0xx_HAL_Driver文件夹中。

解压完后,需要将Inc文件夹中以_template结尾的头文件改名,去掉_template这个后缀

改名后:

另外,还要把Src文件夹里面带_template的c文件都删掉

(4)解压以下文件到STM32F0xx_HAL_Driver文件夹中:

en.stm32cubef0.zip\STM32Cube_FW_F0_V1.11.0\Drivers\CMSIS\Device\ST\STM32F0xx\Source\Templates\system_stm32f0xx.c

en.stm32cubef0.zip\STM32Cube_FW_F0_V1.11.0\Drivers\CMSIS\Device\ST\STM32F0xx\Source\Templates\arm\startup_stm32f030x8.s

en.stm32cubef0.zip\STM32Cube_FW_F0_V1.11.0\Drivers\CMSIS\Core\Include\下的cmsis_armcc.h、cmsis_compiler.h、cmsis_version.h和core_cm0.h

这个步骤根据代码的编译情况确定。编译的时候缺什么文件,就解压什么文件。

(5)将所有的*.c文件和*.s文件都添加到工程里面去(Src\Legacy里面的不用添加)。把main.c也编写好,这次还需包含一个<stdio.h>的头文件。

(6)在项目属性中添加头文件的包含路径,并定义USE_HAL_DRIVER宏

创建STM32F103 HAL库工程的步骤如下: 1. 打开Keil软件,点击File -> New Project,弹出新建工程对话框。 2. 在对话框中选择“STMicroelectronics” -> “STM32F103C6” -> “MDK-ARM”,然后输入工程名和保存路径,点击“Save”按钮。 3. 选择“Device”选项卡,选择正确的芯片型号和Flash大小等参数,然后点击“OK”按钮。 4. 在工程窗口中,右键点击“Src”文件夹,选择“New Items”,然后选择“C File”或者“C++ File”,输入文件名,点击“Add”按钮。这里以main.c为例。 5. 在新建的main.c文件中,编写代码。 6. 在工程窗口中,右键点击“Inc”文件夹,选择“New Items”,然后选择“Header File”,输入文件名,点击“Add”按钮。这里以stm32f1xx_hal_conf.h为例。 7. 在新建的stm32f1xx_hal_conf.h文件中,添加以下代码: ``` /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F1xx_HAL_CONF_H #define __STM32F1xx_HAL_CONF_H /* Includes ------------------------------------------------------------------*/ #include "stm32f1xx_hal.h" /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/ #define assert_param(expr) ((void)0U) /* Exported functions prototypes ---------------------------------------------*/ /* Exported variables --------------------------------------------------------*/ #endif /* __STM32F1xx_HAL_CONF_H */ ``` 8. 在工程窗口中,右键点击“Src”文件夹,选择“New Items”,然后选择“C File”或者“C++ File”,输入文件名,点击“Add”按钮。这里以stm32f1xx_hal_msp.c为例。 9. 在新建的stm32f1xx_hal_msp.c文件中,添加以下代码: ``` #include "stm32f1xx_hal.h" void HAL_MspInit(void) { __HAL_RCC_AFIO_CLK_ENABLE(); } void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { if(htim_base->Instance==TIM2) { /* Peripheral clock enable */ __HAL_RCC_TIM2_CLK_ENABLE(); } } void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) { if(htim_base->Instance==TIM2) { /* Peripheral clock disable */ __HAL_RCC_TIM2_CLK_DISABLE(); } } ``` 10. 在工程窗口中,右键点击“Inc”文件夹,选择“New Items”,然后选择“Header File”,输入文件名,点击“Add”按钮。这里以stm32f1xx_hal_msp.h为例。 11. 在新建的stm32f1xx_hal_msp.h文件中,添加以下代码: ``` #ifndef __STM32F1xx_HAL_MSP_H #define __STM32F1xx_HAL_MSP_H #include "stm32f1xx_hal.h" void HAL_MspInit(void); void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base); void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base); #endif /* __STM32F1xx_HAL_MSP_H */ ``` 12. 在工程窗口中,右键点击“Inc”文件夹,选择“New Items”,然后选择“Header File”,输入文件名,点击“Add”按钮。这里以stm32f1xx_it.h为例。 13. 在新建的stm32f1xx_it.h文件中,添加以下代码: ``` #ifndef __STM32F1xx_IT_H #define __STM32F1xx_IT_H #include "stm32f1xx_hal.h" void SysTick_Handler(void); #endif /* __STM32F1xx_IT_H */ ``` 14. 在工程窗口中,右键点击“Src”文件夹,选择“New Items”,然后选择“C File”或者“C++ File”,输入文件名,点击“Add”按钮。这里以stm32f1xx_it.c为例。 15. 在新建的stm32f1xx_it.c文件中,添加以下代码: ``` #include "stm32f1xx_hal.h" #include "stm32f1xx_it.h" void SysTick_Handler(void) { HAL_IncTick(); } ``` 16. 在工程窗口中,右键点击“Inc”文件夹,选择“New Items”,然后选择“Header File”,输入文件名,点击“Add”按钮。这里以main.h为例。 17. 在新建的main.h文件中,添加以下代码: ``` #ifndef __MAIN_H #define __MAIN_H #include "stm32f1xx_hal.h" #endif /* __MAIN_H */ ``` 18. 在工程窗口中,右键点击工程名,选择“Options for Target 'Target 1'”,弹出“Options for Target 'Target 1'”对话框。 19. 选择“C/C++”选项卡,然后在“Define”栏中添加以下宏定义: ``` USE_HAL_DRIVER ``` 20. 点击“OK”按钮保存设置。 现在,你的STM32F103 HAL库工程已经创建完成了,可以开始编写代码了。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

巨大八爪鱼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值