细说ARM MCU中的MX_GPIO_Init()函数的实现过程

目录

1、建立.ioc工程

2、 MX_GPIO_Init()函数

(1)MX_GPIO_Init()函数的类型

(2)MX_GPIO_Init()函数中用到的结构体变量

(3)MX_GPIO_Init()函数使能时钟

(4)MX_GPIO_Init()函数配置GPIO


        本文中使用ST的开发板NUCLEO-G474RE,板上MCU型号为STM32G474RET6。配套的扩展板:

        实例中当开发板上的按键B1被按下时,PC13引脚被上拉至高电平VDD,不按下时,PC13下拉至低电平GND。用按键B1控制板上的LD2灯的亮灭,当PA5输出高电平时LD2亮,否则灯灭。

1、建立.ioc工程

        根据上述信息,建立工程,具体操作,略。

2、 MX_GPIO_Init()函数

        系统自动生成代码后,打开main.c。因为工程配置了2个GPIO,一个作为输入,另一个作为输出。MX_GPIO_Init()定义如下:

static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* USER CODE BEGIN MX_GPIO_Init_1 *//* USER CODE END MX_GPIO_Init_1 *//* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOF_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);/*Configure GPIO pin : KEY_Pin */GPIO_InitStruct.Pin = KEY_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLDOWN;HAL_GPIO_Init(KEY_GPIO_Port, &GPIO_InitStruct);/*Configure GPIO pin : LED0_Pin */GPIO_InitStruct.Pin = LED0_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(LED0_GPIO_Port, &GPIO_InitStruct);/* USER CODE BEGIN MX_GPIO_Init_2 *//* USER CODE END MX_GPIO_Init_2 */
}

(1)MX_GPIO_Init()函数的类型

        从上面的定义可知,函数MX_GPIO_Init()的类型为void,不返回任何值。不过在void前加了一个static,表示该函数只能在定义它的文件中可见。对于MX_GPIO_Init()函数,只能在main.c中可见。实际上,该函数只置用于设置GPIO的参数,别的地方也用不到。

(2)MX_GPIO_Init()函数中用到的结构体变量

        其中,第一句定义了一个结构体变量GPIO_InitStruct,结构体名称为GPIO_InitTypeDef。这个结构体的声明是在固件库的stm32g4xx_hal_gpio.h文件中:

typedef struct
{unint32_t Pin:unint32_t Mode;unint32_t Pull;unint32_t Speed;unint32_t Alternate;
}GPIO_IniyTypeDef;

        GPIO_InitTypeDef在这里是结构体名称,并不是一个结构体变量,所以在使用该结构体类型时,还需要定义变量。结构体GPIO_InitTypeDef中有5个成员。

  • 成员Pin

        成员Pin实际就是引脚号,譬如GPIO_PIN_0~GPIO_PIN_15等。这些引脚号也是数值,在stm32g4xx_hal_gpio.h中有定义:

#define GPIO_PIN_0  ((uint16_t)0x0001) //第1个引脚
......
#define GPIO_PIN_15 ((uint16_t)0x8000) //第16个引脚
#define GPIO_PIN_All ((uint16_t)0xFFFF)//所有引脚

        在这些define宏定义中,引脚号定义为uint16_t类型,而在结构体GPIO_InitTypeDef中,成员Pin定义为uint32_t。由此可见,在给32位的结构体变量赋值时,实际赋的是16位数。

        实际上STM32G4系列MCU的GPIO寄存器,都是32位的,但有的寄存器只是低16位有效。

  • 成员Mode

        成员Mode是指输入、输出等模式。例如:

输入模式:GPIO_MODE_INPUT;
推挽输出模式:GPIO_MODE_OUTPUT_PP;
开漏输出模式:GPIO_MODE_OUTPUT_OD。

        当然还有一些响应外部中断和外部事件的模式,此处暂时略过。

  • 成员Pull

        成员Pull是用于配置上拉、下拉功能的。例如:

不用上拉下拉:GPIO_NOPULL;
上拉:GPIO_PULLUP;
下拉:GPIO_PULLDOWN。
  • 成员Speed

        成员Speed用于配置GPIO速度,有4个挡位。例如:

