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

news2024/10/6 10:41:16

本文以 立创·天空星开发板-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.coloradmin.cn/o/1800469.html

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

相关文章

nvm,node不是内部命令,npm版本不支持问题(曾经安装过nodejs)

nvm安装后nvm -v有效&#xff0c;node指令无效 环境变量配置无问题 推荐方案 下载你需要的node版本 Index of /dist/ (nodejs.org) 下载后解压到你的nvm存储版本的位置 cmd进入切换你的使用版本&#xff08;此时你的nodejs是从网上下载的&#xff0c;npm文件是存在的&…

react、vue动态form表单

需求在日常开发中反复写form 是一种低效的开发效率&#xff0c;布局而且还不同这就需要我们对其封装 为了简单明了看懂代码&#xff0c;我这里没有组件&#xff0c;都放在一起&#xff0c;简单抽离相信作为大佬的你&#xff0c;可以自己完成&#xff0c; 一、首先我们做动态f…

谷歌上架防关联,打包环境到底是不是关联因素之一?

在Google play上架应用&#xff0c;防关联是开发者们最关注的问题之一&#xff0c;只要开发者账号被谷歌审核系统与其它违规的开发者账号或应用存在关联&#xff0c;就很有可能被封号。 如果账号被封了&#xff0c;通常谷歌的封号通知邮件里只是写了因为关联或高风险、多次违规…

鸿蒙轻内核M核源码分析系列十七(3) 异常信息ExcInfo

本文中所涉及的源码&#xff0c;以OpenHarmony LiteOS-M内核为例&#xff0c;均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_m 获取。鸿蒙轻内核异常钩子模块代码主要在components\exchook目录下。 1、异常信息的宏定义、枚举和结构体 在文件components\exch…

NSSCTF-Web题目7

目录 [SWPUCTF 2022 新生赛]ez_rce 1、题目 2、知识点 3、思路 ​编辑 [MoeCTF 2022]baby_file 1、题目 2、知识点 3、思路 [SWPUCTF 2022 新生赛]ez_rce 1、题目 2、知识点 ThinkPHP V5 框架漏洞的利用&#xff0c;命令执行 由于ThinkPHP5在处理控制器传参时&#xff…

RK3588+FPGA+算能BM1684X:高性能AI边缘计算盒子,应用于视频分析、图像视觉等

搭载RK3588&#xff08;四核 A76四核 A55&#xff09;&#xff0c;CPU主频高达 2.4GHz &#xff0c;提供1MB L2 Cache 和 3MB L3 &#xff0c;Cache提供更强的 CPU运算能力&#xff0c;具备6T AI算力&#xff0c;可扩展至38T算力。 产品规格 系统主控CPURK3588&#xff0c;四核…

38页 | 工商银行大数据平台助力全行数字化转型之路(免费下载)

【1】关注本公众号&#xff0c;转发当前文章到微信朋友圈 【2】私信发送 工商银行大数据平台 【3】获取本方案PDF下载链接&#xff0c;直接下载即可。 如需下载本方案PPT/WORD原格式&#xff0c;请加入微信扫描以下方案驿站知识星球&#xff0c;获取上万份PPT/WORD解决方案&a…

leetcode刷题-栈与队列03

代码随想录栈与队列part02|239. 滑动窗口最大值、347.前 K 个高频元素、总结 239. 滑动窗口最大值347.前 K 个高频元素栈与队列总结 239. 滑动窗口最大值 leetcode题目链接 代码随想录文档讲解 思路&#xff1a; 滑动窗口的移动过程很像一个队列&#xff08;先进先出&#xff0…

『大模型笔记』Transformer系列技术博文汇总!

Transformer系列技术博文汇总&#xff01; 文章目录 第1篇&#xff1a;矩阵乘法概念解释第2篇&#xff1a;使用缩放点积方法的自注意力第3篇&#xff1a;深入探讨多头注意力、自注意力和交叉注意力第4篇&#xff1a;Transformer 架构第5篇&#xff1a;PostLN&#xff0c;PreLN…

Linux存储管理

简介 硬件上的存储设备目前有两类&#xff0c;通过磁头读写信息的机械硬盘和用主控芯片将信息写入晶体管的固态硬盘&#xff0c;硬盘调度算法等知识可以通过前面的操作系统设备管理文章学习&#xff0c;本章只介绍Linux中能对存储设备的操作。 为了让操作系统识别和管理物理磁…

