DSP28335定时中断方式扫描矩阵键盘,并用LCD1602显示

本文介绍了一种基于DSP2833x的3x3矩阵键盘扫描方法及1602液晶屏显示的实现过程。通过定时器控制,实现了每200ms扫描一次按键,并利用1602液晶屏实时显示所按下的按键数字。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源码连接,有需要的朋友自取。

/***************************************************
使用GPIO0-GPIO11,液晶与其对应的引脚如下所示:
//
//        RS--GPIO0引脚,
    	  R/W--GND,
    	  EN--GPIO1引脚,
    	  D0--GPIO2引脚
//        D1--GPIO3引脚,
 * 		  D2--GPIO4引脚,
 *        D3--GPIO5引脚,
 *        D4--GPIO6引脚
//        D5--GPIO7引脚,
 *        D6--GPIO8引脚,
 *        D7--GPIO9引脚;
 *
 *按键扫描,,三行接的是GPIO12  13  14
                        三列接的是GPIO48  49  50
                        按键扫描原理: 1、3列对应的IO设置为输出,3行对应的IO设置为输入。其实
					   2、若无按键按下,3行输入IO,均为高电平(因为有外部上拉电阻)
					   3、若按键按下,对应行IO被拉低(假设为第X行),检测为低电平。按键所在行(X行),被鉴别出来。
					   4、此时,依次改变3列的输出为高,当遇到按键所在列时,第X行电平重新变为高。按键所在列。被鉴别出来。
			观测变量Key的值来判断哪个按键按下了;
			
			程序中设定定时器0的定时周期是100ms,,KX_Tim的值为2时才进行按键值的计算,,也就是相当于每200ms扫描一次按键,,然后用1602显示
 *       ****************************************************/

#include "DSP2833x_Device.h"
#include "DSP2833x_Examples.h"
/*******************************
//宏定义
 ******************************/

#define		SET_KY1		GpioDataRegs.GPBSET.bit.GPIO48 = 1
#define		SET_KY2		GpioDataRegs.GPBSET.bit.GPIO49 = 1
#define		SET_KY3		GpioDataRegs.GPBSET.bit.GPIO50 = 1
#define		RST_KY1		GpioDataRegs.GPBCLEAR.bit.GPIO48 = 1
#define		RST_KY2		GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1
#define		RST_KY3		GpioDataRegs.GPBCLEAR.bit.GPIO50 = 1
#define		KX1_STATUS	GpioDataRegs.GPADAT.bit.GPIO12
#define		KX2_STATUS	GpioDataRegs.GPADAT.bit.GPIO13
#define		KX3_STATUS	GpioDataRegs.GPADAT.bit.GPIO14

#define uchar unsigned char
#define LCD_RS GpioDataRegs.GPADAT.bit.GPIO0
#define LCD_EN GpioDataRegs.GPADAT.bit.GPIO1
#define LCD_DB GpioDataRegs.GPADAT.all


interrupt void cpu_timer0_isr(void);

void Init_KeyGpio(void);//初始化3X3矩阵键盘对应的GPIO端口
void delay(Uint32 t);//软件延时函数
void ResetAllKY(void);//用于复位所有列端口的函数
void KX_AllStatus(void);//用于读取所有行端口的电平状态的函数
void Read_KX(Uint16 x);//读取按键行值的函数
void Read_KY(Uint16 x);//读取按键列值的函数
void Set_KY(Uint16 x);//用于将某一列对应端口置高的函数
void Rst_KY(Uint16 x);//用于将某一列对应端口置低的函数

void Init_Port(void);//初始化1602使用的GPIO端口
void LCD_init(void);//初始化Lcd1602
void LCD_write_command(uchar command);//LCDD写命令函数
void LCD_write_data(uchar dat);//LCD写数据函数
void show(char *cont);//LCD显示函数



Uint16 Keys[3][3] = {1,2,3,4,5,6,7,8,9};
Uint16 Key = 0;
Uint16 KX_On = 0;
uchar temp = 0;
Uint16 KX_Tim[5] = {0};
Uint16 KX_Status[5] = {0};
Uint16 KY_On = 0;


