在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宏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章