STM32学习和实践笔记(4): 分析和理解GPIO_InitTypeDef GPIO_InitStructure (a)

深入分析及学习一下上面这一段代码的构成与含义。

首先,这个GPIO_InitTypeDef GPIO_InitStructure;其实与int a 是完全类似的语法格式以及含义。

GPIO_InitStructure就相当于a这样一个变量。不过从这个变量的名字可以知道,这是一个用于GPIO初始化的结构体类型变量而已。

GPIO_InitTypeDef,就相当于int这样的类型声明。不过很明显的,GPIO_InitTypeDef是一个自定义的数据类型。它到底是一个什么样的类型?从后面的跟的这个GPIO_InitStructure,可以大概猜测它是一个结构体类型。

那么通过右键go to define,找到这个GPIO_InitTypeDef的定义如下:

/** * @brief  GPIO Init structure definition  */typedef struct
{uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.This parameter can be any value of @ref GPIO_pins_define */GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.This parameter can be a value of @ref GPIOSpeed_TypeDef */GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;

很明显这是一个结构体。这个结构体本身没有命名,但是通过 type struct{}GPIO_InitTypeDef的方式,将这个结构体类型起了一个别名GPIO_InitTypeDef,这样定义之后,就可以直接使用GPIO_InitTypeDef作为这个结构体类型的声明。

也就是我前面说的,使用GPIO_InitTypeDef GPIO_InitStructure;其实与int a 是完全类似的语法格式以及含义!

跟int a声明后应该给a 赋值一样,GPIO_InitTypeDef GPIO_InitStructure之后,也需要为这个GPIO_InitStructure结构构体变量指明它的值。而这个结构体变量里有三个成员,所以就要分别为这三个成员指定相应的值。

所以后面的:

    GPIO_InitStructure.GPIO_Pin=LED_PIN; 
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;    

就是给这个结构体变量成员分别赋值。

在这个结构体内,有三个成员变量。它们的每一个也其实与int a 是完全类似的语法格式以及含义。

第一个成员变量是uint16_t GPIO_Pin;  

这个uint16_t,是用这个typedef unsigned short     int uint16_t 语句得到一个别名,其含义就是unsigned short     int,这是一个无符号16位整型数据。

GPIO_Pin则是像int a的a一样的变量名称,通过这个名字我们可以了解到,这个变量表示的是GPIO_Pin的引脚。

通过后面的这条注释语句: /*!< Specifies the GPIO pins to be configured.
                                      This parameter can be any value of @ref GPIO_pins_define */

用GPIO_pins_define查找,这个变量取下面这些值才是有意义,有相应的作用:

/** @defgroup GPIO_pins_define 
  * @{
  */

#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 */

#define IS_GPIO_PIN(PIN)   ((((PIN) & (uint16_t)0x00) == 0x00) && ((PIN) != (uint16_t)0x00))

#define IS_GET_GPIO_PIN(PIN)   (((PIN) == GPIO_Pin_0) || \
                              ((PIN) == GPIO_Pin_1) || \
                              ((PIN) == GPIO_Pin_2) || \
                              ((PIN) == GPIO_Pin_3) || \
                              ((PIN) == GPIO_Pin_4) || \
                              ((PIN) == GPIO_Pin_5) || \
                              ((PIN) == GPIO_Pin_6) || \
                              ((PIN) == GPIO_Pin_7) || \
                              ((PIN) == GPIO_Pin_8) || \
                              ((PIN) == GPIO_Pin_9) || \
                              ((PIN) == GPIO_Pin_10) || \
                              ((PIN) == GPIO_Pin_11) || \
                              ((PIN) == GPIO_Pin_12) || \
                              ((PIN) == GPIO_Pin_13) || \
                              ((PIN) == GPIO_Pin_14) || \
                              ((PIN) == GPIO_Pin_15))

也就是当GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 ; 时,其实就是将对应的该引脚的寄存器地址给了GPIO_InitStructure.GPIO_Pin,这就表示,选中了GPIO_Pin_0来操作!

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

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

相关文章

界面控件DevExtreme JS ASP.NET Core 2024年度产品规划预览(一)

在本文中我们将介绍今年即将发布的v24.1附带的主要特性&#xff0c;这些特性既适用于DevExtreme JavaScript (Angular、React、Vue、jQuery)&#xff0c;也适用于基于DevExtreme的ASP.NET MVC/Core控件。 注意&#xff1a;本文中列出的功能和特性说明官方当前/预计的发展计划&a…

hcip实验4:gre mgre ppp综合实验

实验拓扑: 实验目的&#xff1a; 1.R5为ISP&#xff0c;只能进行IP地址配置&#xff0c;其所有地址均配为公有IP地址 2.R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证方&#xff1b;R2与R5之间使用ppp的CHAP认证&#xff0c;R5为主认证方;R3与R5之间使用HDLC封装; 3.R1、R…

MQ消息队列详解以及MQ重复消费问题

MQ消息队列详解以及MQ重复消费问题 1、解耦2、异步调用3、流量削峰4、MQ重复消费问题&#xff0c;以及怎么解决&#xff1f;4.1、重复消费产生4.2、解决方法&#xff1a; https://blog.csdn.net/qq_44240587/article/details/104630567 核心的就是&#xff1a;解耦、异步、削锋…

当面试官问你插入排序算法,你敢说自己会吗?

算法学习的重要性 在程序员的世界里&#xff0c;算法就如同一座桥梁&#xff0c;连接着问题与解决方案&#xff0c;是实现优秀程序的关键。 掌握算法&#xff0c;就能够在面对各种问题时&#xff0c;找到最合适的解决方法&#xff0c;以最少的时间和空间&#xff0c;实现最优的…

