【STM32 CubeMX】GPIO_HAL库源码分析

文章目录

  • 前言
  • 一、GPIO_HAL库源码分析
    • 1.1 初始化GPIO
    • 1.2 HAL_GPIO_Init源码分析
      • GPIO_InitTypeDef初始化结构体
      • HAL_GPIO_Init函数
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


一、GPIO_HAL库源码分析

1.1 初始化GPIO

void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOB_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);/*Configure GPIO pin : PB5 */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(GPIOB, &GPIO_InitStruct);
}

上面这个代码是初始化GPIOBpin5引脚
在这里设置哪个引脚:GPIO_InitStruct.Pin = GPIO_PIN_5;
设置模式:GPIO_InitStruct.ModeGPIO_MODE_OUTPUT_PP为推挽输出
除了推挽输出,他还有下面这些:

#define  GPIO_MODE_OUTPUT_PP                    0x00000001u   /*推挽输出               */
#define  GPIO_MODE_OUTPUT_OD                    0x00000011u   /*开漏输出                */

在这里:GPIO_InitStruct.Pull,我们是设置是否有上下拉电阻,他有以下这些值

#define  GPIO_NOPULL        0x00000000u   /*!< No Pull-up or Pull-down activation  */
#define  GPIO_PULLUP        0x00000001u   /*!< Pull-up activation                  */
#define  GPIO_PULLDOWN      0x00000002u   /*!< Pull-down activation                */

其中就是无上下拉电阻,上拉、下拉电阻的设置

在我们主函数的while循环如下:

while (1)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);
HAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */
}

他就只是对GPIOB pin5输出高低电平点灯

我们主要需要看一下HAL_GPIO_Init函数是如何实现的

1.2 HAL_GPIO_Init源码分析

GPIO_InitTypeDef初始化结构体

GPIO_InitTypeDef这个结构体是用来对于某一个引脚进行初始化存储的结构体
他长下面这样:

typedef struct
{uint32_t Pin;       /*!< Specifies the GPIO pins to be configured.This parameter can be any value of @ref GPIO_pins_define */uint32_t Mode;      /*!< Specifies the operating mode for the selected pins.This parameter can be a value of @ref GPIO_mode_define */uint32_t Pull;      /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.This parameter can be a value of @ref GPIO_pull_define */uint32_t Speed;     /*!< Specifies the speed for the selected pins.This parameter can be a value of @ref GPIO_speed_define */
} GPIO_InitTypeDef;

第一个成员为pin,pin这样表示

#define GPIO_PIN_0                 ((uint16_t)0x0001)  /* Pin 0 selected    */
#define GPIO_PIN_1                 ((uint16_t)0x0002)  /* Pin 1 selected    */
#define GPIO_PIN_2                 ((uint16_t)0x0004)  /* Pin 2 selected    */
#define GPIO_PIN_3                 ((uint16_t)0x0008)  /* Pin 3 selected    */
#define GPIO_PIN_4                 ((uint16_t)0x0010)  /* Pin 4 selected    */
#define GPIO_PIN_5                 ((uint16_t)0x0020)  /* Pin 5 selected    */
#define GPIO_PIN_6                 ((uint16_t)0x0040)  /* Pin 6 selected    */
#define GPIO_PIN_7                 ((uint16_t)0x0080)  /* Pin 7 selected    */
#define GPIO_PIN_8                 ((uint16_t)0x0100)  /* Pin 8 selected    */
#define GPIO_PIN_9                 ((uint16_t)0x0200)  /* Pin 9 selected    */
#define GPIO_PIN_10                ((uint16_t)0x0400)  /* Pin 10 selected   */
#define GPIO_PIN_11                ((uint16_t)0x0800)  /* Pin 11 selected   */
#define GPIO_PIN_12                ((uint16_t)0x1000)  /* Pin 12 selected   */
#define GPIO_PIN_13                ((uint16_t)0x2000)  /* Pin 13 selected   */
#define GPIO_PIN_14                ((uint16_t)0x4000)  /* Pin 14 selected   */
#define GPIO_PIN_15                ((uint16_t)0x8000)  /* Pin 15 selected   */
#define GPIO_PIN_All               ((uint16_t)0xFFFF)  /* All pins selected */

比如GPIO5,他变成二进制如下:在这里插入图片描述
他的bit5为1,是不是和我们上两节课的寄存器联系起来了
如果没有看过的同学可以进入HAL库的本质是操作寄存器来进行学习

