STM32 基于HAL库和STM32cubeIDE的应用教程 (二)--GPIO的使用

news/2024/11/8 14:34:22 标签: 单片机, 嵌入式硬件, stm32

如果有什么不懂的地方欢迎私聊博主,欢迎小白,博主必一一解答。

在 STM32 中,GPIO(通用输入输出)是与外部硬件接口进行交互的主要方式之一。STM32 HAL 库提供了简洁的接口来配置和控制 GPIO 引脚。下面是使用 STM32 HAL 库进行 GPIO 操作的详细教程。

1. 环境准备

确保您已经按照以下步骤准备好开发环境:

  • STM32CubeIDE 已安装。
  • 创建了 STM32 项目,配置了目标 STM32 微控制器或开发板。

2. 配置 GPIO 外设

在 STM32CubeIDE 中,我们通过 STM32CubeMX 来配置 GPIO 引脚。

步骤:
  1. 打开 STM32CubeIDE,选择新建一个 STM32 项目。
  2. Pinout & Configuration 页面,选择您要使用的 GPIO 引脚。例如,选择 GPIOA 上的引脚如 PA5(通常用作 LED 灯),并设置为 GPIO_Output,或 GPIOA 上的引脚如 PA0 设置为 GPIO_Input
  3. Configuration 选项卡中,设置引脚的模式、输出类型等。
    • 对于输出引脚,选择 Push-Pull,并设置速率。
    • 对于输入引脚,选择 Pull-upPull-down,以决定输入信号的默认状态。
  4. Project 设置中,选择项目名称和代码生成选项(选择 STM32CubeIDE 为 IDE,选择 HAL 库作为中间件)。
  5. 点击 Generate Code,STM32CubeMX 会生成初始化代码。

3. HAL 库的 GPIO 操作

生成代码后,您可以开始在 main.c 文件中编写应用程序,利用 STM32 HAL 库操作 GPIO 引脚。

GPIO 输入输出操作

1.初始化 GPIO

STM32CubeMX 会自动生成用于初始化 GPIO 的代码,您只需调用 HAL_GPIO_Init() 函数。例如,在 main.c 中可以看到类似这样的初始化代码,我以注释的方式,解释了代码。

// main.c
#include "main.h"

int main(void)
{
    HAL_Init();  // 初始化 HAL 库
    SystemClock_Config();  // 配置系统时钟
    MX_GPIO_Init();  // 初始化 GPIO

    while (1)
    {
        // 在主循环中进行其他任务
    }
}

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

    __HAL_RCC_GPIOA_CLK_ENABLE();  // 启用 GPIOA 时钟

    // 配置 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);  // 初始化 GPIOA5

    // 配置 PA0 为输入
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;  // 上升沿中断模式
    GPIO_InitStruct.Pull = GPIO_NOPULL;  // 无上下拉
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);  // 初始化 GPIOA0
}

GPIO 输出操作

要设置 GPIO 引脚的输出状态(高电平或低电平),您可以使用 HAL_GPIO_WritePin() 函数。例如:

// 设置 PA5 为高电平(点亮 LED)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);  // 高电平

// 设置 PA5 为低电平(熄灭 LED)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);  // 低电平

GPIO 输入操作

要读取 GPIO 引脚的输入状态,可以使用 HAL_GPIO_ReadPin() 函数。例如,读取 PA0 的状态:

GPIO_PinState pinState = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);

if (pinState == GPIO_PIN_SET) {
    // 引脚 PA0 为高电平
} else {
    // 引脚 PA0 为低电平
}

GPIO 中断操作

STM32 HAL 库还支持 GPIO 中断。通过 STM32CubeMX 配置中断模式,例如将 PA0 设置为上升沿触发的中断。下面介绍中断的概念。

额外(中断是什么?)

中断(Interrupt)是微控制器(单片机)处理外部事件或任务的一种机制。它允许微控制器在执行程序的过程中,能够中断当前的工作,立即响应外部事件,然后在处理完事件后恢复到原来的工作状态。中断是实时操作系统(RTOS)和高效嵌入式系统设计中常用的一种技术。 

中断的工作原理

当一个中断发生时,微控制器会:

  1. 暂停当前程序:当前正在执行的代码(包括主程序或其他中断服务程序)会被暂停。微控制器保存当前的执行状态(程序计数器、寄存器值等)。

  2. 跳转到中断处理函数(ISR):程序计数器会被修改,跳转到对应的中断服务程序地址。该中断服务程序通常是用户编写的代码,用来处理特定的中断事件。

  3. 处理中断:在中断服务程序中,微控制器执行相应的代码以响应中断,比如读取传感器数据、处理外部设备的请求等。

  4. 恢复执行:中断处理完毕后,微控制器恢复执行原来的程序,继续之前被暂停的操作。

回归正题 ,将 PA0 设置为上升沿触发的中断

在代码中,您需要启用和配置外部中断:

