F28335有88个GPIO口,可灵活配置为输入引脚,输出引脚与通用I/O引脚。其实现可以通过GPIO MUX 寄存器进行相关设置。
1.1 GPIO工作原理
88个GPIO口分为A、B、C三组,具体分配见表1。工作在哪个模式通过GPIO MUX寄存器进行配置;如果将这 些引脚选择数字量I/O模式,通过方向寄存器GPxDIR配置数字量I/O方向,既可作为输入引脚也可作为输出引脚;还可以通过GPxQUAL对输入信号进行量化限制,消除数字量I/O引脚的噪声干扰。
表1 GPIO引脚分布
GPIOA | GPIOB | GPIOC |
0~31 | 32~63 | 64~87 |
此外,有下面4种方式对GPIO引脚进行读/写操作:
① 通过GPxDAT寄存器独立读/写/I/O信号。
② 利用GPxSET寄存器进行写1对I/O口置位。
③ 利用GPxCLEAR寄存器进行写1对I/O口清零。
④ 利用GPxTOOGLE寄存器置1后(写0无效)翻转I/O输出电平,高变低低变高。
GPIO模块图如图1所示。两个三角形是控制GPIO作为输入还是输出,上三角为输入通道,GPIO输入后经滤波电路。引脚功能选择由多路选择器控制,每个引脚有4种功能,00为通用I/O引脚,01,10,11分别为外设1,2,3引脚。输入的值都会进入GPADAT寄存器。下三角为输出模式,输出值为GPADAT内的值,在做输出引脚时,可以通过GPA-SET等寄存器设置该寄存器的值。
图1 GPIO模块框图
GPIO输入受到可编程的滤波器的限制,可以通过配置GPAQSEL1,GPAQSEL2寄存器选择GPIO引脚的输入限制类型。对于一个GPIO输入引脚,输入限制可以被SYSCLKOUT同步然后经采样窗进行滤波限制,而对于配置成外设输入的引脚,除同步与采样窗限制外,也可以是异步输入的。如图2所示GPAQSEL1、GPAQSEL2
图2 GPIO滤波采样
中信号采样次数被指定为3个采样或6个采样,当输入信号经过3个或6个采样周期都保持一致时,输入信号才被认为是个有效的信号。否则保持原来状态不变。例如图3中有一个GPIO输入信号中有一个较窄脉冲,因为其持续时间没到采样数3个采样周期或6个采样周期,所以认为该脉冲是干扰信号,采样信号保持原先不变,这样就起到了滤波的作用,在采样信号初始时,会延迟设置的采样周期,因为需要经过3个或6个采样周期后,才确认有效信号,采样信号才做有效变换。凡是滤波,用硬件或软件,都会引入信号延迟。
图3 GPIO滤波采样波形
1.2 寄存器设置与应用
将IOA全部设置GPIO功能,输出状态,0量化,
void GPIO_SELECT(void)
{
EALLOW;
Uint16var1 = 0x0000;
Uint16var2 = 0xffff;
Uint16var3 = 0x0000;
GpioCtrlRegs.GPAMUX1.all= var1;
GpioCtrlRegs.GPAMUX2.all= var1;
GpioCtrlRegs.GPADIR.all= var2;
GpioCtrlRegs.GPAQSEL1.all= var3;
GpioCtrlRegs.GPAQSEL2.all= var3;
EDIS;
}
F28335一共有88个GPIO,分为三组,分别为ABC,其中A组GPIO可以通过软件配置为外部中断1,2以及NMI功能,B组GPIO可以通过软件配置为外部中断3,4,5,6,7功能。而C组的GPIO不能配置为中断功能。如果将GPIO配置为外部中断功能,配置步骤如下。
① 将数字量I/O配置为GPIO功能。
② 将数字量I/O配置为输入方向。
③ 将数字量I/O量化配置正确。
④ 利用外部中断选择寄存器选择相应的引脚为外部中断源。
⑤ 为此GPIO触发信号设置极性,上升沿,下降沿或者双边沿。
⑥ 使能外部中断即可。
例如将GPIO54~GPIO57分别设置为外部中断3~6。
//将GPIO54~GPIO57分别设置为外部中断3~6。 54~57为B组
void Interrput_GPIO(void)
{
EALLOW;
GpioCtrlRegs.GPBMUX2.bit.GPIO54= 0; // 普通的GPIO输入输出引脚
GpioCtrlRegs.GPBMUX2.bit.GPIO55= 0;
GpioCtrlRegs.GPBMUX2.bit.GPIO56= 0;
GpioCtrlRegs.GPBMUX2.bit.GPIO57= 0;
GpioCtrlRegs.GPBDIR.bit.GPIO54= 0; // 设置为输入
GpioCtrlRegs.GPBDIR.bit.GPIO55= 0;
GpioCtrlRegs.GPBDIR.bit.GPIO56= 0;
GpioCtrlRegs.GPBDIR.bit.GPIO57= 0;
GpioCtrlRegs.GPBQSEL2.bit.GPIO54= 0; //系统时钟不分频
GpioCtrlRegs.GPBQSEL2.bit.GPIO55= 0;
GpioCtrlRegs.GPBQSEL2.bit.GPIO56= 0;
GpioCtrlRegs.GPBQSEL2.bit.GPIO57= 0;
GpioIntRegs.GPIOXINT3SEL.bit.GPIOSEL= 54; // 设置外部中断
GpioIntRegs.GPIOXINT4SEL.bit.GPIOSEL= 55;
GpioIntRegs.GPIOXINT5SEL.bit.GPIOSEL= 56;
GpioIntRegs.GPIOXINT6SEL.bit.GPIOSEL= 57;
XIntruptRegs.XINT3CR.bit.POLARITY= 0; // 中断触发方式
XIntruptRegs.XINT4CR.bit.POLARITY= 0;
XIntruptRegs.XINT5CR.bit.POLARITY= 0;
XIntruptRegs.XINT6CR.bit.POLARITY= 0;
XIntruptRegs.XINT3CR.bit.ENABLE= 1; // 使能外部中断
XIntruptRegs.XINT4CR.bit.ENABLE= 1;
XIntruptRegs.XINT5CR.bit.ENABLE= 1;
XIntruptRegs.XINT6CR.bit.ENABLE= 1;
EDIS;
}
1.3 跑马灯程序设计
1.头文件程序设计
#ifndef LED__H
#define LED__H
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#define LED1_OFF (GpioDataRegs.GPCSET.bit.GPIO68=1)
#define LED1_ON (GpioDataRegs.GPCCLEAR.bit.GPIO68=1)
#define LED1_TOGGLE (GpioDataRegs.GPCTOGGLE.bit.GPIO68=1)
#define LED2_OFF (GpioDataRegs.GPCSET.bit.GPIO67=1)
#define LED2_ON (GpioDataRegs.GPCCLEAR.bit.GPIO67=1)
#define LED2_TOGGLE (GpioDataRegs.GPCTOGGLE.bit.GPIO67=1)
#define LED3_OFF (GpioDataRegs.GPCSET.bit.GPIO66=1)
#define LED3_ON (GpioDataRegs.GPCCLEAR.bit.GPIO66=1)
#define LED3_TOGGLE (GpioDataRegs.GPCTOGGLE.bit.GPIO66=1)
#define LED4_OFF (GpioDataRegs.GPCSET.bit.GPIO65=1)
#define LED4_ON (GpioDataRegs.GPCCLEAR.bit.GPIO65=1)
#define LED4_TOGGLE (GpioDataRegs.GPCTOGGLE.bit.GPIO65=1)
#define LED5_OFF (GpioDataRegs.GPCSET.bit.GPIO64=1)
#define LED5_ON (GpioDataRegs.GPCCLEAR.bit.GPIO64=1)
#define LED5_TOGGLE (GpioDataRegs.GPCTOGGLE.bit.GPIO64=1)
#define LED6_OFF (GpioDataRegs.GPASET.bit.GPIO10=1)
#define LED6_ON (GpioDataRegs.GPACLEAR.bit.GPIO10=1)
#define LED6_TOGGLE (GpioDataRegs.GPATOGGLE.bit.GPIO10=1)
#define LED7_OFF (GpioDataRegs.GPASET.bit.GPIO11=1)
#define LED7_ON (GpioDataRegs.GPACLEAR.bit.GPIO11=1)
#define LED7_TOGGLE (GpioDataRegs.GPATOGGLE.bit.GPIO11=1)
//#define LED1 (GpioDataRegs.GPCDAT.bit.GPIO68)
//#define LED2 (GpioDataRegs.GPCDAT.bit.GPIO67)
//#define LED3 (GpioDataRegs.GPCDAT.bit.GPIO66)
//#define LED4 (GpioDataRegs.GPCDAT.bit.GPIO65)
//#define LED5 (GpioDataRegs.GPCDAT.bit.GPIO64)
//#define LED6 (GpioDataRegs.GPADAT.bit.GPIO10)
//#define LED7 (GpioDataRegs.GPADAT.bit.GPIO11)
// 定义初始化
void LED_Init(void);
// 延时函数
void delay(void);
#endif /* LED_MINE_H_ */
2.源文件程序设计
/*
* Led_Mine.c
*
* Created on: 2023年10月31日
* Author: jingk
*/
#include"Led_Mine.h"
void LED_Init(void)
{
EALLOW; // 关闭写保护
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // 开启GPIO时钟
//GpioCtrlRegs 控制寄存器
// MUx1 为61-79 MUX2 80-87
GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 0; // 设置GPIO为输出模式
GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 0; // 设置GPIO为输出模式
GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 0; // 设置GPIO为输出模式
GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 0; // 设置GPIO为输出模式
GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 0; // 设置GPIO为输出模式
GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 0; // 设置GPIO为输出模式
GpioCtrlRegs.GPAMUX1.bit.GPIO11 = 0; // 设置GPIO为输出模式
GpioCtrlRegs.GPCDIR.bit.GPIO68 = 1; // 设置GPIO为输出模式
GpioCtrlRegs.GPCDIR.bit.GPIO67 = 1; // 设置GPIO为输出模式
GpioCtrlRegs.GPCDIR.bit.GPIO66 = 1; // 设置GPIO为输出模式
GpioCtrlRegs.GPCDIR.bit.GPIO65 = 1; // 设置GPIO为输出模式
GpioCtrlRegs.GPCDIR.bit.GPIO64 = 1; // 设置GPIO为输出模式
GpioCtrlRegs.GPADIR.bit.GPIO10 = 1; // 设置GPIO为输出模式
GpioCtrlRegs.GPADIR.bit.GPIO11 = 1; // 设置GPIO为输出模式
GpioCtrlRegs.GPAQSEL1.bit.GPIO11 = 3;
// 上拉电阻设置 保护LED灯稳定信号
GpioCtrlRegs.GPCPUD.bit.GPIO68 = 0; //
GpioCtrlRegs.GPCPUD.bit.GPIO67 = 0;
GpioCtrlRegs.GPCPUD.bit.GPIO66 = 0;
GpioCtrlRegs.GPCPUD.bit.GPIO65 = 0;
GpioCtrlRegs.GPCPUD.bit.GPIO64 = 0;
GpioCtrlRegs.GPAPUD.bit.GPIO10 = 0;
GpioCtrlRegs.GPAPUD.bit.GPIO11 = 0;
// 初始状态下为熄灭 所以设置为高电平
GpioDataRegs.GPCSET.bit.GPIO68 = 1;
GpioDataRegs.GPCSET.bit.GPIO67 = 1;
GpioDataRegs.GPCSET.bit.GPIO66 = 1;
GpioDataRegs.GPCSET.bit.GPIO65 = 1;
GpioDataRegs.GPCSET.bit.GPIO64 = 1;
GpioDataRegs.GPASET.bit.GPIO10 = 1;
GpioDataRegs.GPASET.bit.GPIO11 = 1;
EDIS; // 开启写保护
}
void delay(void)
{
Uint16 i;
Uint16 j;
for(i=0; i<32; i++)
for(j =0; j<100000; j++);
}
3.主函数程序设计
#include"Led_Mine.h"
void main()
{
InitSysCtrl(); // 系统时钟初始化 默认开启所有外设时钟
LED_Init();
// GpioDataRegs.GPCCLEAR.bit.GPIO68 = 1;
while(1)
{
LED1_ON;DELAY_US(50000);LED1_OFF;
LED2_ON; DELAY_US(50000); LED2_OFF;
LED3_ON; DELAY_US(50000); LED3_OFF;
LED4_ON;DELAY_US(50000);LED4_OFF;
LED5_ON; DELAY_US(50000); LED5_OFF;
LED6_ON; DELAY_US(50000);LED6_OFF;
LED7_ON; DELAY_US(50000); LED7_OFF;
DELAY_US(50000); //延时函数
}
}