1、按前述教程快速新建一个新工程,在工程文件中app文件夹下新建key子文件夹用于存放key.c/key.h文件(记得添加进头文件路径),在user/main.c编写主函数
2、key.c代码
#include "key.h"
//按键初始化函数
void KEY_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK=1;//开启GPIO时钟
//KEY端口配置
GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;//设置为普通IO口
GpioCtrlRegs.GPADIR.bit.GPIO12=0;//设置为输入(行)
GpioCtrlRegs.GPAPUD.bit.GPIO12=0;//默认上拉
GpioCtrlRegs.GPAMUX1.bit.GPIO13=0;//设置为普通IO口
GpioCtrlRegs.GPADIR.bit.GPIO13=0;//设置为输入(行)
GpioCtrlRegs.GPAPUD.bit.GPIO13=0;//默认上拉
GpioCtrlRegs.GPAMUX1.bit.GPIO14=0;//设置为普通IO口
GpioCtrlRegs.GPADIR.bit.GPIO14=0;//设置为输入(行)
GpioCtrlRegs.GPAPUD.bit.GPIO14=0;//默认上拉
GpioCtrlRegs.GPBMUX2.bit.GPIO48=0;//设置为普通IO口
GpioCtrlRegs.GPBDIR.bit.GPIO48=1;//设置为输出(列)
GpioCtrlRegs.GPBPUD.bit.GPIO48=0;//默认上拉
GpioCtrlRegs.GPBMUX2.bit.GPIO49=0;//设置为普通IO口
GpioCtrlRegs.GPBDIR.bit.GPIO49=1;//设置为输出(列)
GpioCtrlRegs.GPBPUD.bit.GPIO49=0;//默认上拉
GpioCtrlRegs.GPBMUX2.bit.GPIO50=0;//设置为普通IO口
GpioCtrlRegs.GPBDIR.bit.GPIO50=1;//设置为输出(列)
GpioCtrlRegs.GPBPUD.bit.GPIO50=0;//默认上拉
EDIS;
GpioDataRegs.GPBSET.bit.GPIO48=1;//设置输出高电平
GpioDataRegs.GPBSET.bit.GPIO49=1;//设置输出高电平
GpioDataRegs.GPBSET.bit.GPIO50=1;//设置输出高电平
//即使按键按下也不影响判断
}
//按键检测函数
char KEY_Scan(char mode)
{
static char keyl1=1;//三个静态变量(如不是静态变量,在执行过程中,每次进入该函数变量值为1)
static char keyl2=1;
static char keyl3=1;
//第一列扫描
KEY_L1_SetL;//第一列为低电平,其他为高电平
KEY_L2_SetH;//
KEY_L3_SetH;//
if(keyl1==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))//有一个为0即按键按下
{
DELAY_US(10000);//延时10ms,软件消抖
keyl1=0;//如该列有按键按下,则变为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;//松开后按键要为1,为下次判断做准备
}
if(mode)//mode为0相当于按键按一下执行一下不能连续按。但当mode为1(连续扫描)时则可以连续按,像音量加减那样
keyl1=1;//始终
//第2列扫描
KEY_L1_SetH;//第2列为低电平,其他为高电平
KEY_L2_SetL;//
KEY_L3_SetH;//
if(keyl2==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))//有一个为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;
//第三列扫描
KEY_L1_SetH;//第3列为低电平,其他为高电平
KEY_L2_SetH;//
KEY_L3_SetL;//
if(keyl3==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))//有一个为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;
}
3、key.h代码
#ifndef KEY_H_
#define KEY_H_
#include "DSP2833x_Device.h"//包含所有的头文件,常用的宏定义 、F2833x 内核、 外设驱动的源文件对应的头文件
#include "DSP2833x_Examples.h"// 包含F2833x 通用文件的头文件。 比如中断、全局变量及函数声明、 IQmath 库等
#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);
char KEY_Scan(char mode);
#endif /* KEY_H_ */
4、main.c代码
#include "DSP2833x_Device.h"//包含所有的头文件,常用的宏定义 、F2833x 内核、 外设驱动的源文件对应的头文件
#include "DSP2833x_Examples.h"// 包含F2833x 通用文件的头文件。 比如中断、全局变量及函数声明、 IQmath 库等
#include "leds.h"
#include "key.h"
#include "relay.h"
#include "beep.h"
void main()
{
int i=0;
char key=0;
InitSysCtrl();//系统时钟初始化
LED_Init();
KEY_Init();
BEEP_Init();
Relay_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;
case KEY7_PRESS: while(1)
{
i++;
BEEP_TOGGLE;
DELAY_US(100);
};
break;//按下7蜂鸣器发声,但进入这个while死循环了,前面控制灯的用不了了
}
i++;
if(i%2000==0)
{
LED1_TOGGLE;//设置GPIO输出翻转信号
i=0;
}
DELAY_US(100);
}
}