立创·天空星开发板-GD32F407VE-GPIO

本文以 立创·天空星开发板-GD32F407VET6-青春版 作为学习的板子,记录学习笔记。

立创·天空星开发板-GD32F407VE-GPIO

    • 基础概念
      • 三极管
      • MOS管
    • GPIO输出模式
    • 输出线与
    • GPIO输入模式
    • GPIO点灯

基础概念

  • GPIO,全称为“通用输入/输出”(General Purpose Input/Output),是计算机系统中用于与外部世界进行数字通信的一种接口标准。
  • 它允许硬件和软件通过电信号来交换数据,控制外部设备或接收外部事件。
  • GPIO通常用于连接各种外设,如按钮、LED灯、传感器、马达、继电器等,以便与计算机系统进行交互。GD32 支持的 GPIO 模式有如下八种:
模式性质
浮空输入数字输入
上拉输入数字输入
下拉输入数字输入
模拟输入模拟输入
开漏输出数字输出
推挽输出数字输出
复用开漏输出数字输出
复用推挽输出数字输出

三极管

总是记混 NPN 和 PNP 这两种型号的三极管,如下图所示:

三极管原理图对比
特性描述:

  1. 电流关系: I E = I B + I C I_E = I_B + I_C IE=IB+IC
  2. 导通条件: NPN型的基极比发射极电压高0.7v,PNP型的基极比发射极电压低0.7v
  3. 设计原理图: 无论是 NPN 还是 NPN 型的三极管,耗电元器件都需要接在集电极

助记小技巧:

  1. 电路图中,箭头永远指向的 N 极,根据箭头可快速确认是 NPN 还是 PNP
  2. 电路图中,箭头对应的极比箭尾对应的极的电压要低

思维导图:

三极管思维导图

MOS管

MOS管有 NMOS 和 PMOS 两种类型。MOS管包含了三个极:

  • 栅极(G),对应英文单词:Gate
  • 漏极(D),对应英文单词:Drain
  • 源极(S),对应英文单词:Source

MOS管的作用就是开关,通过栅极控制漏极和源极的导通。主要关注两个点:

  1. 控制:负责MOS管导通和截止,高电平导通还是低电平导通。
  2. 流向:是从漏极流向源极,还是从源极流向漏极。

MOS管和三级管主要区别:三极管导通有电流,而MOS管导通没有电流(有点像继电器)

一张图搞懂 MOS 管,如下所示:
一张图搞懂 MOS 管

如果 Input 为电平,PMOS 断开,NMOS 导通,如果 GPIO_PIN_X 有上拉电阻,则电流可以顺利从 NMOS 的漏极(D)流向源极(S)。
如果 Input 为电平,PMOS 导通,NMOS 断开,如果 GPIO_PIN_X 有下拉电阻,则电流可以顺利从 PMOS 的源极(S)流向漏极(D)。

特点描述:

  • PMOS 的栅极(G)低通高断,导通时,电流方向是源极(S)流向漏极(D)
  • PMOS 可以类比 PNP 类型的三极管
  • NMOS 的栅极(G)高通低断,导通时,电流方向是漏极(D)流向源极(S)
  • NMOS 可以类比 NPN 类型的三极管

思维导图:

MOS管思维导图

GPIO输出模式

  1. 推挽输出
  • 【推】寄存器控制输出高电平时,过非门后变低电平,PMOS导通,外部引脚为高,电流流出

输出高电平

  • 【挽】寄存器控制输出低电平时,过非门后变高电平,NMOS导通,外部引脚为低,电流流入
    输出低电平
  1. 开漏输出
  • 寄存器控制输出低电平时,过非门后变高电平,NMOS导通,外部引脚为低,电流流入

输出低电平

  • 寄存器控制输出高电平时,因为PMOS未接入,所以外部引脚断开。

无法输出高电平

  1. 高阻态
  • 因为 PMOS和 NMOS 均未接入,无论寄存器输出高或者低,外部引脚始终断开。

高阻态

  1. 复用开漏输出 和 复用推挽输出
  • 不经过寄存器来输出高低电平,也就是下图中的 Alternate function output 部分

