从单片机的启动说起一个单片机到点灯发生了什么下——使用GPIO点一个灯

目录

前言

HAL库对GPIO的抽象

核心分析:HAL_GPIO_Init

前言

我们终于到达了熟悉的地方,对GPIO的初始化。经过漫长的铺垫,我们终于历经千辛万苦,来到了这里。关于GPIO的八种模式等更加详细的细节,由于只是点个灯,我们不做所有的分析。

HAL库对GPIO的抽象

HAL库对GPIO的抽象可以说是到了一个巅峰。使能一个GPIO,被化简到了一个非常显然的步骤。

  • 使能对应GPIO所在的Port的时钟

  • 设置GPIO对应的模式——点灯的时候,我们是推挽强力的控制外设

  • 使用HAL_GPIO_Init函数注册到寄存器当中

  • 做一些Post Init工作。比如说,我们明确的要求拉高拉低GPIO。这个,需要根据外设电路来实现

以我板子上外接的PA9作为一个例子把!

static void __open_gpioclk(){__HAL_RCC_GPIOF_CLK_ENABLE();
}
​
CCGPIOInitTypeDef led0_init = {.type = {.Pin    = GPIO_PIN_9,.Mode   = GPIO_MODE_OUTPUT_PP,.Speed  = GPIO_SPEED_HIGH,.Pull   = GPIO_PULLUP},.open_clock = __open_gpioclk,.post_init  = __post_init,.port = GPIOF
};
​
void configure_ccgpio(CCGPIOType* type,  CCGPIOInitTypeDef* initer)
{type->port = initer->port;type->pinType = initer->type.Pin;
​// oh shit, the open clock is missing initediniter->open_clock ? initer->open_clock() : __die();
​HAL_GPIO_Init(type->port, &initer->type);
​if(initer->post_init) initer->post_init(type);
}

核心分析:HAL_GPIO_Init

我们只是简单的点个灯,这个函数就可被化简为如下的逻辑

void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)
{uint32_t position;uint32_t ioposition = 0x00U;uint32_t iocurrent = 0x00U;uint32_t temp = 0x00U;
​/* 检查参数 */assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));assert_param(IS_GPIO_PIN(GPIO_Init->Pin));assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
​/* 配置GPIO引脚 */for(position = 0U; position < GPIO_NUMBER; position++){/* 获取IO引脚位置 */ioposition = 0x01U << position;/* 获取当前IO引脚的状态 */iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
​...
​/* 配置引脚为高电平来点亮LED */GPIOx->ODR |= iocurrent; // 设置为高电平}}
}

这就是为什么我们可以使用Pin9 | Pin10完成我们的组操作,因为内部,我们是逐个比特的完成我们对GPIO的设置,对于每一个满足——的确是我们要设置的GPIO

  
  if(iocurrent == ioposition){/* --------------------- GPIO模式配置 ------------------------*//* 仅当输出模式时才需要配置 */if(((GPIO_Init->Mode & GPIO_MODE) == MODE_OUTPUT)){/* 配置IO速度 */assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));temp = GPIOx->OSPEEDR;temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2U));temp |= (GPIO_Init->Speed << (position * 2U));GPIOx->OSPEEDR = temp;
​/* 配置IO输出类型 */temp = GPIOx->OTYPER;temp &= ~(GPIO_OTYPER_OT_0 << position);temp |= (((GPIO_Init->Mode & OUTPUT_TYPE) >> OUTPUT_TYPE_Pos) << position);GPIOx->OTYPER = temp;
​/* 配置IO输出模式 */temp = GPIOx->MODER;temp &= ~(GPIO_MODER_MODER0 << (position * 2U));temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2U));GPIOx->MODER = temp;}

也就是说,设置我们的输出类型是下面的:

  • 上拉是指在GPIO引脚与电源(通常是3.3V或5V)之间连接一个电阻,这样当引脚处于输入状态时,如果没有外部信号驱动该引脚,它会自动被拉到高电平。也就是被高电平拽上去了!

  • 下拉是指在GPIO引脚与地(0V)之间连接一个电阻,这样当引脚处于输入状态时,如果没有外部信号驱动该引脚,它会自动被拉到低电平。也就是被低电平拽下去了!

  • 无上下拉配置意味着不连接任何上拉或下拉电阻。当GPIO引脚处于输入模式时,它的电平状态将取决于外部电路。如果没有外部驱动信号,这个引脚将处于浮空状态(Hi-Z),可能会导致电平不稳定,容易受到噪声干扰。