解析基础设施即代码:重新定义云管理

由于现代架构、应用程序接口和相互关联的服务之间的互联性越来越强&#xff0c;云基础设施的复杂性也与日俱增。随着需要管理的云资源数量不断增加&#xff0c;企业开始采用基础设施即代码&#xff08;IaC&#xff09;来解决云应用的复杂性和相互依赖性问题。 IaC 提供各种工具…

《深入探索 Netty 框架:构建高效稳定的网络应用》

大家好&#xff0c;今天我将为大家深入介绍 Netty 框架&#xff0c;并分享一些基于 Java 实现的代码示例。 Netty 是一个非常强大的网络框架&#xff0c;它提供了一种高效、可靠的方式来构建网络应用程序。它具有以下优点&#xff1a; 高性能&#xff1a;通过优化的 IO 处理和线…

波长可调激光器中的增益芯片和SOA

----翻译自SATO Kenji&#xff0c;ZHANG Xiaobo于2019年发表的文章 摘要&#xff1a; 本文讨论了用于波长可调激光器&#xff08;TL&#xff09;的半导体光放大器&#xff08;SOA&#xff09;和增益芯片的设计规则。即与常规SOA或激光器相似&#xff0c;也有一些不同之处。位…

酷开科技不断深耕智能电视领域,用酷开系统带给消费者更多可能性

在这个网络快速发展的时代&#xff0c;电视行业也发生了巨大变革。与以往单纯的“看”电视不同&#xff0c;人们不再满足于现有的状态&#xff0c;消费者对电视娱乐的追求更加丰富&#xff0c;这也就带给智能电视产业无限的发展可能。酷开科技瞄准这一产业趋势&#xff0c;不断…

家庭影院触摸屏中应用的电容式触摸芯片

家庭影院的主要组成部分包括显示设备、音响设备、信号源和接线设备等。其中&#xff0c;显示设备通常采用高清电视或投影仪&#xff0c;音响设备包括功放、音箱、低音炮等&#xff0c;信号源可以是蓝光光盘、游戏机、有线电视、网络电视等多种媒体设备。 家庭影院的影像信号通…

[C#]winform使用OpenCvSharp实现透视变换功能支持自定义选位置和删除位置

【透视变换基本原理】 OpenCvSharp 是一个.NET环境下对OpenCV原生库的封装&#xff0c;它提供了大量的计算机视觉和图像处理的功能。要使用OpenCvSharp实现透视变换&#xff08;Perspective Transformation&#xff09;&#xff0c;你首先需要理解透视变换的原理和它在图像处理…

vulhub打靶记录——healthcare

文章目录 主机发现端口扫描FTP—21search ProPFTd EXPFTP 匿名用户登录 web服务—80目录扫描search openemr exp登录openEMR 后台 提权总结 主机发现 使用nmap扫描局域网内存活的主机&#xff0c;命令如下&#xff1a; netdiscover -i eth0 -r 192.168.151.0/24192.168.151.1…

适配器模式:桥接不兼容的接口

在软件开发中&#xff0c;我们经常会遇到需要将现有的类与新的系统或客户端集成的情况&#xff0c;但这些类可能因为接口不兼容而无法直接使用。适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许不兼容的接口之间能够相互协作&#x…

css预编译sass,css也可以变得优雅

1. 嵌套选择器 #content {article {h1 { color: #333 }p { margin-bottom: 1.4em }}aside { background-color: #EEE } }编译后 #content article h1 { color: #333 } #content article p { margin-bottom: 1.4em } #content aside { background-color: #EEE }2. 变量声明和使…

力扣贪心算法--第一天

前言 今天是贪心算法的第一天&#xff0c;算法之路重新开始&#xff01; 内容 之前没了解过贪心算法。 什么是贪心 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。难点就是如何通过局部最优&#xff0c;推出整体最优。 一、455.分发饼干 假设你是一…

题目:学习static定义静态变量的用法

题目&#xff1a;学习static定义静态变量的用法    There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about being cheate…

JS中的运算符

1.&& 逻辑与 &&会从左到右执行表达式&#xff0c;直到某个表达式的运行结果返回false,如果全部为true,则返回最后一个中表达式的执行结果 console.log(1 && 2) // 2 console.log(1&&10&&15) // 15 console.log(1&&0&&am…

Android的图片加载框架

Android的图片加载框架 为什么要使用图片加载框架&#xff1f;图片加载框架1. Universal Image Loader [https://github.com/nostra13/Android-Universal-Image-Loader](https://github.com/nostra13/Android-Universal-Image-Loader)2. Glide [https://muyangmin.github.io/gl…

每日一题 --- 用栈实现队列[力扣][Go]

用栈实现队列 题目&#xff1a;用栈实现队列 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾int pop() 从队列…

MySQL的多层SP中Cursor的m_max_cursor_index相关BUG分析

源码分析丨MySQL的多层SP中Cursor相关BUG 一、问题发现 在一次开发中在sp中使用多层cursor的时候想知道每层的m_max_cursor_index值分别是多少&#xff0c;以用来做后续开发。于是做了以下的试验&#xff0c;但是发现第一个level2那层的m_max_cursor_index的值有点问题。 注&…

威胁建模与网络安全测试方法

文章目录 1.软件安全的开发背景1.1软件发展与安全问题系统软件问题应用软件问题第三方代码安全新技术安全1.2 软件安全问题产生的原因1.3 漏洞修复的成本运行阶段发布阶段测试阶段研发阶段2.常见的软件安全开发方法2.1 开发方法2.2 什么是SDL2.3 微软SDL发展历史2.4 微软SDL安全…