在这里插入图片描述

输出线与

  1. 推挽线与

推挽过程中,如果一方输出高,一方输出低,则会烧芯片。因此,推挽是不可以线与的。

推挽线与
2. 开漏线与

开漏过程中,无论双方输出高低电平,芯片都不会收到影响。I2C就是线与的一个实例。
开漏线与

GPIO输入模式

  1. 浮空输入
  • 就是将模拟信号、上拉、下拉全部断开,只接收外部电路的输入信号。如下图红色线条所示:
    浮空输入
  1. 上拉输入
  • 过上拉电阻后,经由斯密特触发器,写入寄存器。如下图红色线条所示:
  • 过斯密特后,也可做复用输入,不写入寄存器
    上拉输入
  1. 下拉输入
  • 过下拉电阻后,经由斯密特触发器,写入寄存器。如下图红色线条所示:
  • 过斯密特后,可做复用输入,不写入寄存器
    下拉输入
  1. 模拟输入
  • 不经过斯密特触发器,直接读入。如下图红色线条所示:

模拟输入

GPIO点灯

我用 GPIO 封装了一个可以动态点亮多个 LED 的拓展驱动,针对 PD 端口, 可以动态增加 LED 灯的引脚。只需要修改 LED_PINS 数组的元素即可。

  • ExtendedLED.h
#ifndef __EXTENDED_LED_H__
#define __EXTENDED_LED_H__#include "gd32f4xx.h"
#include "systick.h"#define LED_RCU  RCU_GPIOD
#define LED_PORT GPIOD
#ifndef BIT
#define BIT(x) ((uint16_t)((uint16_t)0x01U<<(x)))
#endif// 声明需要针对的引脚, PDx(x=8...15)
static uint32_t LED_PINS[] = {BIT(8),  BIT(9),  BIT(10), BIT(11),BIT(12), BIT(13), BIT(14), BIT(15)
};/*!\brief    初始化 LED\param[in]  none\param[out] none\retval     none
*/
void extended_led_init();/*!\brief    熄灭所有 LED 灯\param[in]  none\param[out] none\retval     none
*/
void extended_led_turn_off_all();/*!\brief    点亮所有 LED 灯\param[in]  none\param[out] none\retval     none
*/
void extended_led_turn_on_all();/*!\brief    熄灭 LED 灯\param[in]  index[int]: LED 灯在 LED_PINS 数组中的索引, -1 针对所有引脚\param[out] none\retval     none
*/
void extended_led_turn_off(int index);/*!\brief    点亮 LED 灯\param[in]  index[int]: LED 灯在 LED_PINS 数组中的索引, -1 针对所有引脚\param[out] none\retval     none
*/
void extended_led_turn_on(int index);/*!\brief    运行多个共阳 LED 灯示例: extended_led_run(0,  1, 1); 效果为:从第一个灯开始依次亮起, 切灯过程不熄灭其他灯[流水灯]示例: extended_led_run(0,  1, 0); 效果为:从第一个灯开始依次亮起, 切灯过程会熄灭其他灯[跑马灯]示例: extended_led_run(0,  2, 1); 效果为:按 0.2.4.6 顺序依次亮起, 切灯过程不熄灭其他灯[流水灯]示例: extended_led_run(1,  2, 0); 效果为:按 1.3.5.7 顺序依次亮起, 切灯过程会熄灭其他灯[跑马灯]示例: extended_led_run(6, -2, 1); 效果为:按 6.4.2.0 顺序依次亮起, 切灯过程不熄灭其他灯[流水灯]示例: extended_led_run(7, -2, 0); 效果为:按 7.5.3.1 顺序依次亮起, 切灯过程会熄灭其他灯[跑马灯]\param[in]  status  [uint16_t]:     表示灯的状态, 可选值有 (亮:0) 或 (灭:1)\param[in]  start   [uint32_t]:     表示从哪个灯开始亮, 可选值有 0...\param[in]  step    [int16_t] :     表示切灯的时候跨越步长, 可选值有 0...\param[in]  flowing [uint16_t]:     表示切灯的时候是否采用流水灯\param[out] none\retval     none
*/
void extended_led_run(uint16_t status, uint32_t start, int16_t step, uint16_t flowing);#endif
  • ExtendedLED.c