接下来看Speed成员:
他可以有以下取值:

#define  GPIO_SPEED_FREQ_LOW              (GPIO_CRL_MODE0_1) /*!< Low speed */
#define  GPIO_SPEED_FREQ_MEDIUM           (GPIO_CRL_MODE0_0) /*!< Medium speed */
#define  GPIO_SPEED_FREQ_HIGH             (GPIO_CRL_MODE0)   /*!< High speed */

其中有低速,中速和高速
其中低速为2M,中速10M高速50M

HAL_GPIO_Init函数

这个函数有两个参数。一个为组号,另一个为初始化结构体
首先第一个参数,他有如下取值:

#define GPIOA               ((GPIO_TypeDef *)GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *)GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *)GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *)GPIOD_BASE)
#define GPIOE               ((GPIO_TypeDef *)GPIOE_BASE)
#define GPIOF               ((GPIO_TypeDef *)GPIOF_BASE)
#define GPIOG               ((GPIO_TypeDef *)GPIOG_BASE)
//。。。。。。

GPIOx_Base如下:

#define GPIOA_BASE            (APB2PERIPH_BASE + 0x00000800UL)
#define GPIOB_BASE            (APB2PERIPH_BASE + 0x00000C00UL)
#define GPIOC_BASE            (APB2PERIPH_BASE + 0x00001000UL)
#define GPIOD_BASE            (APB2PERIPH_BASE + 0x00001400UL)

这些就一起定义了一个组的基地址是什么

接下来我们看HAL_GPIO_Init源码:

void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)
{uint32_t position = 0x00u;uint32_t ioposition;uint32_t iocurrent;uint32_t temp;uint32_t config = 0x00u;__IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */uint32_t registeroffset;       /* offset used during computation of CNF and MODE bits placement inside CRL or CRH register *//* Check the parameters */assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));assert_param(IS_GPIO_PIN(GPIO_Init->Pin));assert_param(IS_GPIO_MODE(GPIO_Init->Mode));/* Configure the port pins */while (((GPIO_Init->Pin) >> position) != 0x00u){/* Get the IO position */ioposition = (0x01uL << position);/* Get the current IO position */iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;if (iocurrent == ioposition){/* Check the Alternate function parameters */assert_param(IS_GPIO_AF_INSTANCE(GPIOx));/* Based on the required mode, filling config variable with MODEy[1:0] and CNFy[3:2] corresponding bits */switch (GPIO_Init->Mode){/* If we are configuring the pin in OUTPUT push-pull mode */case GPIO_MODE_OUTPUT_PP:/* Check the GPIO speed parameter */assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_PP;break;/* If we are configuring the pin in OUTPUT open-drain mode */case GPIO_MODE_OUTPUT_OD:/* Check the GPIO speed parameter */assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_OD;break;/* If we are configuring the pin in ALTERNATE FUNCTION push-pull mode */case GPIO_MODE_AF_PP:/* Check the GPIO speed parameter */assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_PP;break;/* If we are configuring the pin in ALTERNATE FUNCTION open-drain mode */case GPIO_MODE_AF_OD:/* Check the GPIO speed parameter */assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_OD;break;/* If we are configuring the pin in INPUT (also applicable to EVENT and IT mode) */case GPIO_MODE_INPUT:case GPIO_MODE_IT_RISING:case GPIO_MODE_IT_FALLING:case GPIO_MODE_IT_RISING_FALLING:case GPIO_MODE_EVT_RISING:case GPIO_MODE_EVT_FALLING:case GPIO_MODE_EVT_RISING_FALLING:/* Check the GPIO pull parameter */assert_param(IS_GPIO_PULL(GPIO_Init->Pull));if (GPIO_Init->Pull == GPIO_NOPULL){config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_FLOATING;}else if (GPIO_Init->Pull == GPIO_PULLUP){config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;/* Set the corresponding ODR bit */GPIOx->BSRR = ioposition;}else /* GPIO_PULLDOWN */{config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;/* Reset the corresponding ODR bit */GPIOx->BRR = ioposition;}break;/* If we are configuring the pin in INPUT analog mode */case GPIO_MODE_ANALOG:config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_ANALOG;break;/* Parameters are checked with assert_param */default:break;}//code..................
}

这些功能太复杂,我们只分析怎么把传入的参数变成输出引脚
他根据mode,来进行具体的设置:
在这里插入图片描述
然后他把数据存储到了config变量中
在这里插入图片描述
接下来我们看MODIFY_REG,修改寄存器,他需要修改指定寄存器,并且其他寄存器不被破坏

#define MODIFY_REG(REG, CLEARMASK, SETMASK)  WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))

在这里WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))他要写寄存器REG
他写什么呢,首先把寄存器的值读出来,& (~(CLEARMASK))清除掉某些位 | (SETMASK)设置某些位,这样就达到了修改寄存器且不破坏其他位