// 在 MX_GPIO_Init 函数中启用中断
HAL_NVIC_SetPriority(EXTI0_1_IRQn, 0, 0);  // 设置中断优先级
HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);  // 启用 EXTI0_1 中断

中断服务程序(ISR)通常放在 stm32f1xx_it.c 中:

// 中断回调函数
void EXTI0_1_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);  // 处理外部中断
}

// 回调函数,当发生中断时调用
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_0) {
        // 对 PA0 引脚的中断进行处理
    }
}

4. 使用外设和其他功能

  • 配置和使用多个 GPIO 引脚:通过 STM32CubeMX 配置多个 GPIO 引脚进行输入、输出或中断操作。
  • 控制 LED:在 main.c 中使用 HAL_GPIO_WritePin() 控制连接到开发板的 LED。
  • 配置按键:配置外部按键,并在中断或轮询模式下读取按键状态。

5. 示例代码:点亮 LED

下面是一个完整的示例,展示如何通过 GPIO 控制 LED:

#include "main.h"

// 主函数
int main(void)
{
    HAL_Init();  // 初始化 HAL 库
    SystemClock_Config();  // 配置系统时钟
    MX_GPIO_Init();  // 初始化 GPIO

    while (1)
    {
        // 点亮 LED
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
        HAL_Delay(500);  // 延时 500ms

        // 熄灭 LED
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
        HAL_Delay(500);  // 延时 500ms
    }
}

// GPIO 初始化函数
void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();  // 启用 GPIOA 时钟

    // 配置 PA5 为输出(LED)
    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);  // 初始化 GPIOA5
}

6. 小结

  • GPIO 初始化:通过 STM32CubeMX 配置引脚,并使用 HAL 库函数进行初始化。
  • 输入输出操作:使用 HAL_GPIO_WritePin() 控制输出,使用 HAL_GPIO_ReadPin() 读取输入。
  • 中断处理:通过 STM32CubeMX 配置中断,并在中断回调函数中处理外部中断。


http://www.niftyadmin.cn/n/5744031.html

相关文章

Android Parcelable和Serializable的区别与联系

在Android开发中,Parcelable和Serializable是两种用来在组件之间传递数据的序列化机制。它们有不同的使用场景和性能特点。 以下是它们之间的关系和区别: 1. 什么是 Parcelable Parcelable 是 Android 特有的接口,用于高效地在进程间传递数…

优化策略:揭秘钢条切割与饼干分发的算法艺术

引言 在生活中,钢条和饼干看似风马牛不相及,但它们的分割与分发却隐藏着惊人的数学魅力。如何最大化利润?如何用有限的资源最大程度满足需求?这便是算法世界中的艺术。今天,我们来揭秘钢条切割与饼干分发的算法设计。本…

6-1.Java 面向对象 - 初级(对象与属性、对象与方法、递归、重载、可变参数、作用域、构造器、对象创建流程详解、this 关键字)

一、对象与属性 1、基本介绍 属性是类的一个组成部分,一般是基本数据类型,也可以是引用数据类型 属性的定义语法类似变量 【访问修饰符】 【属性类型】 【属性名】;属性的定义类型可以为任何类型(基本数据类型、引用数据类型)…

生产环境中添加多项式特征实现:将逻辑回归应用于非线性关系

要将逻辑回归应用于非线性关系,并实现到生产环境中,我们可以通过以下步骤来完成。这里主要使用 Python 和 Scikit-Learn 库,因为它们为机器学习任务提供了强大的工具和易于使用的接口。我们将通过添加多项式特征来扩展逻辑回归模型&#xff0…

免费数据集网站

1、DataSearch https://datasetsearch.research.google.comhttp://DataSearch 2、FindData findata-科学数据搜索引擎https://www.findata.cn/ 3、Kaggle Kaggle: Your Machine Learning and Data Science CommunityKaggle is the world’s largest data science community …

16通道AD采集方案,基于复旦微ARM + FPGA国产SoC处理器平台

测试数据汇总 表 1 本文带来的是基于复旦微FMQL20S400M四核ARM Cortex-A7(PS端) + FPGA可编程逻辑资源(PL端)异构多核SoC处理器设计的全国产工业评估板的AD采集案例。本次案例演示的开发环境如下: Windows开发环境:Windows 7 64bit、Windows 10 64bit PL端开发环境:P…

react搭建router,redux教程

react项目搭建create-router-dom,redux详细解说 1.搭建react脚手架 首先选择脚手架,dav-cli,create-react-app,Ant-Design-Pro-cli。脚手架即为代码层次。这里我们选用create-react-app脚手架 打开我们的cmd,windowR输…

第一章 Linux安装 -- 安装Debian 12操作系统(四)

文章目录 2.3.4 安装Debian 12操作系统 2.3.4 安装Debian 12操作系统 虚拟机的创建参照前面2.3.1.3节里的步骤创建,这里不再详述。 下面就开始安装Debian 12系统了,单击“开启此虚拟机”,如图1-161虚拟机主界面。 图1-161 虚拟机主界面 弹…