void main(void)
{
	InitSysCtrl();

	Init_KeyGpio();
	Init_Port();

	DINT;

	InitPieCtrl();

	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();

	EALLOW;
	PieVectTable.TINT0 = &cpu_timer0_isr;
	EDIS;

	InitCpuTimers();

	ConfigCpuTimer(&CpuTimer0,150,100000);//定时器定时100ms

	StartCpuTimer0();

	EALLOW;
	GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 0;
	GpioCtrlRegs.GPBDIR.bit.GPIO60 = 1;
	GpioDataRegs.GPBSET.bit.GPIO60 = 1;
	EDIS;

	IER |= M_INT1;

	PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

	EINT;

	LCD_init();
	LCD_write_command(0x80);
	show("Key number: ");
	while(1)
	{
		//显示函数
	}

	
}
interrupt void cpu_timer0_isr(void)
{
	Read_KX(1);
	Read_KX(2);
	Read_KX(3);
	Read_KY(1);
	Read_KY(2);
	Read_KY(3);
	//GpioDataRegs.GPBTOGGLE.bit.GPIO60 = 1;

	CpuTimer0.InterruptCount++;


	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

void Init_KeyGpio(void)
{
	EALLOW;
	//GPIO48  输出,低电平
	GpioCtrlRegs.GPBMUX2.bit.GPIO48 = 0;
	GpioCtrlRegs.GPBDIR.bit.GPIO48 = 1;
	GpioDataRegs.GPBCLEAR.bit.GPIO48 = 1;
	GpioCtrlRegs.GPBPUD.bit.GPIO48 = 0;
	//GPIO49 输出,低电平
	GpioCtrlRegs.GPBMUX2.bit.GPIO49 = 0;
	GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1;
	GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1;
	GpioCtrlRegs.GPBPUD.bit.GPIO49 = 0;
	//GPIO50输出,低电平
	GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 0;
	GpioCtrlRegs.GPBDIR.bit.GPIO50 = 1;
	GpioDataRegs.GPBCLEAR.bit.GPIO50 = 1;
	GpioCtrlRegs.GPBPUD.bit.GPIO50 = 0;

	//GPIO12,输入
	GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0;
	GpioCtrlRegs.GPADIR.bit.GPIO12 = 0;
	GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0;
	//GPIO13 z输入
	GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0;
	GpioCtrlRegs.GPADIR.bit.GPIO13 = 0;
	GpioCtrlRegs.GPAPUD.bit.GPIO13 = 0;
	//GPIO14 输入
	GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 0;
	GpioCtrlRegs.GPADIR.bit.GPIO14 = 0;
	GpioCtrlRegs.GPAPUD.bit.GPIO14 = 0;

	EDIS;
	ResetAllKY();
}
void ResetAllKY(void)
{
	RST_KY1;
	RST_KY2;
	RST_KY3;
}
void Read_KX(Uint16 x)
{
	KX_AllStatus();
	if(KX_Status[x] == 0)
	{

		KX_Tim[x]++;
		if(KX_Tim[x] >= 2)
		{
			KX_On = x;
			KX_Tim[1] = 0;
			KX_Tim[2] = 0;
			KX_Tim[3] = 0;
		}
	}

}
void KX_AllStatus(void)
{
	KX_Status[1] = KX1_STATUS;
	KX_Status[2] = KX2_STATUS;
	KX_Status[3] = KX3_STATUS;
}
void Read_KY(Uint16 x)
{
	if((!KX_Status[KX_On]) && (KX_On))
	{
		Set_KY(x);
		DELAY_US(200);
		KX_AllStatus();
		if(KX_Status[KX_On])
		{
			KY_On = x;
			Key = Keys[KX_On - 1][KY_On - 1];
			temp = Key + 0x30;//数字转字符,,因为LCD1602只能显示字符
			LCD_write_command(0x8c);
			LCD_write_data(temp);

			KX_On = 0;
			KY_On = 0;
		}
		Rst_KY(x);

	}
}
void Set_KY(Uint16 x)
{
	if(x == 1){SET_KY1;}
	if(x == 2){SET_KY2;}
	if(x == 3){SET_KY3;}
}
void Rst_KY(Uint16 x)
{
	if(x == 1){RST_KY1;}
	if(x == 2){RST_KY2;}
	if(x == 3){RST_KY3;}

}

void Init_Port(void)
{
	EALLOW;

	GpioCtrlRegs.GPAMUX1.all = 0x00000000;
	GpioCtrlRegs.GPADIR.all = 0x00000FFF;

	GpioDataRegs.GPADAT.bit.GPIO0 = 0;
	GpioDataRegs.GPADAT.bit.GPIO1 = 0;

	EDIS;
}
void LCD_init(void)
{
	DELAY_US(15000);
	LCD_write_command(0x38);
	DELAY_US(5000);
	LCD_write_command(0x38);
	DELAY_US(5000);
	LCD_write_command(0x38);
	LCD_write_command(0x38);
	LCD_write_command(0x08);
	LCD_write_command(0x01);
	LCD_write_command(0x06);
	LCD_write_command(0x0c);
}
void LCD_write_command(uchar command)
{
	LCD_EN = 0;
	LCD_RS = 0;
	LCD_DB = (command << 2) | 0x0000;
	DELAY_US(500);
	LCD_EN = 1;
	DELAY_US(1000);
	LCD_EN = 0;
}
void show(char *cont)
{
	while(*cont != 0)
	{
		LCD_write_data(*cont);
		DELAY_US(500);
		cont++;
	}
}
void LCD_write_data(uchar dat)
{
	LCD_EN = 0;
	LCD_RS = 1;
	LCD_DB = (dat << 2) | 0x0001;
	DELAY_US(500);
	LCD_EN = 1;
	DELAY_US(1000);
	LCD_EN = 0;
}

源码连接,有需要的自取

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值