企业差旅费管理如何实现真正的降本增效

看企业发展&#xff0c;不能只看当下&#xff0c;尤其对于看重长期价值的企业家来说&#xff0c;必须要用更长远的目光去看行业的未来。开源节流&#xff0c;扔掉一些没用的包袱减少负担&#xff0c;然后轻装上阵&#xff0c;并寻找企业发展的新增长点&#xff0c;仍然是众多企…

探索未来制造,BFT Robotics引领潮流

“买机器人&#xff0c;上BFT” 在这个快速变化的时代&#xff0c;创新和效率是企业发展的关键。BFT Robotics&#xff0c;作为您值得信赖的合作伙伴&#xff0c;专注于为您提供一站式的机器人采购和自动化解决方案。 产品系列&#xff1a; 协作机器人&#xff1a;安全、灵活、…

Vue3_对接腾讯云COS_大文件分片上传和下载

目录 一、腾讯云后台配置 二、安装SDK 1.script 引入方式 2.webpack 引入方式 三、文件上传 1.new COS 实例 2.上传文件 四、文件下载 腾讯云官方文档&#xff1a; 腾讯云官方文档https://cloud.tencent.com/document/product/436/11459 一、腾讯云后台配置 1.登录 对…

【外汇天眼】选择外汇EA的关键:策略适配、风险控制与稳定性评估

外汇EA&#xff08;Expert Advisor&#xff09;是外汇交易市场中广泛使用的自动化交易系统。它们通过预定义的规则和算法自动执行交易&#xff0c;旨在为交易者提供便捷的交易体验&#xff0c;同时提高交易效率和准确性。本文将从策略选择、风险控制和稳定性评估三个方面&#…

OKP绩效管理系统:助力企业实现卓越绩效

在当今竞争激烈的商业环境中&#xff0c;绩效管理系统成为企业提升效率和竞争力的重要工具。搭贝OKP绩效管理系统通过其强大的功能模块&#xff0c;帮助企业全面优化绩效管理流程&#xff0c;提升员工工作效率和企业整体绩效。本文将详细介绍搭贝OKP绩效管理系统的核心功能模块…

SpringBoot中的WebMvcConfigurationSupport和WebMvcConfigurer

在SpringBoot中可以通过以下两种方式来完成自定义WebMvc的配置&#xff1a; &#xff08;1&#xff09;继承WebMvcConfigurationSupport类 &#xff08;2&#xff09;实现WebMvcConfigurer接口 通过这两种方式完成的WebMvc配置存在差异&#xff0c;本文将对此作简单说明与区…

官网万词霸屏推广 轻松实现百度万词霸屏源码系统 带完整的安装代码包以及搭建教程

系统概述 官网万词霸屏推广源码系统是一款基于先进技术研发的综合性 SEO 工具。它的设计理念是通过智能化的算法和策略&#xff0c;帮助用户快速提升网站在百度等搜索引擎中的排名&#xff0c;实现大量关键词的霸屏效果。该系统整合了多种优化技术&#xff0c;包括关键词研究、…

日本指数实时API接口

日本 指数 实时API接口 # Restful API https://tsanghi.com/api/fin/index/JPN/realtime?token{token}&ticker{ticker}指定指数代码&#xff0c;获取该指数的实时行情&#xff08;开、高、低、收、量&#xff09;。 更新周期&#xff1a;实时。 请求方式&#xff1a;GET。…

Kali linux学习入门

Kali linux学习入门 文章目录 Kali linux学习入门Kali Linux简介Kali Linux工具篇Kali Docker安装Docker 更换国内镜像源Kali 安装 docker compose Kali Linux文档篇Kali Linux 社区篇 Kali Linux简介 Kali Linux是专门用于渗透测试linux操作系统&#xff0c;它由BackTrack发展…

Bev 车道标注方案及复杂车道线解决

文章目录 1. 数据采集方案1.1 传感器方案1.2 数据同步2. 标注方案2.1 标注注意项2.2 4d 标注(时序)2.2.1 4d标签制作2.2.2 时序融合的作用2.2.2.1 时序融合方式2.2.2.2 时序融合难点2.2.2.2 时序实际应用情况3. 复杂车道线解决3.1 split 和merge车道线的解决3.2 大曲率或U形车道…