#include "ExtendedLED.h"// 获取 LED 灯的总数
static uint16_t pins_length(void) {return sizeof(LED_PINS) / sizeof(LED_PINS[0]);
}// 获取所有引脚
static uint16_t pins_all(void) {int length = 0, i = 0;length = pins_length();uint16_t pin = (uint16_t)0x00U;for(i = 0; i < length; i++) {pin |= LED_PINS[i];}return pin;
}/*!\brief    初始化 LED\param[in]  none\param[out] none\retval     none
*/
void extended_led_init() {rcu_periph_clock_enable(LED_RCU);gpio_mode_set(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, pins_all());gpio_output_options_set(LED_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, pins_all());gpio_bit_set(GPIOD, pins_all());
}/*!\brief    熄灭所有 LED 灯\param[in]  none\param[out] none\retval     none
*/
void extended_led_turn_off_all() { extended_led_turn_off(-1); }/*!\brief    点亮所有 LED 灯\param[in]  none\param[out] none\retval     none
*/
void extended_led_turn_on_all() { extended_led_turn_on(-1); }/*!\brief    熄灭 LED 灯\param[in]  index[int]: LED 灯在 LED_PINS 数组中的索引, -1 针对所有引脚\param[out] none\retval     none
*/
void extended_led_turn_off(int index) {int length = pins_length();if (index >= length) {return;}if (index < 0) {gpio_bit_set(GPIOD, pins_all());   // 负数针对所有return;}gpio_bit_set(GPIOD, LED_PINS[index]);
}/*!\brief    点亮 LED 灯\param[in]  index[int]: LED 灯在 LED_PINS 数组中的索引, -1 针对所有引脚\param[out] none\retval     none
*/
void extended_led_turn_on(int index) {int length = pins_length();if (index >= length) {return;}if (index < 0) {gpio_bit_reset(GPIOD, pins_all());   // 负数针对所有return;}gpio_bit_reset(GPIOD, LED_PINS[index]);}/*!\brief    运行多个共阳 LED 灯示例: extended_led_run(0,  1, 1); 效果为:从第一个灯开始依次亮起, 切灯过程不熄灭其他灯[流水灯]示例: extended_led_run(0,  1, 0); 效果为:从第一个灯开始依次亮起, 切灯过程会熄灭其他灯[跑马灯]示例: extended_led_run(0,  2, 1); 效果为:按 0.2.4.6 顺序依次亮起, 切灯过程不熄灭其他灯[流水灯]示例: extended_led_run(1,  2, 0); 效果为:按 1.3.5.7 顺序依次亮起, 切灯过程会熄灭其他灯[跑马灯]示例: extended_led_run(6, -2, 1); 效果为:按 6.4.2.0 顺序依次亮起, 切灯过程不熄灭其他灯[流水灯]示例: extended_led_run(7, -2, 0); 效果为:按 7.5.3.1 顺序依次亮起, 切灯过程会熄灭其他灯[跑马灯]\param[in]  status  [uint16_t]:     表示灯的状态, 可选值有 (亮:0) 或 (灭:1)\param[in]  start   [uint32_t]:     表示从哪个灯开始亮, 可选值有 0...\param[in]  step    [int16_t] :     表示切灯的时候跨越步长, 可选值有 0...\param[in]  flowing [uint16_t]:     表示切灯的时候是否采用流水灯\param[out] none\retval     none
*/
void extended_led_run(uint16_t status, uint32_t start, int16_t step, uint16_t flowing) {int length = pins_length();int i = 0;if(start < 0 || start >= length) {start = 0;}if(start + step  >= length) {start = length - 1 - (step - 1);}for(i = start; i < length && i > -1; i += step) {if(status) {// 熄灭指定索引的灯extended_led_turn_off(i);} else {// 点亮指定索引的灯if(!flowing) {// 如果不是流水灯, 每次切灯之前都需要关掉所有灯extended_led_turn_off(-1);delay_1ms(200);}extended_led_turn_on(i);}delay_1ms(200);}
}
  • main.c
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>#include "ExtendedLED.h"int main(void) {systick_config();extended_led_init();extended_led_run(0, 0,  1, 1);extended_led_run(1, 7, -1, 1);extended_led_run(0, 0,  1, 0);extended_led_turn_off_all();while(1) { }
}

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

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

相关文章

算法金 | 这次终于能把张量(Tensor)搞清楚了!

大侠幸会&#xff0c;在下全网同名[算法金] 0 基础转 AI 上岸&#xff0c;多个算法赛 Top [日更万日&#xff0c;让更多人享受智能乐趣] 1. 张量&#xff08;Tensor&#xff09;基础概念 1.1 张量的定义与重要性 张量是深度学习中用于表示数据的核心结构&#xff0c;它可以视…

《帝国时代 III:决定版》秘籍 怎么在苹果电脑上玩《帝国时代 III:决定版》

《帝国时代 III&#xff1a;决定版》是一款让玩家沉浸于历史长河体验从大航海时代到工业革命时期的游戏。下面我们来看看《帝国时代 III&#xff1a;决定版》是什么类型的游戏&#xff0c;《帝国时代 III&#xff1a;决定版》Mac安装教程的相关内容。 一、《帝国时代 III&…

【BOM02】本地存储

一&#xff1a;什么是本地存储 数据存储在用户浏览器中&#xff0c;用户设置、读取方便&#xff0c;同时页面刷新时不会丢失数据。存储在浏览器中数据约5M&#xff0c;分为sessionStorage和localStorage两种存储方式 二&#xff1a;localStorage存储 作用 将数据永久存储在…

opencv实战小结-银行卡号识别

实战1-银行卡号识别 项目来源&#xff1a;opencv入门 项目目的&#xff1a;识别传入的银行卡照片中的卡号 难点&#xff1a;银行卡上会有一些干扰项&#xff0c;如何排除这些干扰项&#xff0c;并且打印正确的号码是一个问题 最终效果如上图 实现这样的功能需要以下几个步骤…

算法导论实战(三)(算法导论习题第二十四章)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;算法启示录 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 前言 第二十四章 24.1-3 24.1-4 2…

【Week-R2】使用LSTM实现火灾预测(tf版本)

【Week-R2】使用LSTM实现火灾预测&#xff08;tf版本&#xff09; 一、 前期准备1.1 设置GPU1.2 导入数据1.3 数据可视化 二、数据预处理(构建数据集)2.1 设置x、y2.2 归一化2.3 划分数据集 三、模型创建、编译、训练、得到训练结果3.1 构建模型3.2 编译模型3.3 训练模型3.4 模…

超详细的java Comparable,Comparator接口解析

前言 Hello大家好呀&#xff0c;在java中我们常常涉及到对象的比较&#xff0c;不同于基本数据类型&#xff0c;对于我们的自定义对象&#xff0c;需要我们自己去建立比较标准&#xff0c;例如我们自定义一个People类&#xff0c;这个类有name和age两个属性&#xff0c;那么问…

[数据集][图像分类]蘑菇分类数据集3122张215类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;3122 分类类别数&#xff1a;215 类别名称:[“almond_mushroom”,“amanita…

实验笔记之——DPVO(Deep Patch Visual Odometry)

本博文记录本文测试DPVO的过程&#xff0c;本博文仅供本人学习记录用~ 《Deep Patch Visual Odometry》 代码链接&#xff1a;GitHub - princeton-vl/DPVO: Deep Patch Visual Odometry 目录 配置过程 测试记录 参考资料 配置过程 首先下载代码以及创建conda环境 git clo…

有待挖掘的金矿:大模型的幻觉之境

人工智能正在迅速变得无处不在&#xff0c;在科学和学术研究中&#xff0c;自回归的大型语言模型&#xff08;LLM&#xff09;走在了前列。自从LLM的概念被整合到自然语言处理&#xff08;NLP&#xff09;的讨论中以来&#xff0c;LLM中的幻觉现象一直被广泛视为一个显著的社会…

Oracle EBS AP发票创建会计科目提示:APP-SQLAP-10710:无法联机创建会计分录

系统版本 RDBMS : 12.1.0.2.0 Oracle Applications : 12.2.6 问题症状: 提交“创建会计科目”请求提示错误信息如下: APP-SQLAP-10710:无法联机创建会计分录。 请提交应付款管理系统会计流程,而不要为此事务处理创建会计分录解决方法 数据修复SQL脚本: UPDATE ap_invoi…

LabVIEW阀性能试验台测控系统

本项目开发的阀性能试验台测控系统是为满足国家和企业相关标准而设计的&#xff0c;主要用于汽车气压制动系统控制装置和调节装置等产品的综合性能测试。系统采用工控机控制&#xff0c;配置电器控制柜&#xff0c;实现运动控制、开关量控制及传感器信号采集&#xff0c;具备数…

算法-分治策略

概念 分治算法&#xff08;Divide and Conquer&#xff09;是一种解决问题的策略&#xff0c;它将一个问题分解成若干个规模较小的相同问题&#xff0c;然后递归地解决这些子问题&#xff0c;最后合并子问题的解得到原问题的解。分治算法的基本思想是将复杂问题分解成若干个较…

计算机网络 期末复习(谢希仁版本)第3章

对于点对点的链路&#xff0c;目前使用得最广泛的数据链路层协议是点对点协议 PPP (Point-to-Point Protocol)。局域网的传输媒体&#xff0c;包括有线传输媒体和无线传输媒体两个大类&#xff0c;那么有线传输媒体有同轴电缆、双绞线和光纤&#xff1b;无线传输媒体有微波、红…

基于Texture2D 实现Unity 截屏功能

实现 截屏 Texture2D texture new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false); texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0); texture.Apply(); 存储 byte[] array ImageConversion.EncodeToPNG(texture); if (!…

分享万能点击器免费版,吾爱大佬出品,这个太赞了!

小伙伴们&#xff01;阿星又来给大家推荐神奇的小软件啦&#xff01;这次的主角可是个神器——鼠标连点器&#xff01;你听过没&#xff1f;这玩意儿简直是个“自动小助手”&#xff0c;让你的鼠标在屏幕上飞舞&#xff0c;点得飞快&#xff0c;解放你的双手&#xff0c;让你网…

一篇文章带你搞懂C++引用(建议收藏)

引用 6.1 引用概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。 比如&#xff1a;李逵&#xff0c;在家称为"铁牛"&#xff0c;江湖上人称&quo…

Linux.软件操作

1.yum 命令 要连网 2.systemctl 命令控制软件的启动和关闭 3.ln 创建软连接 使用cat来找本体&#xff0c;看看链接生不生效 4.date 命令查看系统时间 格式化的时候可以用双引号把他们引出来 -d 对时间进行修改 修改时区 自动校准 手动校准 5.ifconfig 查看本机的ip地址 6.h…

5.31.15 使用图像到图像转换和 YOLO 技术对先前的乳房 X 光检查结果中的异常进行早期检测和分类

在本研究中&#xff0c;我们研究了基于 You-Only-Look-Once (YOLO) 架构的端到端融合模型的有效性&#xff0c;该模型可同时检测和分类数字乳房 X 光检查中的可疑乳腺病变。包括四类病例&#xff1a;肿块、钙化、结构扭曲和正常&#xff0c;这些病例来自包含 413 个病例的私人数…

ic基础|复位篇02:芯片中的“人生重来枪”!crg之复位系统

大家好&#xff0c;我是数字小熊饼干&#xff0c;一个练习时长两年半的ic打工人。我在两年前通过自学跨行社招加入了IC行业。现在我打算将这两年的工作经验和当初面试时最常问的一些问题进行总结&#xff0c;并通过汇总成文章的形式进行输出&#xff0c;相信无论你是在职的还是…