7 通用数字量输入输出GPIO

news2024/11/28 0:58:39

文章目录

  • 7.0 GPIO概念
  • 7.1 GPIO工作原理
  • 7.2 GPIO寄存器以及编程
    • 7.2.5 GPIO寄存器编程设置与应用
  • 7.3 GPIO跑马灯
    • 7.3.1 LED 输出初始化
    • 7.3.2 跑马灯输出实验
    • 7.3.3 按键输入实验

7.0 GPIO概念

GPIO(general purpose intput output)是通用输入输出端口的简称,可以通过软件来控制其输入和输出。

  • F28335有88个GPIO口,对应着芯片的88个引脚
  • 88个引脚多是复用的,既可作为输入引脚也可作为输出引脚,即可作为通用IO引脚,也可作为特殊功能口(外设)
  • 可以通过GPIO MUX(输入输出多路选择器)寄存器进行相关配置。

7.1 GPIO工作原理

F28335的88个GPIO分为3组,分为A、B、C。

  • A组包括GPIO0-GPIO31
  • B组包括GPIO32-GPIO63
  • C组包括GPIO64-GPIO87

每个引脚都复用了多个功能,GPIO MUX寄存器用来配置每个引脚的具体功能。

  • 00 为通用IO引脚
  • 01 10 11分别为外设1 2 3引脚

如果某个引脚选择了数字量IO模式

  • 可以通过方向寄存器GPxDIR配置IO方向,既可作为输入引脚也可以作为输出引脚。
  • 可以通过量化寄存器GPxQUAL对输入信号进行量化限制,从而消除数字量IO引脚的早上干扰。

有以下四种方式对GPIO引脚进行读写操作:

  • 可以通过GPxDAT寄存器独立读写IO
  • 可以通过GPxSET寄存器写1对IO进行置位
  • 可以通过GPxCLEAR寄存器写1对IO进行清除
  • 可以通过GPxTOGGLE寄存器写1翻转IO的输出电平
    在这里插入图片描述

如7.1图所示,最左侧为GPIO0-27,上方有个PU,代表是否上拉。

  • 控制寄存器为GPAPUD,0的时候上拉有效,反之无效。

两个三角形控制GPIO作为输入还是输出,上边输入,下边输出。

  • GPIO输入后经过滤波电路。

GPIO输入

  • 数据进入GPADAT寄存器,此时该寄存器为读寄存器,对其进行置位是无效的。
  • GPADAT上方为PIE中断。

GPIO输出

  • 下方三角为输出通道,输出值为GPADAT内的值。
  • GPA-SET可以设置GPADAT的值

GPIO输入受到可编程滤波器的限制。用户可以通过配置GPAQSEL1、GPAQSEL2、GPBQSEL2寄存器选择GPIO引脚的输入限制类型。

7.2 GPIO寄存器以及编程

7.2.5 GPIO寄存器编程设置与应用

GPIO的数据寄存器一共有4类,分别是GPIODAT、GPIOSET、GPIOCLEAR、GPIOTOGGLE。
如果某个GPIO输出设置为输出状态,那么通过GPIODAT相应位写0或者1,此时GPIO就会输出相应的状态。
F28335的88个GPIO分为3组,分为A、B、C。

  • A组GPIO可以通过软件配置为外部中断1、2以及NMI功能。
  • B组GPIO可以通过软件配置为外部中断3、4、5、6、7功能。
  • C组GPIO不可以配置为中断功能。

如果要将某GPIO配置为外部中断功能,下面是设置步骤。

7.3 GPIO跑马灯

7.3.1 LED 输出初始化

void LED_Init(void)
{
	EALLOW;//关闭写保护
	SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;    // 开启GPIO时钟
 
	//LED1端口配置
	GpioCtrlRegs.GPCMUX1.bit.GPIO68=0;//设置为通用GPIO功能    0-通用输出 1-外设1输出 2-外设2输出 3-外设3输出
	GpioCtrlRegs.GPCDIR.bit.GPIO68=1;//设置GPIO方向为输出    1-输出 0-输入
	GpioCtrlRegs.GPCPUD.bit.GPIO68=0;//使能GPIO上拉电阻    0-使能上拉 1-禁止上拉
 
	GpioDataRegs.GPCSET.bit.GPIO68=1;//设置GPIO输出高电平
    //GpioDataRegs.GPCCLEAR.bit.GPIO68 = 1; //设置GPIO输出为低电平
 
	EDIS;//开启写保护
}

7.3.2 跑马灯输出实验

使用DSP的引脚GPIO0-GPIO5,共阴极连接,当高电平时,LED被点亮;当为低电平时,LED熄灭。
初始化代码:

