STM32芯片编程指南(1)— 点亮LED

STM32芯片编程指南(1)— 点亮LED

首先实现,使用STM32芯片点亮LED

以下是一个通用的示例,假设你使用的是STM32CubeIDE和CubeMX进行开发,并将LED连接到STM32的GPIO引脚上。

这个示例假设你将LED连接到了STM32的GPIO引脚PA5上。

#include "main.h"
#include "stm32f4xx_hal.h"

void SystemClock_Config(void);
static void MX_GPIO_Init(void);

int main(void) {
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();

  while (1) {
    // 点亮LED
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
    HAL_Delay(1000); // 延迟1秒

    // 关闭LED
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
    HAL_Delay(1000); // 延迟1秒
  }
}

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 CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_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();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  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();
  }
}

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

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

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

  /*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()函数控制了GPIO引脚PA5的电平,从而控制LED的点亮和关闭。在main()函数的无限循环中,LED会每隔一秒交替点亮和关闭。

记得根据你的具体硬件连接和使用的STM32芯片型号进行必要的修改,包括修改引脚号、时钟设置等。此外,这个示例使用了HAL库函数,如果你使用的是其他库或者裸机编程,可能需要做相应的调整。

什么是HAL库

HAL库(Hardware Abstraction Layer)是由STMicroelectronics提供的一组预先编写好的函数,用于与STM32系列微控制器进行交互。这些函数封装了对硬件寄存器的访问,使得你可以更方便地编写代码而无需直接操作底层寄存器。

HAL库的优点在于它提供了一种抽象层,使得代码更易读、易写和可移植。它简化了与硬件的交互,允许你专注于应用程序的开发而不是底层硬件的细节。

你可以直接使用HAL库函数来开发STM32应用程序。ST提供了完整的文档和示例代码,帮助你了解如何使用这些函数。通常,你需要设置好硬件初始化,然后使用HAL库函数来操作GPIO、定时器、串口等外设,实现你的应用逻辑。

在使用HAL库时,需要包含对应的库文件,并进行相应的配置。使用CubeMX可以方便地生成初始化代码和配置,然后在IDE中使用HAL库函数来编写应用程序。

记住,尽管HAL库简化了开发流程,但有时在对性能或资源使用有严格要求的场景下,直接操作寄存器可能更为灵活和高效。选择使用HAL还是直接操作寄存器,取决于你的项目需求和个人偏好。

对SystemClock_Config的解释

SystemClock_Config 函数是用来配置STM32微控制器的系统时钟的函数。

在STM32中,系统时钟的配置非常重要,因为它决定了微控制器的运行速度和各种外设的时钟频率。

这个函数通常是由CubeMX自动生成的,用于初始化系统时钟。让我们来解释一下这个函数的主要部分:

void SystemClock_Config(void) {
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /* 配置主时钟源和PLL(锁相环) */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_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();
  }
}
  1. 配置主时钟源和PLL:

    • RCC_OscInitStruct 结构体用于配置时钟源。在这个例子中,使用外部晶振(HSE)作为主时钟源,然后配置PLL来产生系统所需的时钟频率。这里设置了PLL的各种参数,比如分频器的值,以及输出频率等。
    • HAL_RCC_OscConfig(&RCC_OscInitStruct) 调用函数应用这些配置并启动时钟源和PLL。
  2. 配置系统时钟:

    • RCC_ClkInitStruct 结构体用于配置系统时钟。在这个例子中,选择将系统时钟源设置为PLL输出,并且设置了AHB(高速总线)、APB1和APB2(外设总线)的分频器。
    • HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) 调用函数应用这些配置,并设置相应的FLASH存储器延迟以匹配新的时钟频率。

总的来说,SystemClock_Config 函数的目的是配置系统时钟源和时钟分频器,确保微控制器能够以期望的频率稳定运行。这样可以确保外设的时钟频率正确,并保证整个系统的稳定性和性能。

PLL(Phase-Locked Loop,相位锁定环是一种电路系统,用于产生稳定的输出信号,

其频率和相位与输入信号相关联。它是用于调整和稳定频率的重要电路组件,广泛应用于通信、计算机、数字信号处理和各种电子设备中。

PLL的工作原理:

  1. 基本组成部分:一个典型的PLL包括三个主要部分:相频比较器(Phase Detector)、电压控制振荡器(Voltage-Controlled Oscillator,VCO)、反馈回路(Feedback Loop)。

  2. 输入信号与VCO:输入信号与VCO连接,VCO产生一个频率可调的输出信号。

  3. 相频比较器:相频比较器检测输入信号和VCO输出信号之间的相位差异,并将这种差异转换成一个控制信号。

  4. 控制信号和VCO:控制信号被发送到VCO,用来调整VCO的输出频率,使得VCO输出的信号的相位和频率与输入信号匹配或者锁定。

  5. 反馈回路:将VCO输出信号反馈给相频比较器,使得它能够不断地检测和修正输入信号和VCO输出信号之间的相位差,以保持它们保持同步或锁定。

PLL的应用:

  1. 时钟生成:在数字电路中,PLL经常被用于产生精确的时钟信号,用于各种系统中的时序控制。

  2. 频率合成器:PLL可以将一个较低频率的参考信号转换成一个更高频率的输出信号。

  3. 通信系统:在调制解调器和无线通信中,PLL用于产生调制解调的本地振荡信号。

  4. 数字信号处理:用于时序同步和数据采样等方面。

对MX_GPIO_Init的解释

MX_GPIO_Init 是由 STM32CubeMX 自动生成的初始化函数之一,

用于初始化 STM32 微控制器的 GPIO(通用输入输出)引脚。

示例代码结构:

以下是一个示例代码结构,展示了一个由 STM32CubeMX 自动生成的 MX_GPIO_Init 函数:

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

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

  /* Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

  /* 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);
}
解释:
  1. 启用 GPIO 时钟

    • __HAL_RCC_GPIOA_CLK_ENABLE():启用 GPIOA 端口的时钟。这个函数确保了你要使用的 GPIO 端口的时钟被启用,以便使用这些 GPIO 引脚。
  2. 配置 GPIO 引脚

    • GPIO_InitStruct 是一个 GPIO_InitTypeDef 结构体类型的变量,用于配置特定的 GPIO 引脚。
    • GPIO_InitStruct.Pin = GPIO_PIN_5;:指定要配置的引脚是 PA5。
    • GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;:配置引脚为推挽输出模式。这意味着这个引脚可以输出高电平或低电平,而不是输入模式或开漏输出。
    • GPIO_InitStruct.Pull = GPIO_NOPULL;:禁用了上下拉电阻。这意味着在配置为输入模式时,引脚上不会有上拉或下拉电阻。
    • GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;:设置引脚的速度为低速。这表示引脚的驱动能力较低。
  3. 设置引脚输出电平

    • HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);:将 PA5 引脚的输出电平设置为低电平。在这里,GPIO_PIN_RESET 表示低电平。
  4. 初始化 GPIO 引脚

    • HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);:使用上述配置初始化 GPIOA 的引脚,这里是 PA5。

这个函数的作用是配置特定 GPIO 引脚的工作模式、输入/输出特性和电气特性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值