低速:GPIO_GPIO_SPEED_FREQ_LOW,最高5MHz;
中速:GPIO_SPEED_FREQ_MEDIUM,5~25 MHz;
高速:GPIO_SPEED_FREQ_HIGH,25~50 MHz;
很高速:GPIO_SPEED_FREQ_VERY_HIGH,50~120 MHz。
  • 成员Alternate

        成员 Alternate涉及引脚复用功能。

       继续,看MX_GPIO_Init()函数的定义,第一条语句是给变量GPIO_InitStruct赋值,等号右侧为{0},意思是将结构体中的所有成员都初始化为0。

(3)MX_GPIO_Init()函数使能时钟

        接下来是三条时钟使能语句,分别使能GPIOC、GPIOF和GPIOA的时钟。使能GPIOF是因为外接晶体用到了GPIOF端口。

(4)MX_GPIO_Init()函数配置GPIO

        因为配置了PA5作为输出,所以接下来的一条语句是初始化PA5的输出状态,用的是GPIO_PIN_RESET,即将其初始化为低电平输出。

        随后,分别对PC13(KEY)和PA5(LED)进行配置。由于已经定义了一个结构体变量GPIO_InitStruct,所以这里需要先给其中的成员赋值:

GPIO_InitStruct.Pin =KEY_Pin;
GPIO_InitStruct.Mode =GPIO_MODE_INPUT;
GPIO_InitStruct.Pull =GPIO_PULLDOWN;

        在这三条语句中,访问结构体成员变量用的是“.”。

      至此,这只是通过结构体变量给成员赋值,还不会作用到硬件(GPIO寄存器)来,调用HAL_GPIO_Init函数,将结构体变量的信息传递过来并作用到相关GPIO寄存器中。所用语句如下:

HAL_GPIO_Init(KEY_GPIO_Port,&GPIO_InitStruct);

        HAL_GPIO_Init函数有两个参数:一个是端口KEY_GPIO_Port,也就是GP个是已经给结构体成员赋值的结构体变量GPIO_InitStruct,注意在结构体变量前要后面的代码是用类似的方式初始化PA5。

        关于HAL_GPIO_Init函数的解析,请看本文作者的其他文章。

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

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

相关文章

vue3学习使用笔记

1.学习参考资料 vue3菜鸟教程:https://www.runoob.com/vue3/vue3-tutorial.html 官方网站:https://cn.vuejs.org/ 中文文档: https://cn.vuejs.org/guide/introduction.html Webpack 入门教程:https://www.runoob.com/w3cnote/webpack-tutor…

Proteus 安装报错There is a problem with this Windows lnstaller package

Proteus 安装常见问题 1.安装秘钥(许可证)的时候报错 报错信息如下所示: There is a problem with this Windows lnstaller package. A program required for this instalt to compiete coutd notbe run,contact your support personnet or packagevendor. 这个是…

在Ubuntu乌班图上安装Docker

最近在学习乌班图相关的内容,找了一些文档安装的都是报错的,于是记录一下学习过程,希望也能帮助有缘人,首先查看乌班图的系统版本,我的是如下的: cat /proc/version以下是在Ubuntu 20.04版本上安装Docker。…

Apache Druid 代码执行(CVE-2021-25646)漏洞复现

Druid简介与漏洞成因 Apache Druid是一个高性能的实时分析型数据库,旨在对大型数据集进行快速查询分析。Druid最常被当做数据库来用以支持实时摄取、高性能查询和高稳定运行的应用场景,同时,Druid也通常被用来助力分析型应用的图形化界面&am…

3---C++之list(逻辑梳理、简单使用演示、部分源码实现)

一、先决知识点1——认识list: list底层实现是双向链表,但是不是循环链表。list是否使用哨兵节点,是细节问题,C标准并未规定。list是链表,他的优势在于对节点的操作会十分灵活,因此它在需要频繁插入和删除元…

【UnityShader入门精要学习笔记】第十六章 Unity中的渲染优化技术 (下)

本系列为作者学习UnityShader入门精要而作的笔记,内容将包括: 书本中句子照抄 个人批注项目源码一堆新手会犯的错误潜在的太监断更,有始无终 我的GitHub仓库 总之适用于同样开始学习Shader的同学们进行有取舍的参考。 文章目录 减少需要处…

德人合科技——天锐绿盾内网安全管理软件 | -文档透明加密模块