void LED_GPIO_Config(void)
{
    EALLOW;
    GpioCtrlRegs.GPAMUX1.bit.GPIO0=0;//普通IO模式
    GpioCtrlRegs.GPAPUD.bit.GPIO0=0;//使能内部上拉
    GpioCtrlRegs.GPADIR.bit.GPIO0=1;//配置成输出

    GpioCtrlRegs.GPAMUX1.bit.GPIO1=0;//普通IO模式
    GpioCtrlRegs.GPAPUD.bit.GPIO1=0;//使能内部上拉
    GpioCtrlRegs.GPADIR.bit.GPIO1=1;//配置成输出

    GpioCtrlRegs.GPAMUX1.bit.GPIO2=0;//普通IO模式
    GpioCtrlRegs.GPAPUD.bit.GPIO2=0;//使能内部上拉
    GpioCtrlRegs.GPADIR.bit.GPIO2=1;//配置成输出

    GpioCtrlRegs.GPAMUX1.bit.GPIO3=0;//普通IO模式
    GpioCtrlRegs.GPAPUD.bit.GPIO3=0;//使能内部上拉
    GpioCtrlRegs.GPADIR.bit.GPIO3=1;//配置成输出

    GpioCtrlRegs.GPAMUX1.bit.GPIO4=0;//普通IO模式
    GpioCtrlRegs.GPAPUD.bit.GPIO4=0;//使能内部上拉
    GpioCtrlRegs.GPADIR.bit.GPIO4=1;//配置成输出

    GpioDataRegs. GPASET.bit.GPIO0=1; //输出高电平
    GpioDataRegs. GPASET.bit.GPIO1=1; //输出高电平
    GpioDataRegs. GPASET.bit.GPIO2=1;
    GpioDataRegs. GPASET.bit.GPIO3=1;
    GpioDataRegs. GPASET.bit.GPIO4=1;
    EDIS;
}

7.3.3 按键输入实验

DSP GPIO作为输入时,硬件自带滤波功能,通过设置指定寄存器达到3次或6次采样滤波
在这里插入图片描述

#define KEY_L1_SetL			(GpioDataRegs.GPBCLEAR.bit.GPIO48=1)
#define KEY_L2_SetL			(GpioDataRegs.GPBCLEAR.bit.GPIO49=1)
#define KEY_L3_SetL			(GpioDataRegs.GPBCLEAR.bit.GPIO50=1)
 
#define KEY_L1_SetH			(GpioDataRegs.GPBSET.bit.GPIO48=1)
#define KEY_L2_SetH			(GpioDataRegs.GPBSET.bit.GPIO49=1)
#define KEY_L3_SetH			(GpioDataRegs.GPBSET.bit.GPIO50=1)
 
#define KEY_H1			(GpioDataRegs.GPADAT.bit.GPIO12)
#define KEY_H2			(GpioDataRegs.GPADAT.bit.GPIO13)
#define KEY_H3			(GpioDataRegs.GPADAT.bit.GPIO14)
 
#define KEY1_PRESS		1
#define KEY2_PRESS		2
#define KEY3_PRESS		3
#define KEY4_PRESS		4
#define KEY5_PRESS		5
#define KEY6_PRESS		6
#define KEY7_PRESS		7
#define KEY8_PRESS		8
#define KEY9_PRESS		9
#define KEY_UNPRESS		0
 
void KEY_Init(void)
{
	EALLOW;
	SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;// 开启GPIO时钟
 
	//KEY端口配置
    /*GPIO输入端*/
	GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;
	GpioCtrlRegs.GPADIR.bit.GPIO12=0;    // GPIO设置为输入
	GpioCtrlRegs.GPAPUD.bit.GPIO12=0;
 
	GpioCtrlRegs.GPAMUX1.bit.GPIO13=0;
	GpioCtrlRegs.GPADIR.bit.GPIO13=0;    // GPIO设置为输入
	GpioCtrlRegs.GPAPUD.bit.GPIO13=0;
 
	GpioCtrlRegs.GPAMUX1.bit.GPIO14=0;
	GpioCtrlRegs.GPADIR.bit.GPIO14=0;    // GPIO设置为输入
	GpioCtrlRegs.GPAPUD.bit.GPIO14=0;
 
    /*GPIO输出端*/
	GpioCtrlRegs.GPBMUX2.bit.GPIO48=0;
	GpioCtrlRegs.GPBDIR.bit.GPIO48=1;    // GPIO设置为输出
	GpioCtrlRegs.GPBPUD.bit.GPIO48=0;
 
	GpioCtrlRegs.GPBMUX2.bit.GPIO49=0;
	GpioCtrlRegs.GPBDIR.bit.GPIO49=1;    // GPIO设置为输出
	GpioCtrlRegs.GPBPUD.bit.GPIO49=0;
 
	GpioCtrlRegs.GPBMUX2.bit.GPIO50=0;
	GpioCtrlRegs.GPBDIR.bit.GPIO50=1;    // GPIO设置为输出
	GpioCtrlRegs.GPBPUD.bit.GPIO50=0;
 
	GpioDataRegs.GPBSET.bit.GPIO48=1;
	GpioDataRegs.GPBSET.bit.GPIO49=1;
	GpioDataRegs.GPBSET.bit.GPIO50=1;
 
	EDIS;
}
 