中的一种。至于GPIO的速度,则是分为低速中速高速。我们的输出模式大致分两种:

  • 推挽输出(Push-pull):这种输出类型意味着GPIO引脚可以驱动电流流向负载,并且在输出高电平和低电平时都会主动提供电流。即引脚会主动拉高电平和拉低电平。它是最常用的输出类型。

  • 开漏输出(Open-drain):这种输出类型意味着GPIO引脚只有在输出低电平时才会提供电流(拉低电平),而在输出高电平时,它不会输出电流,而是处于高阻态(Hi-Z)。通常需要外部上拉电阻来将引脚拉到高电平。你会在使用软件IIC的时候,再看到它。

所以,笔者按照给出的这个原理图:配置为上拉的情况,确保初始化后不会立马被点亮。

很好,现在,我们终于来到了点灯!

set_ccgpio_state(&led0, CCGPIO_LOW);
​
void set_ccgpio_state(CCGPIOType* type, CCGPIOState state)
{HAL_GPIO_WritePin(type->port, type->pinType, (state ? (GPIO_PIN_SET) : (GPIO_PIN_RESET)));
}

此时此刻,我们的GPIO就会被拉到低,形成一个高低的电压差,存在的电流就把我们的LED导通了!

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

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

相关文章

ESP32S3:解决RWDT无法触发中断问题,二次开发者怎么才能使用内部RTC看门狗中断RWDT呢?

目录 基于ESP32S3:解决RWDT无法触发中断问题引言解决方案1. 查看报错日志2. 分析报错及一步一步找到解决方法3.小结我的源码基于ESP32S3:解决RWDT无法触发中断问题 引言 在嵌入式系统中,RWDT(看门狗定时器)是确保系统稳定性的重要组件。然而,在某些情况下,RWDT可能无法…

对计算机中缓存的理解和使用Redis作为缓存

使用Redis作为缓存缓存例子缓存的引入 Redis缓存的实现 使用Redis作为缓存 缓存 ​什么是缓存&#xff0c;第一次接触这个东西是在考研学习408的时候&#xff0c;计算机组成原理里面学习到Cache缓存&#xff0c;用于降低由于内存和CPU的速度的差异带来的延迟。它是在CPU和内存…

vue3的实用工具库@vueuse/core

1.什么是vueuse/core 是一个基于 ‌Vue Composition API‌ 开发的实用工具库&#xff0c;旨在通过封装高频功能为可复用的组合式函数&#xff08;Composables&#xff09;&#xff0c;简化 Vue 应用的开发流程。 提供 ‌200 开箱即用的函数‌&#xff0c;覆盖状态管理、浏览器…

基于SSM的《计算机网络》题库管理系统(源码+lw+部署文档+讲解),源码可白嫖!

摘 要 《计算机网络》题库管理系统是一种新颖的考试管理模式&#xff0c;因为系统是用Java技术进行开发。系统分为三个用户进行登录并操作&#xff0c;分别是管理员、教师和学生。教师在系统后台新增试题和试卷&#xff0c;学生进行在线考试&#xff0c;还能对考生记录、错题…

C++初阶——简单实现stack和queue

目录 1、Deque(了解) 1.1 起源 1.2 结构 1.3 优缺点 1.4 应用 2、Stack 3、Queue 4、Priority_Queue 注意&#xff1a;stack&#xff0c;queue&#xff0c;priority_queue是容器适配器(container adaptor) &#xff0c;封装一个容器&#xff0c;按照某种规则使用&#…

第2课 树莓派镜像的烧录

树莓派的系统通常是安装在SD卡上的‌。SD卡作为启动设备,负责启动树莓派并加载操作系统。这种设计使得树莓派具有便携性和灵活性,用户可以通过更换SD卡来更换操作系统或恢复出厂设置。 烧录树莓派的镜像即是将树莓派镜像烧录到SD卡上,在此期间会格式化SD卡,如果SD卡…

【Unity】URP管线Shader编程实例详解 (1) : 漩涡效果shader

作者说 本系列教程适用于有编程基础和图形学基础知识的读者.如果对您有所帮助&#xff0c;请点个免费的赞和关注&#xff0c;您的支持就是我更新最大的动力&#xff01;如果你有任何想看的内容欢迎评论区留言&#xff01;本系列教程Github : https://github.com/Sky0Master/Un…

如何安装vm 和centos

安装 VMware Workstation&#xff08;以 Windows 系统为例&#xff09; 1. 下载 VMware Workstation 打开 VMware 官方网站&#xff08;Desktop Hypervisor Solutions | VMware &#xff09;&#xff0c;在页面中选择适合你系统的版本进行下载。如果你是个人非商业使用&#x…

STM32-心知天气项目

