使用STM32_HAL库点亮LED灯教程

用HAL库点亮一个LED灯

编程思路,代码,代码理解

芯片型号:

STM32F407ZGT6

参考文件:

F4 HAL库官方文档、STM32F4xx中文参考手册

基本思路:

点亮一个LED的最主要的就是控制LED对应的引脚的电平高低,如原理图可知:例如点亮LED_R,LED正极外界3.3V电压,则需要对PF6口输出低电平,即控制PF6_IO口输出低电平,形成电压差,从而点亮LED。

如原理图可知LED_R负极接芯片PF6口。

1、运用STM32CubeMX初始化

具体步骤:

①点击ACCESS TO MCU SELECTOR

 ②按上图所示步骤

在1处输入自己单片机型号 例如:STM32F407ZGT6。

在2处单机选择

在3处点击start project创建文件进入到配置界面

③初始化界面配置

1处可以搜索需要配置的功能,例如我需要配置IO口即可在此输入搜索GPIO

2处可以查看所有配置的列表

3处可视化芯片所有引脚

*******************************************

   这种颜色表示不可配置引脚  电源专用引脚以黄色突出显示。其配置不能更改

这种颜色表示你配置了一个I/O口的功能,但是没有初始化相对应的外设功能  引脚处于no mode 状态  

  绿色表示配置成功

来源:【STM32】STM32CubeMX教程二–基本使用(新建工程点亮LED灯)_Z小旋的博客-CSDN博客

 ******************************************

4处可以搜索要用的引脚,搜索到后会在3处闪烁 例如搜索PF6,会出现如下左图

-->

点击相应的引脚会显示出该引脚可配置的功能,点击所需要配置的功能即可,点击后出现如上右图。当右图可视化引脚冒绿光代表配置完成,可在中间框点击PF6配置更多参数。

 (有需要可配置时钟初始化Clock Configuration;默认时钟选择的是内部HSI RC

-16Mhz)

1可配置时钟

2配置文件

根据自己的需要配置Name、文件位置、IDE

配置完Project后配置Code Generator

 (我的一般配置)

 配置的大致说明:

 【STM32】STM32CubeMX教程二–基本使用(新建工程点亮LED灯)_Z小旋的博客-CSDN博客

配置完成后点击右上角GENERATE CODE生成文件如下图所示:

 打开MDK-ARAM里的程序,进行第一次编译,可能会发现会有如下报错:

 想要解决问题,需要在右侧Project处做如下操作:

 双击Drivers/CMSIS文件,在官方下载的STM32Cube_FW_F4_V1.27.0文件夹里选择Drivers,然后选择CMSIS,然后选择Device,无脑点到底到有一个Source文件的目录下,点击Source,再无脑点到有三个文件夹构成的目录下,点击arm,寻找和自己型号匹配的启动文件,双击添加,搞定。

至此配置的初始化差不多了,可以开始写简单的电灯程序了:

③正式电灯:

main函数中的while循环(已经自动生成)

while (1) {
        //对PF6口设置低电平
		HAL_GPIO_WritePin(GPIOF,GPIO_PIN_6,GPIO_PIN_RESET);
  }

搞定!!

④由于我是第一次用HAL找不到看的爽的教程,所以尝试自己分析里面的内容。

附上主函数:

//main函数
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();

  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */
		HAL_GPIO_WritePin(GPIOF,GPIO_PIN_6,GPIO_PIN_RESET);
  }
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  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_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @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 */
}
HAL_StatusTypeDef HAL_Init(void)
{
  /* Configure Flash prefetch, Instruction cache, Data cache */ 
#if (INSTRUCTION_CACHE_ENABLE != 0U)
  __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
#endif /* INSTRUCTION_CACHE_ENABLE */

#if (DATA_CACHE_ENABLE != 0U)
  __HAL_FLASH_DATA_CACHE_ENABLE();
#endif /* DATA_CACHE_ENABLE */

#if (PREFETCH_ENABLE != 0U)
  __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
#endif /* PREFETCH_ENABLE */

  /* Set Interrupt Group Priority */
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

  /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
  HAL_InitTick(TICK_INT_PRIORITY);

  /* Init the low level hardware */
  HAL_MspInit();

  /* Return function status */
  return HAL_OK;
}

 HAL_Init();使能HAL

这个函数用于初始化HAL库;它一定是第一个在主程序中执行的指令,它执行以下操作:

*配置Flash预取,指令和数据缓存。

*配置SysTick每1毫秒产生一个中断,

*设置“NVIC组优先级”为“4”。

*调用用户文件中定义的HAL_MspInit()回调函数在“stm32f4xx_hal_msp.c”文件中的进行全局底层硬件初始化。

最后返回HAL使能的状态

SystemClock_Config();

顾名思义,系统时钟初始化

在这个函数中对RCC内/外振荡器(HSE, HSI, LSE和LSI)配置结构进行初始化

/** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;//使用内部竞争HSI
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;//当然要开启HSI
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;//看不懂,默认就是这玩意
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;//锁相环结构参数
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

HAL_RCC_OscConfig(&RCC_OscInitStruct) 初始化配置的时钟,标准库里也有类似的操作,这个有返回值能判断是否初始化成功。如果没有初始化成功,进入到一个Error_Handler()函数,程序注释说的是可以自己编写错误报告在里面。

上面的初始化时钟在标准库编程中也有不同的实现。

/** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  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_0) != HAL_OK)
  {
    Error_Handler();
  }

HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0)初始化CPU、

AHB、APB总线

同时也要配置总线时钟的结构体

和标准库编程一样分频差不多的配置,只不过在STM32CubeMX上配置好了

函数调用的第二个参数:FLatency:FLatency FLASH延迟时间,该参数取决于所选择的设备

同样可以判断是否配置完成。

 然后有一个

MX_GPIO_Init();熟悉的GPIO初始化函数

void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOF_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_RESET);

  /*Configure GPIO pin : PF6 */
  GPIO_InitStruct.Pin = GPIO_PIN_6;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
}

__HAL_RCC_GPIOF_CLK_ENABLE();熟悉的GPIO时钟使能

结构体配置也是和标准库函数一样的套路,能在STM32CubeMX生成

最后调用HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);将结构体写入。

和标准库一摸一样!!!!!!!!!

上述已经初始化完成了,能开始写简单的带灯了 so easy

while (1) {
        //对PF6口设置低电平
		HAL_GPIO_WritePin(GPIOF,GPIO_PIN_6,GPIO_PIN_RESET);
  }

HAL_GPIO_WritePin(GPIOF,GPIO_PIN_6,GPIO_PIN_RESET);

该函数作用是往这个指定的引脚写入低电平然后就能做到一直亮灯。

保存编译烧录and运行--->

效果:

 总结: 

电灯是最简单的一个案例,不管在标准库里编程还是HAL库里,找回了之前用标准库的感觉,原理大差不大,只不过调用的函数不同,配置过程有点差别,更加方便了。同时这个电灯程序让我了解基本的HAL库编程思路。

附:

STM32CubeF4 – STM32Cube MCU包,用于STM32F4系列(HAL、底层API和CMSIS(CORE、DSP和RTOS)、USB、TCP/IP、File system、RTOS和Graphic – 附带在以下ST板上运行的示例:STM32 Nucleo、探索套件和评估板) – 意法半导体STMicroelectronics

物联沃分享整理
物联沃-IOTWORD物联网 » 使用STM32_HAL库点亮LED灯教程

发表评论