char KEY_Scan(char mode)    //mode=0 单次扫描    mode=1 循环扫描
{
 
	static char keyl1=1;
	static char keyl2=1;
	static char keyl3=1;
 
	//第1列扫描
	KEY_L1_SetL;
	KEY_L2_SetH;
	KEY_L3_SetH;
	if(keyl1==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))
	{
		DELAY_US(10000);    //消抖
		keyl1=0;
		if(KEY_H1==0)
		{
			return KEY1_PRESS;
		}
		else if(KEY_H2==0)
		{
			return KEY4_PRESS;
		}
		else if(KEY_H3==0)
		{
			return KEY7_PRESS;
		}
	}
	else if(KEY_H1==1&&KEY_H2==1&&KEY_H3==1)
	{
		keyl1=1;
	}
	if(mode)
		keyl1=1;
 
 
	//第2列扫描
	KEY_L2_SetL;
	KEY_L1_SetH;
	KEY_L3_SetH;
	if(keyl2==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))
	{
		DELAY_US(10000);//消抖
		keyl2=0;
		if(KEY_H1==0)
		{
			return KEY2_PRESS;
		}
		else if(KEY_H2==0)
		{
			return KEY5_PRESS;
		}
		else if(KEY_H3==0)
		{
			return KEY8_PRESS;
		}
	}
	else if(KEY_H1==1&&KEY_H2==1&&KEY_H3==1)
	{
		keyl2=1;
	}
	if(mode)
		keyl2=1;
 
 
	//第3列扫描
	KEY_L3_SetL;
	KEY_L1_SetH;
	KEY_L2_SetH;
	if(keyl3==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))
	{
		DELAY_US(10000);//消抖
		keyl3=0;
		if(KEY_H1==0)
		{
			return KEY3_PRESS;
		}
		else if(KEY_H2==0)
		{
			return KEY6_PRESS;
		}
		else if(KEY_H3==0)
		{
			return KEY9_PRESS;
		}
	}
	else if(KEY_H1==1&&KEY_H2==1&&KEY_H3==1)
	{
		keyl3=1;
	}
	if(mode)
		keyl3=1;
 
	return KEY_UNPRESS;
}
 
void main()
{
	int i=0;
	char key=0;
 
	InitSysCtrl();
 
	LED_Init();
	KEY_Init();
 
	while(1)
	{
		key=KEY_Scan(0);
		switch(key)
		{
			case KEY1_PRESS: LED2_TOGGLE;break;
			case KEY2_PRESS: LED3_TOGGLE;break;
			case KEY3_PRESS: LED4_TOGGLE;break;
			case KEY4_PRESS: LED5_TOGGLE;break;
			case KEY5_PRESS: LED6_TOGGLE;break;
			case KEY6_PRESS: LED7_TOGGLE;break;
		}
 
		i++;
		if(i%2000==0)
		{
			LED1_TOGGLE;
		}
		DELAY_US(100);
	}
}

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

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

相关文章

Elasticsearch:LangChain 是什么?

当你将应用程序称为 “AI(人工智能)” 时,这通常意味着它包含与学习模型(例如大型语言模型,或 LLM)的交互。 [不那么]有趣的事实是,LLM 的使用实际上并不是使应用程序变得智能的原因。 它的特殊…

vue项目npm install报错Failed at the fibersa4.0.3 install script

报错如下 解决:降低node版本 降到12.16.0 参考链接

基于51单片机的全自动洗衣机proteus仿真设计

标题目录 💫51单片机全自动洗衣机proteus仿真设计💫设计介绍💫仿真图电动机驱动模块电路设计电源模块电路设计控制按键进水阀和排水阀控制继电器 💫程序设计main函数 💫设计报告💫资料清单&&下载链…

【古诗生成AI实战】之三——任务加载器与预处理器

本章内容属于数据处理阶段,将分别介绍任务加载器task和预处理器processor。 [1] 数据集 在深入探讨数据处理的具体步骤之前,让我们先了解一下我们将要使用的数据集的形式。 本项目采用的是七绝数据集,总计83072条古诗,其形式如下&…

Linux系统编写C语言程序并执行(图文详解)

目录 前言 Linux如何编写C语言 1.打开编辑器,写代码 2.编译运行文件 相关拓展 前言 LINUX中包含了很多软件开发工具。它们中的很多是用于C和C应用程序开发的。 C是一种能在UNIX的早期就被广泛使用的通用编程语言。它最早是由Bell实验室的Dennis Ritchie为了UN…

