3.DSP学习记录之GPIO按键输入
按键输入控制实验(基于TI 28335)
- 一、按键及硬件连接
- 1.矩阵键盘扫描原理
- 2.硬件电路
- 二、软件实现
- 1.按键扫描思路
- 2.程序实现
一、按键及硬件连接
按键为一种控制输入设备,按键在使用时因为按键的不稳定性,常常需要消抖,软件消抖方法通常有两种:延时消抖和while循环消抖
1.矩阵键盘扫描原理
以33矩阵键盘为例,若将所有键盘均连接在开发板上,则需要9个IO口,可以通过扫描办法,通过6个IO口实现33键盘的使用,通常有行列扫描和线翻转法两种。
行列扫描:将列线置低电平,检测三个行线是否有低电平,若有则证明该列某一行的按键按下
行列扫描较为简单,故本实验采用行列扫描来检测按键是否按下
2.硬件电路
如下图:
如上图,行线由GPIO12、GPIO13、GPIO14控制,列线由GPIO48、GPIO49、GPIO50控制,行线上接3.3V上拉电平
二、软件实现
我们设定该实验为按键1、2、3、4、5按下翻转LED1~5的电平,按键6按下将五个LED全部点亮,按键7按下将所有五个LED全部熄灭
1.按键扫描思路
矩阵键盘扫描思路:将列键配置为输出,行键配置为输入,初始状态下列键输出为高电平
某一列扫描思路:拉低该列电平,检测对应输入行的电平状态,以第一列为例:
在扫描时,将第一列输出低电平,第二和第三列输出高电平,然后检测三行状态,如下:
`//1.第一列扫描:拉低第一列
GpioDataRegs.GPBCLEAR.bit.GPIO48 = 1;
GpioDataRegs.GPBSET.bit.GPIO49 = 1;
GpioDataRegs.GPBSET.bit.GPIO50 = 1;
//1.第一列扫描:拉低第一列GpioDataRegs.GPBCLEAR.bit.GPIO48 = 1;GpioDataRegs.GPBSET.bit.GPIO49 = 1;GpioDataRegs.GPBSET.bit.GPIO50 = 1;if(Key11 == 1 && (Key_H1 == 0 ||Key_H2 == 0||Key_H3 == 0)){DELAY_US(10000);Key11 = 0;if(Key_H1 == 0){return 1;}else if(Key_H2 == 0){return 4;}else if(Key_H3 == 0){return 7;}}
上面程序中,DELAY_US(10000);用于对按键进行消抖,定义的Key11变量用于反应该列里是否有行对按键进行按下,Key11为0则按下,Key11为1则没有按下
然后再检测完该列之后重复同样操作进行检测第二列和第三列对应的三行是否有按键按下,然后返回相应的键码
此外,再该函数Key_Scan()中,还定义了一个局部变量mode,该变量用于设定按键的工作情况,mode 若设定为1,则将Key11、Key12、Key13三个变量置高电平,表示按键按下长按不松开
Key_H1等三个变量宏定义在Key.h文件中,用于返回输入电平信号
2.程序实现
(1)Key.c文件
#include "key.h"void Key_Init(void)
{EALLOW;SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;//行键//12GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;GpioCtrlRegs.GPADIR.bit.GPIO12=0;GpioCtrlRegs.GPAPUD.bit.GPIO12=0;//13GpioCtrlRegs.GPAMUX1.bit.GPIO13=0;GpioCtrlRegs.GPADIR.bit.GPIO13=0;GpioCtrlRegs.GPAPUD.bit.GPIO13=0;//14GpioCtrlRegs.GPAMUX1.bit.GPIO14=0;GpioCtrlRegs.GPADIR.bit.GPIO14=0;GpioCtrlRegs.GPAPUD.bit.GPIO14=0;//列键//48GpioCtrlRegs.GPBMUX2.bit.GPIO48=0;GpioCtrlRegs.GPBDIR.bit.GPIO48=1;GpioCtrlRegs.GPBPUD.bit.GPIO48=0;//49GpioCtrlRegs.GPBMUX2.bit.GPIO49=0;GpioCtrlRegs.GPBDIR.bit.GPIO49=1;GpioCtrlRegs.GPBPUD.bit.GPIO49=0;//50GpioCtrlRegs.GPBMUX2.bit.GPIO50=0;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 Key11 = 1;static char Key12 = 1;static char Key13 = 1;//1.第一列扫描:拉低第一列GpioDataRegs.GPBCLEAR.bit.GPIO48 = 1;GpioDataRegs.GPBSET.bit.GPIO49 = 1;GpioDataRegs.GPBSET.bit.GPIO50 = 1;if(Key11 == 1 && (Key_H1 == 0 ||Key_H2 == 0||Key_H3 == 0)){DELAY_US(10000);Key11 = 0;if(Key_H1 == 0){return 1;}else if(Key_H2 == 0){return 4;}else if(Key_H3 == 0){return 7;}}else if(Key_H1 == 1||Key_H2 == 1||Key_H3 == 1){Key11 = 1;//松开按键返回Key11初始转状态}if(mode == 1){Key11 = 1;}//2.第二列扫描:拉低第二列GpioDataRegs.GPBSET.bit.GPIO48 = 1;GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1;GpioDataRegs.GPBSET.bit.GPIO50 = 1;if(Key12 == 1 && (Key_H1 == 0 ||Key_H2 == 0||Key_H3 == 0)){DELAY_US(10000);Key12 = 0;if(Key_H1 == 0){return 2;}else if(Key_H2 == 0){return 5;}else if(Key_H3 == 0){return 8;}}else if(Key_H1 == 1||Key_H2 == 1||Key_H3 == 1){Key12 = 1;//松开按键返回Key12初始转状态}if(mode == 1){Key12 = 1;}//3.第三列扫描:拉低第三列GpioDataRegs.GPBSET.bit.GPIO48 = 1;GpioDataRegs.GPBSET.bit.GPIO49 = 1;GpioDataRegs.GPBCLEAR.bit.GPIO50 = 1;if(Key13 == 1 && (Key_H1 == 0 ||Key_H2 == 0||Key_H3 == 0)){DELAY_US(10000);Key13 = 0;if(Key_H1 == 0){return 3;}else if(Key_H2 == 0){return 6;}else if(Key_H3 == 0){return 9;}}else if(Key_H1 == 1||Key_H2 == 1||Key_H3 == 1){Key13 = 1;//松开按键返回Key13初始转状态}if(mode == 1){Key13 = 1;}return 0;
}
(2)Key.h文件
#ifndef APP_KEY_KEY_H_
#define APP_KEY_KEY_H_#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File#include "beep.h"void Key_Init(void);
char Key_Scan(char mode);#define Key_H1 GpioDataRegs.GPADAT.bit.GPIO12
#define Key_H2 GpioDataRegs.GPADAT.bit.GPIO13
#define Key_H3 GpioDataRegs.GPADAT.bit.GPIO14#endif /* APP_KEY_KEY_H_ */
(3)LED.h
#include "led.h"void Led_Init(void)
{EALLOW;SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;//64GpioCtrlRegs.GPCMUX1.bit.GPIO64=0;GpioCtrlRegs.GPCDIR.bit.GPIO64=1;GpioCtrlRegs.GPCPUD.bit.GPIO64=0;//65GpioCtrlRegs.GPCMUX1.bit.GPIO65=0;GpioCtrlRegs.GPCDIR.bit.GPIO65=1;GpioCtrlRegs.GPCPUD.bit.GPIO65=0;//66GpioCtrlRegs.GPCMUX1.bit.GPIO66=0;GpioCtrlRegs.GPCDIR.bit.GPIO66=1;GpioCtrlRegs.GPCPUD.bit.GPIO66=0;//67GpioCtrlRegs.GPCMUX1.bit.GPIO67=0;GpioCtrlRegs.GPCDIR.bit.GPIO67=1;GpioCtrlRegs.GPCPUD.bit.GPIO67=0;//68GpioCtrlRegs.GPCMUX1.bit.GPIO68=0;GpioCtrlRegs.GPCDIR.bit.GPIO68=1;GpioCtrlRegs.GPCPUD.bit.GPIO68=0;EDIS;GpioDataRegs.GPCSET.bit.GPIO64=1;GpioDataRegs.GPCSET.bit.GPIO65=1;GpioDataRegs.GPCSET.bit.GPIO66=1;GpioDataRegs.GPCSET.bit.GPIO67=1;GpioDataRegs.GPCSET.bit.GPIO68=1;
}
(4)LED.h
#ifndef APP_LED_LED_H_
#define APP_LED_LED_H_#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File#include "beep.h"void Led_Init(void);#endif /* APP_LED_LED_H_ */
(5)main.c
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "beep.h"
#include "Key.h"
#include "LED.h"void main()
{InitSysCtrl();Key_Init();Led_Init();char key_num = 0;while(1){key_num = Key_Scan(0);switch(key_num){case 1:GpioDataRegs.GPCTOGGLE.bit.GPIO68=1;break;case 2:GpioDataRegs.GPCTOGGLE.bit.GPIO67=1;break;case 3:GpioDataRegs.GPCTOGGLE.bit.GPIO66=1;break;case 4:GpioDataRegs.GPCTOGGLE.bit.GPIO65=1;break;case 5:GpioDataRegs.GPCTOGGLE.bit.GPIO64=1;break;case 6:GpioDataRegs.GPCCLEAR.bit.GPIO64=1;GpioDataRegs.GPCCLEAR.bit.GPIO65=1;GpioDataRegs.GPCCLEAR.bit.GPIO66=1;GpioDataRegs.GPCCLEAR.bit.GPIO67=1;GpioDataRegs.GPCCLEAR.bit.GPIO68=1;break;case 7:GpioDataRegs.GPCSET.bit.GPIO64=1;GpioDataRegs.GPCSET.bit.GPIO65=1;GpioDataRegs.GPCSET.bit.GPIO66=1;GpioDataRegs.GPCSET.bit.GPIO67=1;GpioDataRegs.GPCSET.bit.GPIO68=1;break;}}}