Keil创建自定义的STM32 HAL库工程

注:以下工程创建将以STM32F103ZET6为例:

  • 72MHz 主频;
  • 64K SRAM;
  • 512K Flash.

1 下载需要的资料包

1.1 下载 Keil 的 STM32F103 芯片支持包

1.1.1 手动下载安装包

Keil官网:https://www.keil.com/
(1)进入官网,点击 Download。
在这里插入图片描述


(2)选择 Product Downloads,然后选择 MDK-Arm,进入之后选择 Device List。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


(3)直接输入芯片名称查找芯片支持包。
在这里插入图片描述

或选择供应商和内核查找芯片支持包
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


(4)下载支持包 点击 STM32F1xx_DFP,进入下载界面,点击 Download 下面的支持包。

在这里插入图片描述
在这里插入图片描述


下载完成之后,后续使用 Keil 的 Pack Installer 导入到项目中。

在这里插入图片描述

1.1.2 使用 Keil 的 Pack Installer 下载

点击如下图图标打开 Pack Installer ,
在这里插入图片描述


左侧 Device 找到 All Devices - STMicroelectronics - STM32F1 Series - STM32F103 - STM32F103ZE,右侧 Packs 窗口下找到 Keil::STM32F1xx_DFP, 点击右侧的 Install 下载。
在这里插入图片描述

1.2 下载STM32F103 HAL库

ST官网: https://www.st.com/content/st_com/en.html
在这里插入图片描述
选择 Tools&Software,


在这里插入图片描述
选择 STM32 embedded software,


在这里插入图片描述

选择 STM32Cube MCU & MPU Packages


在这里插入图片描述
选择 F1 系列,点击 Open software page,打开软件包下载页面。


在这里插入图片描述

点击 Get latest 进行下载外设标准库。

2 创建工程文件夹

在这里插入图片描述

Core:存放从SDK中抽取的部分可能会修改的核心文件;
Driver:存放用户编写的外设驱动;
User:存放用户函数文件
Project:存放Keil工程文件,二进制目标文件;
SDK:存放CMSIS和HAL库(或标准库)
Clean.bat:清理Project里的Keil生成的工程文件;
Readme.txt:该工程的说明信息。

3 拷贝相关文件到工程目录

3.1 解压HAL库包

在这里插入图片描述

3.2 拷贝相关文件

(1)拷贝启动文件
在这里插入图片描述
在这里插入图片描述

将 STM32Cube_FW_F1_V1.8.0\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\arm 目录下的 startup_stm32f103xe.s 拷贝到 00_STM32_Demo\Core 目录下。


(2)拷贝系统初始化文件和外设寄存器描述文件

在这里插入图片描述

将 STM32Cube_FW_F1_V1.8.0\Drivers\CMSIS\Device\ST\STM32F1xx\Include 目录下的 {system_stm32f1xx.h, stm32f103xe.h, stm32f1xx.h} 拷贝到 00_STM32_Demo\Core 目录下。

在这里插入图片描述
将 STM32Cube_FW_F1_V1.8.0\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates 目录下的 {system_stm32f1xx.c} 拷贝到 00_STM32_Demo\Core 目录下。

(3)拷贝内核寄存器描述文件

在这里插入图片描述

将 STM32Cube_FW_F1_V1.8.0\Drivers\CMSIS\Core\Include 目录下的 {core_cm3.h} 拷贝到 00_STM32_Demo\Core 目录下。

(4)拷贝中断和HAL配置相关文件
在这里插入图片描述
将 STM32Cube_FW_F1_V1.8.0\Projects\STM3210E_EVAL\Templates\Inc 目录下的 {stm32f1xx_it.h, stm32f1xx_hal_conf.h} 拷贝到 00_STM32_Demo\Core 目录下。

在这里插入图片描述
将 STM32Cube_FW_F1_V1.8.0\Projects\STM3210E_EVAL\Templates\Src 目录下的 {stm32f1xx_it.c} 拷贝到 00_STM32_Demo\Core 目录下。

(5)拷贝 CMSIS 相关头文件
在这里插入图片描述

4 Keil 创建项目工程

(1)新建项目工程。
Project - New uVision Project
在这里插入图片描述


找到对应的芯片类型。

在这里插入图片描述
在这里插入图片描述


(2)创建分组

在这里插入图片描述


(3)将本地本件添加到工程分组

在这里插入图片描述

添加文件之后需要更改文件类型,否则会出现下面的告警。

Rebuild started: Project: STM32_Demo
*** Using Compiler 'V6.14.1', folder: 'D:\Keil_v5\Core\ARM\ARMCLANG\Bin'
Rebuild target 'Target 1'
FCARM - Output Name not specified, please check 'Options for Target - Utilities'
Target not created.
Build Time Elapsed:  00:00:00

修改文件类型方法:
选中文件后右键,
File Type 更改为对应的文件类型,如下:
在这里插入图片描述

在这里插入图片描述
其他 .s 或 .c 文件同样设置。

注意:.h 文件添加到分组后不能设置为 “C Source File” 类型,可以设置为 “Text Document file” ,或者直接不要把 .h 文件添加到分组中,否则编译报错
在这里插入图片描述


(4)添加设备型号宏定义

Core/stm32f1xx.h

在这里插入图片描述

在这里插入图片描述


(5)配置时钟和编译器版本 开发板使用8M外部晶振。 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/b3de7804a0c74f709f5502257e918197.png) 只能选择 version 5 的版本,不然编译报错,version 6版本有些语法不支持。
(6)配置目标文件输出路径和 listing 文件存放路径 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/41e0b1b5510846e9897d9a9ff23c5e64.png)

在这里插入图片描述