天锐绿盾文档加密功能能够为各种模式的电子文档提供高强度加密保护,丰富的权限控制以及灵活的应用管理,帮助企业构建更严密的立体保密体系。 PC地址: https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee ————…

Chatglm3-6b报错处理

目录 AttributeError: ChatGLMTokenizer object has no attribute sp_tokenizer AttributeError: ChatGLMConfig object has no attribute max_sequence_length AttributeError: ChatGLMConfig object has no attribute position_encoding_2d AttributeError: ChatGLMConfi…

BioVendor—sHLA-G ELISA试剂盒

人类白细胞抗原-G (HLA-G)与其他MHC类基因的不同之处在于它的低多态性和产生七种HLA-G蛋白的选择性剪接,这些蛋白的组织分布局限于正常的胎儿和成人组织,这些组织对先天和后天免疫细胞都具有耐受性。可溶性HLA-G是一种免疫抑制分子,诱导活化的…

详细解析Barlow Twins:自监督学习中的创新方法

首先先简单了解一下机器学习中,主要有三种学习范式:监督学习、无监督学习和自监督学习: 监督学习:依赖带标签的数据,通过输入输出映射关系进行训练。无监督学习:不依赖标签,关注数据的内在结构…

pikachu靶场(unsafe upfileupload(文件上传)通关教程)

目录 client check 1.在桌面新建一个文本文档 2.保存为.png格式 3.打开网站 4.按照图中操作 5.点击forward 6.访问 MIME type 1.新建一个php文件,里面写上 2.上传文件,就是我们保存的文件 3.打开抓包工具,点击开始上传 4.修改Conen…

ADC数模转换器

一、ADC(Analog-Digital Converter)模拟-数字转换器 1、ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁 2、12位逐次逼近型ADC,1us转换时间 3、输入电压范围:0~3.3V&a…

20分钟快速入门SQL

SQL(Structured Query Language,结构化查询语言)是一种专门用来管理和操作关系型数据库的编程语言。以下是SQL入门的一些基础概念和教程: 1. SQL基础 数据库(Database):存储数据的集合。表&am…

【K8s】专题四(2):Kubernetes 控制器之 Deployment

以下内容均来自个人笔记并重新梳理,如有错误欢迎指正!如果对您有帮助,烦请点赞、关注、转发!欢迎扫码关注个人公众号! 目录 一、基本介绍 二、工作原理 三、相关特性 四、资源清单(示例) 五…

C-数据结构-平衡二叉树

平衡二叉树(Balanced Binary Tree)是一种二叉树,其中任意节点的两棵子树的高度差不超过 1。也可以说是一棵空树或者左右子树高度差不超过 1 的二叉树。 特点和性质 高度平衡:平衡二叉树是一种高度平衡的二叉树,任意节…

Java进阶指南:高级面试问题与精辟解答(六)

Java 面试问题及答案 1. 请解释 Java 中的多线程概念,并说明如何实现一个简单的多线程程序? 答案: 多线程是 Java 中的一个核心概念,它允许同时执行多个任务,从而提高程序的效率和响应性。在 Java 中,可以…

Golang获取文件名扩展名/后缀

在Go语言中,可以使用path/filepath 标准库中的Ext函数来获取文件的扩展名(也就是后缀)。以下是一个简单的示例代码: package mainimport ("fmt""path/filepath" )func main() {fileName : "example.txt…

【Linux】多线程——线程概念|进程VS线程|线程控制

> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:理解【Linux】多线程——线程概念|进程VS线程|线程控制 > 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早安! &…

产品上市新闻稿怎么写?纯干货

一个产品的上市,想要达到一个非常好的宣传效果,前期的预热造势是必不可少的,投放产品上市新闻稿到权威专业的媒体,潜移默化去影响用户的心智,产品上市新闻稿怎么写?接下来伯乐网络传媒就来给大家分享一下&a…

【WEEK14】学习目标及总结【Spring Boot】【中文版】

学习目标: 学习SpringBoot 学习内容: 参考视频教程【狂神说Java】SpringBoot最新教程IDEA版通俗易懂Shiro Shiro请求授权的实现(后半部分)Shiro整合Thymeleaf Swagger 简介SpringBoot集成Swagger配置扫描接口,配置Sw…