在这里:configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;他会去确定某个寄存器


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/689048.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

05.QT坐标系

1. 坐标系原点 坐标系原点就是屏幕/窗口的左上角&#xff0c;X向右增长&#xff0c;Y向下增长。 2.设置控件位置 设置控件位置&#xff0c;就相当于是需要指定控件的坐标&#xff0c;对于该控件来说&#xff0c;其坐标原点是其父窗口/父控件的左上角。 设置方法就是通过控件的…

C++ Webserver从零开始:配置环境(九)——下载github的项目进行测试

前言 大家好&#xff0c;我又来更新Webserver的博客了。上一次更新这个专栏时2024.2.5号&#xff0c;离现在已经13天了。非常抱歉&#xff0c;中间隔了那么久。一方面是基础知识学完之后&#xff0c;就要开始自己写代码了。看基础知识和写代码是两回事&#xff0c;理论和实践的…

BUGKU-WEB 变量1

题目描述 题目截图如下&#xff1a; 进入场景看看&#xff1a; flag In the variable !<?php error_reporting(0); include "flag1.php"; highlight_file(__file__); if(isset($_GET[args])){$args $_GET[args];if(!preg_match("/^\w$/",$args…

数据库概述、部署MySQL服务、必备命令 、密码管理、安装图形软件、SELECT语法 、筛选条件

目录 1 案例1&#xff1a;构建MySQL服务器 1.1 问题 1.2 方案 1.3 步骤 2 案例2&#xff1a;密码管理 2.1 问题 2.2 步骤 3 案例3&#xff1a;安装图形软件 3.1 问题 3.2 方案 3.3 步骤 4 案例4&#xff1a;筛选条件 4.1 问题 4.2 方案 4.3 步骤 1 案例1&#x…

AcWing 1050 鸣人的影分身(复杂DP ——整数划分问题)

[题目概述] 在火影忍者的世界里&#xff0c;令敌人捉摸不透是非常关键的。 我们的主角漩涡鸣人所拥有的一个招数——多重影分身之术——就是一个很好的例子。 影分身是由鸣人身体的查克拉能量制造的&#xff0c;使用的查克拉越多&#xff0c;制造出的影分身越强。 针对不同的作…

【Linux】进程的初步认识(二)

进程的初步认识 前言查看进程通过系统调用创建进程关于创建进程的几点补充 前言 之前的一篇文章(文章链接)已经初步对于进程有了一个认识&#xff0c;这篇文章主要是介绍如何去查看进程的相关信息以及创建一个进程的相关知识 查看进程 查看进程的信息可以在/proc系统文件夹中查…

代码随想录刷题笔记-Day19

1. 二叉搜索树的最小绝对差 530. 二叉搜索树的最小绝对差https://leetcode.cn/problems/minimum-absolute-difference-in-bst/ 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的绝…

ZigBee学习——基于AF的数据通信

文章目录 一、简单描述符1.1 简单介绍1.2 简单描述结构体介绍1.3 结构体中的簇1.4 应用场景 二、AF通信原理2.1 通信过程2.2 端点号分类2.3 通信方式2.4 注册简单描述符 三、数据发送API简介3.1 AF层数据发送API3.2 基于AF层封装的通信API3.2.1 点对点通信API3.2.2 广播通信API…

数据库管理-第151期 Oracle Vector DB AI-03(20240218)

数据库管理151期 2024-02-18 数据库管理-第151期 Oracle Vector DB & AI-03&#xff08;20240218&#xff09;1 向量数据库应用场景2 Oracle Vector DB3 Vector数据类型4 Vector运算5 Vector DML插入向量获取向量 总结 数据库管理-第151期 Oracle Vector DB & AI-03&am…