中年人怎么发展?持续发展?

现在ai这么火,就像当年的xxx,如果没有抓住,会xxx吗? 为了ai,多学学python也是也是好的啊。 在学习之余,还是想做做自媒体的。不求马上赚到钱。我的想法是,现在每天下班回家都是刷刷抖音&#…

Jmeter工具学习三——CSV文件、关联、断言

Jmeter学习三——CSV文件和关联 jmeter做功能测试和做性能测试的区别CSV数据文件设置(读取外部文件,进行分数据驱动)文件设置字段介绍:文件名文件编码如果出现编码问题导致的乱码,如何解决? 变量名忽略首行…

基于深度学习的图像超分辨率应用

引言 在使用图片浏览软件显示图片时,为了凸显某个部位,你会放大图片,为了显示整体,你会缩小图片。 你的原始图片大小是固定的,但图像浏览软件既可以最大化到整个屏幕,也可以只占一个区域,这些…

【云平台】STM32微信小程序阿里云平台学习板

【云平台】STM32微信小程序阿里云平台学习板 文章目录 前言一、立创EDA(硬件设计)1.主控STM32F103C8T62.ESP8266模块3.温湿度模块4.光照强度模块5.OLED显示模块6.PCB正面7.PCB反面8.3D视角正面9.3D视角反面 二、【云平台】STM32微信小程序阿里云平台学习…

Linux7设置ssh秘钥登录并关闭密码登录

说明:场景为windows使用WinScp远程登录linux服务 winscp安装教程:winscp安装及关联putty使用_putty.exe没有找到_cherishSpring的博客-CSDN博客 1.在window上生成公钥和秘钥,操作方式参考以下文章第3点: git关联云效使用教程_云…

爬取极简壁纸

js反编译的代码需要解密之类的,直接给我干蒙圈了,借助selenium可以直接获取到调式工具中的源码,可以获取渲染后的链接,然后将链接交给下载函数(使用异步提高效率)即可。 后续学习完js反编译的话&#xff0…

项目实战——苍穹外卖(DAY10)

如果之前有改过端口号造成WebSocket无法连接的,可以看本篇文章“来单提醒”前的内容进行解决。 课程内容 Spring Task 订单状态定时处理 WebSocket 来单提醒 客户催单 功能实现:订单状态定时处理、来单提醒和客户催单 订单状态定时处理&#xff1a…

Spring Boot 项目配置文件出现乱码的解决方法

如下图,我们 Spring Boot 项目的配置文件 application.properties 可能会出现如下的乱码问题: 我们写注解的时候是正常的,但是下次启动项目就出现了乱码,这个是字符集设置的问题 解决方法 1.点击 File 选择 Settings 2.搜索 enco…

C#学习-8课时

P10 输入输出程序编写 相同类型的可以直接相加; cwtabtabconsole.Writeline(); using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace C_8_1 { class Program { s…

基于xml配置的AOP

目录 xml方式AOP快速入门 xml方式AOP配置详解 xml方式AOP快速入门 xml方式配置AOP的步骤 导入AOP相关坐标 <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.13</version></de…

树状数组专题

折叠 区间修改&#xff0c;区间查询&#xff0c;这一类题通常都可以使用线段树解决&#xff0c;但对于此题&#xff0c;树状数组同样可以&#xff0c;而且常数较小&#xff0c;代码简单。 思路&#xff1a; 考虑使用树状数组去维护差分数组&#xff0c;即对于 a i a_i ai​,我们…

C语言WFC实现矩形旋转

前言&#xff1a;结合上一篇的博客进行对矩形的创建和旋转操作 代码实现&#xff1a; //旋转矩阵 void CCGDrawingView::RotateRectangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, double angle, CDC* pDC) {//绘制旋转前的矩形Rectangle(x1, y1, x…

阿里云MQTT: 子设备上线流程

0. 背景 阿里云网关子设备上平台的资料很少。有些厂家直接配置每个子设备的DeviceSecret到网关里&#xff0c;显然太麻烦了&#xff01;我经过阅读阿里文档&#xff0c;发现有些简化的方法&#xff0c;更便于客户使用&#xff0c;因此分享给大家。 1. 主要信息片段 子设备 $…

Java之API(上):Boolean

一、前言&#xff1a; 上次我们将到了 java.lang.* 下的包装类&#xff1a;Integer。这次我讲一下基本数据类型中的&#xff1a;布尔型&#xff08;boolean&#xff09;对应的包装类&#xff08;Boolean&#xff09;。注意&#xff1a;还有对包装类&#xff1a;Integer进行一些…

爬楼梯(力扣LeetCode)动态规划

爬楼梯 题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1 阶 1 阶2 阶 示…