(7)配置生成 hex 文件
在这里插入图片描述


(8)配置头文件路径和语法版本

在这里插入图片描述


(9)配置文件的编码格式
在这里插入图片描述

(10)拷贝HAL库
将 STM32Cube_FW_F1_V1.8.0\Drivers\STM32F1xx_HAL_Driver 目录拷贝到 00_STM32_Demo\SDK 目录下。
在这里插入图片描述


将 HAL 库源文件添加到 Driver/Hal Group。 注意:下图文件类型要选择 C Source file(*.c)

在这里插入图片描述

注意:xxxxx_template.c 的文件可以不用加载进来,不然可能会有编译报错。


根据 00_STM32_Demo\Core\stm32f1xx.h 里面用到的宏,
在这里插入图片描述

添加一个使用 HAL库 的宏 “USE_HAL_DRIVER”。

在这里插入图片描述


解决编译错误:
在这里插入图片描述
将 117行挪到 113行。

用户代码调用 HAL 库。

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"

void delay(int ms)
{
    int i, j;
    for (i = 0; i < ms; i++) {
        for (j = 0; j < 1000; j++) {
            ;
        }
    }
}

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
 void Error_Handler(void)
 {
   /* USER CODE BEGIN Error_Handler_Debug */
   /* User can add his own implementation to report the HAL error return state */
   __disable_irq();
   while (1)
   {
   }
   /* USER CODE END Error_Handler_Debug */
 }

/**
  * @brief 系统时钟配置
  * @retval None
  */
void SystemClock_Config(void)
{
	RCC_OscInitTypeDef RCC_OscInitStruct = {0};
	RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
	/* 根据 RCC_OscInitTypeDef 结构中的指定参数初始化RCC振荡器 */
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
	RCC_OscInitStruct.HSEState = RCC_HSE_ON;
	RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
	RCC_OscInitStruct.HSIState = RCC_HSI_ON;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
	RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
	if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
	{
		Error_Handler();
	}
	/* 初始化CPU、AHB和APB总线时钟 */
	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_DIV2;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
	if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
	{
		Error_Handler();
	}
}

int main(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    HAL_Init();

    SystemClock_Config();

    // Enable clock for GPIOB
    __HAL_RCC_GPIOB_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    while (1) {
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
        delay(1000);

        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
        delay(1000);
    }

    return 0;
}

最后再重新编译一下工程,0错误。

在这里插入图片描述

HAL 库工程模板创建完毕。

在Cubemx和Keil IAR集成开发环境中,设计一个支持DMA的两路ADC数据采集程序分为以下几个步骤: 1. **项目创建**: - 在Cubemx中新建一个STM32项目,选择相应的芯片型号和支持的外设配置。 2. **硬件配置**: - 在Pinout视图中,为每一路ADC分配输入引脚,然后配置为ADC模式。 - 如果有内置的DMA资源,配置相应的DMA控制器及其通道,用于数据传输。 3. **软件配置**: - **ADC配置**: - 在Cubemx的HAL Configurator中,添加ADC模块,配置通道、时钟、数据率等参数。 - 为每个通道配置中断,以便在数据准备好时捕获中断。 - **DMA配置**: - 同步添加DMA模块,配置源、目标地址,以及传输的大小和方向。 - 将ADC的数据输出地址映射到内存,为两路ADC配置不同的接收缓冲区。 - **HAL集成**: - 引入`stm32xx_hal_adc.h` 和 `stm32xx_hal_dma.h` 文件,包含必要的函数声明。 - 编写ADC和DMA的初始化函数以及中断处理函数。 4. **数据处理**: - 使用`HAL_ADC_ReadValue`函数读取ADC值,然后在中断处理函数中存储到对应的数组中。 - 更新中断服务函数,处理ADC中断,并在每个通道的采样结束后切换到下一个通道。 5. **主函数中整合**: - 在主循环中,首先初始化ADC和DMA,然后启动ADC的连续转换和DMA的传输。 - 当ADC中断发生时,检查是否来自哪一路ADC,然后更新对应数组的值。 - 在DMA传输完成后,如果已达到预设的样本数或采集时间结束,可以停止ADC。 示例代码片段: ```c void ADC_IRQHandler(void) { if (__HAL_ADC_GET_FLAG(&hadc1, HAL_ADC_FLAG_ADRDY)) { // 检查ADC通道 if (channel == 0) { ADCData[0] = HAL_ADC_GetValue(&hadc1); } else { ADCData[1] = HAL_ADC_GetValue(&hadc1); } channel = (channel + 1) % 2; // 通道轮换 } } void DMAHalfTransferCompletedCallback(DMA_HandleTypeDef *hdma) { HAL_GPIO_ToggleBits(GPIOA, GPIO_PIN_0); // 示例:标志传输完成 if (hdma->Instance == DMA1_Channel2) { // 对应第一路ADC数据的DMA ADC_IRQHandler(); // 触发ADC中断 } else if (hdma->Instance == DMA1_Channel3) { // 对应第二路ADC数据的DMA ADC_IRQHandler(); // 触发ADC中断 } } void SystemClock_Config(void) { // ... ADC_Init(); // ADC初始化 HAL_DMA_Init(DMA_Handle); // DMA初始化 HAL_NVIC_EnableIRQ(ADC_IRQn); // 开启ADC中断 HAL_NVIC_EnableIRQ(DMATx_IRQn); // 开启DMA中断 // ... } int main(void) { // ... ADC_IRQHandler(); // 初始触发一次中断以填充第一个通道的数据 // 启动ADC和DMA HAL_ADC_Start_DMA(&hadc1, ADC_DMA_Buffer, 2 * sizeof(uint16_t)); // ... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值