LeetCode 热题 100 Day01

哈希模块 哈希结构&#xff1a; 哈希结构&#xff0c;即hash table&#xff0c;哈希表|散列表结构。 图摘自《代码随想录》 哈希表本质上表示的元素和索引的一种映射关系。 若查找某个数组中第n个元素&#xff0c;有两种方法&#xff1a; 1.从头遍历&#xff0c;复杂度&#xf…

【Spring】三级缓存

目录标题 触发所有未加载的实例a - 开始getBean&#xff08; doGetBean&#xff09; - 获取单例beangetSingleton() - 获取单例beancreateBean&#xff08;doCreateBean&#xff09; - 创建beancreateBeanInstance - 创建并返回beanaddSingletonFactory -放三级缓存populateBea…

序列发生器

一开始想直接FSM&#xff0c;划分出6状态依次输出对应的。但其实只要6比特的移位寄存器&#xff0c;每次输出高位。复位后的默认值时6’b001_011。这样就可以实现循环&#xff0c;这种移位寄存器也叫barrel_shifter。循环移位。也可以使用循环计数器&#xff0c;然后case计数器…

<爬虫Error篇>:乱码问题

前言: 当涉及到网页编码问题时&#xff0c;经常会遇到不同页面使用不同编码方式的情况。这可能导致在解析页面时出现乱码&#xff0c;使我们无法正确获取页面内容 正文: 网页的编码问题: 在处理网页编码问题之前&#xff0c;我们需要了解一些基础知识。网页中的编码方式通常…

JRT监听-PDF-Excel-Img

依赖全新设计&#xff0c;我们无需再顾虑历史兼容性的束缚&#xff1b;同时&#xff0c;基于多年来累积的深入需求理解&#xff0c;JRT监听机制巧妙地借助CMD命令模式&#xff0c;达成了监听的全面统一。无论是PDF、Excel还是图片文件&#xff0c;都不再需要特殊对待或额外区分…

MT8781核心板_MTK8781安卓核心板规格参数

MT8781安卓核心板以其强大的性能和高效的能耐备受瞩目。其八核CPU架构包括(2x Cortex-A76 2.2GHz 6x Cortex-A55 2.0GHz)&#xff0c;以及高性能的Arm Mali G57级GPU。同时&#xff0c;配备高达2,133MHz的LPDDR4X内存和快速的UFS 2.2级存储&#xff0c;大大加速了数据访问速…

java面试集合篇

上面是java中集合的整体框架图。 集合使用的数据结构 算法复杂度分析 时间复杂度分析 时间复杂度分析&#xff1a;来评估代码的执行耗时的 /*** 求1~n的累加和* param n* return*/ public int sum(int n) {int sum 0;for ( int i 1; i < n; i) {sum sum i;}return …

ubuntu22.04-磁盘管理-虚拟机动态扩容-系统monitor

文章目录 1.虚拟机2.ubuntu设置3.命令查看4.系统资源管理器 1.虚拟机 关闭ubuntu22.04&#xff0c;然后修改虚拟机设置&#xff0c;如下图所示&#xff1a; 修改容量 2.ubuntu设置 搜索打开disks&#xff0c;如下图所示&#xff1a; 选择目标磁盘&#xff0c;选择调整大小…

Filterajax

1.Filter概念 概念:表示过滤器,是JavaWeb三大组件(Servlet,Filter,Listener)之一;过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能.过滤器可以完成一些通用操作比如:登录添加购物车,视频广告,敏感字符处理等等... 2.Filter快速入门 3.Listener 4.Ajax学习 1.使用场…

Android 15 第一个开发者预览版

点击查看&#xff1a;first-developer-preview-android15 点击查看&#xff1a;Get Android 15 2024年2月16日,谷歌发布 Android 15 第一个开发者预览版 翻译 由工程副总裁戴夫伯克发布 今天&#xff0c;我们发布了Android 15的首个开发者预览版&#xff0c;这样我们的开发者就…

腾讯云OSS文件上传功能

腾讯云COS介绍 腾讯云COS&#xff08;Cloud Object Storage&#xff09;是一种基于对象的存储服务&#xff0c;用于存储和管理海量的非结构化数据&#xff0c;如图片、音视频文件、备份数据等。它具有以下特点和优势&#xff1a; 高可靠性&#xff1a;采用分布式存储架构&…