一、项目需求 使用 ESP8266 通过 HTTP 获取天气数据&#xff08;心知天气&#xff09;&#xff0c;并显示在 OLED 屏幕上。 按键 1 &#xff1a;循环切换今天 / 明天 / 后天天气数据&#xff1b; 按键 2 &#xff1a;更新天气。 二、项目框图 三、cjson作用 https://gi…

Wireshark简单教程

1.打开Wireshark,点击最上面栏目里面的“捕获”中的“选项” 2.进入网卡选择界面,选择需要捕获的选择&#xff0c;这里我选择WLAN 3.双击捕获选择出现下面界面 4.点击如下图红方框即可停止捕获 5.点击下图放大镜可以进行放大 6.你也可以查询tcp报文如下图

【Http和Https区别】

概念&#xff1a; 一、Http协议 HTTP&#xff08;超文本传输协议&#xff09;是一种用于传输超媒体文档&#xff08;如HTML&#xff09;的应用层协议&#xff0c;主要用于Web浏览器和服务器之间的通信。http也是客户端和服务器之间请求与响应的标准协议&#xff0c;客户端通常…

Unity Shader 学习13:屏幕后处理 - 使用高斯模糊的Bloom辉光效果

目录 一、基本的后处理流程 - 以将画面转化为灰度图为例 1. C#调用shader 2. Shader实现效果 二、Bloom辉光效果 1. 主要变量 2. Shader效果 &#xff08;1&#xff09;提取较亮区域 - pass1 &#xff08;2&#xff09;高斯模糊 - pass2&3 &#xff08;3&#xff…

【R语言】dplyr包经典函数summarise函数

dplyr包经典函数summarise函数&#xff0c;后面改名乘reframe函数了&#xff0c;但是summarise仍然适用 这个函数的返回结果是一个新的数据框&#xff0c;下面讲一下几种常见用法 示例数据为R自带的数据集mtcars 1.不分组 mtcars %>%summarise(mean mean(disp), n n()…

使用DeepSeek/ChatGPT等AI工具辅助编写wireshark过滤器

随着deepseek,chatgpt等大模型的能力越来越强大&#xff0c;本文将介绍借助deepseek&#xff0c;chatgpt等大模型工具&#xff0c;通过编写提示词&#xff0c;辅助生成全面的Wireshark显示过滤器的能力。 每一种协议的字段众多&#xff0c;流量分析的需求多种多样&#xff0c;…

vscode设置自动换行

vscode设置自动换行 方法 方法 点击文件->首选项->设置。搜索word wrap -> 选择 on 。 搜索Word Wrap&#xff0c;并把选项改为on。

QT 中的元对象系统(一):元对象和元数据

目录 1.为什么需要元系统 2.元数据 3.模拟元对象系统 3.1.元对象声明 3.2.对C扩展 3.3初始化元对象 3.4.使用元对象 4.QT的元系统 4.1.元对象系统基于QObject类、Q_OBJECT宏、元对象编译器MOC实现 4.2.元对象系统的功能 4.3.Q_PROPERTY()的使用 4.4.Q_INVOKABLE使用…

Pytorch实现之浑浊水下图像增强

简介 简介:这也是一篇非常适合GAN小白们上手的架构文章!提出了一种基于GAN的水下图像增强网络。这种网络与其他架构类似,生成器是卷积+激活函数+归一化+残差结构的组成,鉴别器是卷积+激活函数+归一化以及全连接层。损失函数是常用的均方误差、感知损失和对抗损失三部分。 …

TCPDF 任意文件读取漏洞:隐藏在 PDF 生成背后的危险

在网络安全的世界里&#xff0c;漏洞就像隐藏在黑暗中的“定时炸弹”&#xff0c;稍有不慎就会引发灾难性的后果。今天&#xff0c;我们要聊的是一个与 PDF 生成相关的漏洞——TCPDF 任意文件读取漏洞。这个漏洞可能让攻击者轻松读取服务器上的敏感文件&#xff0c;甚至获取整个…

【Git】六、企业级开发模型

文章目录 Ⅰ. 前言Ⅱ. 系统开发环境Ⅲ. Git 分支设计规范master分支release分支develop分支feature分支hotfix分支 Ⅰ. 前言 ​ 我们知道&#xff0c;一个软件从零开始到最终交付&#xff0c;大概包括以下几个阶段&#xff1a;规划、编码、构建、测试、发布、部署和维护。 ​…

Kafka可视化工具EFAK(Kafka-eagle)安装部署

Kafka Eagle是什么&#xff1f; Kafka Eagle是一款用于监控和管理Apache Kafka的开源系统&#xff0c;它提供了完善的管理页面&#xff0c;例如Broker详情、性能指标趋势、Topic集合、消费者信息等。 源代码地址&#xff1a;https://github.com/smartloli/kafka-eagle 前置条件…