这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » STC51单片机实例之09矩阵按键的使用

共2条 1/1 1 跳转至

STC51单片机实例之09矩阵按键的使用

高工
2014-03-20 00:14:35     打赏
/********************************************************************
* 文件名  : 矩阵键盘.c
* 描述    :  该文件实现了 4 * 4 键盘的试验。通过数码管的最后一位来显示
			 当前的按键值。		 

*********************************************************************/
#include<reg51.h>
#include<intrins.h>

#define uint unsigned int
#define uchar unsigned char

uchar code table[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
void Delay_1ms(uint i)//1ms延时
{
	uchar x,j;
	for(j=0;j<i;j++)
	for(x=0;x<=148;x++);	
}
 

/********************************************************************
* 名称 : Keyscan()
* 功能 : 实现按键的读取。下面这个子程序是按处理 矩阵键盘 的基本方法处理的。
* 输入 : 无
* 输出 : 按键值
***********************************************************************/
uchar Keyscan(void)
{
	uchar i,j, temp, Buffer[4] = {0xfe, 0xfd, 0xfb, 0xf7};			//让矩阵键盘的每行分别为低电平
	for(j=0; j<4; j++)
	{
		P1 = Buffer[j];
		temp = 0x10;                                                                                                                                                                    
		for(i=0; i<4; i++)
		{
			if(!(P1 & temp)) 		//判断P1口高4位某一行为低电平
			{
				return (i+j*4);		//返回键码
			}
			temp <<= 1;
		}	
	}
}

/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main(void)
{
	uchar Key_Value;  //读出的键值
	P2 = 7;
	while(1)
	{
		P1 = 0xf0;				
		if(P1 != 0xf0)			//判断有无按键按下
		{
			Delay_1ms(20);		//按键消抖
			if(P1 != 0xf0)		//第二次判断有无按键按下
			{
				Delay_1ms(20);  //按键消抖
				if(P1 != 0xf0)	//第三次判断有无按键按下
				{
					Key_Value = Keyscan();		
				}
			}
		}
		P0 = table[Key_Value];	 //数码管赋值
	}
}

 

/********************************************************************
* 文件名  : 矩阵键盘LCD.c
* 描述    :  该文件实现了 4 * 4 键盘的试验。通过1602液晶来显示当前的按键值。		 

*********************************************************************/
#include<reg51.h>
#include<intrins.h>

#define uint unsigned int
#define uchar unsigned char

//这三个引脚参考资料
sbit E=P2^7;		//1602使能引脚
sbit RW=P2^6;		//1602读写引脚	
sbit RS=P2^5;		//1602数据/命令选择引脚


/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
void Delay_1ms(uint i)//1ms延时
{
	uchar x,j;
	for(j=0;j<i;j++)
	for(x=0;x<=148;x++);	
}

/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间大概为5US。
* 输入 : 无
* 输出 : 无
***********************************************************************/

void delay()
{
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
}
/********************************************************************
* 名称 : bit Busy(void)
* 功能 : 这个是一个读状态函数,读出函数是否处在忙状态
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
bit Busy(void)
{
	bit busy_flag = 0;
	RS = 0;
	RW = 1;
	E = 1;
	delay();
	busy_flag = (bit)(P0 & 0x80);
	E = 0;
	return busy_flag;
}
/********************************************************************
* 名称 : wcmd(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void wcmd(uchar del)
{
	while(Busy());
	RS = 0;
	RW = 0;
	E = 0;
	delay();
	P0 = del;
	delay();
	E = 1;
	delay();
	E = 0;
}

/********************************************************************
* 名称 : wdata(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/

void wdata(uchar del)
{
	while(Busy());
	RS = 1;
	RW = 0;
	E = 0;
	delay();
	P0 = del;
    delay();
	E = 1;
	delay();
	E = 0;
}

/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void L1602_init(void)
{
	wcmd(0x38);
	Delay_1ms(5);
	wcmd(0x38);
	Delay_1ms(5);
	wcmd(0x38);
	Delay_1ms(5);
	wcmd(0x38);
	wcmd(0x08);	
	wcmd(0x0c);
	wcmd(0x04);
	wcmd(0x01);
}

/********************************************************************
* 名称 : L1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
		 L1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_char(uchar hang,uchar lie,char sign)
{
	uchar a;
	if(hang == 1) a = 0x80;
	if(hang == 2) a = 0xc0;
	a = a + lie - 1;
	wcmd(a);
	wdata(sign);
}

/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
	 	 L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
	uchar a,b=0;
	if(hang == 1) a = 0x80;
	if(hang == 2) a = 0xc0;
	a = a + lie - 1;
	while(1)
	{
		wcmd(a++);		
		if((*p == '\0')||(b==16)) break;
		b++;
		wdata(*p);
		p++;
	}
}

/********************************************************************
* 名称 : Keyscan()
* 功能 : 实现按键的读取。下面这个子程序是按处理 矩阵键盘 的基本方法处理的。
* 输入 : 无
* 输出 : 按键值
***********************************************************************/
uchar Keyscan(void)
{
	uchar i,j, temp, Buffer[4] = {0xfe, 0xfd, 0xfb, 0xf7};
	for(j=0; j<4; j++)
	{
		P1 = Buffer[j];
		temp = 0x10;                                                                                                                                                                    
		for(i=0; i<4; i++)
		{
			if(!(P1 & temp)) 
			{
				return (i+j*4);
			}
			temp <<= 1;
		}	
	}
}

/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main(void)
{
	uchar Key_Value;  //读出的键值
	L1602_init();
	L1602_string(1,1,"  4*4 KeyBoard  ");
	L1602_string(2,1,"You Press The    ");
	while(1)
	{
		P1 = 0xf0;
		if(P1 != 0xf0)
		{
			Delay_1ms(20);	//按键消抖
			if(P1 != 0xf0)
			{
				Delay_1ms(20);	//按键消抖
				if(P1 != 0xf0)
				{
					Key_Value = Keyscan();		
				}
			}
		}
		L1602_char(2,15,Key_Value / 10 + 48);
		L1602_char(2,16,Key_Value % 10 + 48);		
	}
}

 

/********************************************************************
* 文件名  : 矩阵键盘LCD.c
* 描述    :  该代码是一个综合性比较强的代码。
             这个代码在程序的最开始,用这个语句:code6wei = 0x123456;
			 把密码固定为123456,这里大家可以进行修改。
			 如果6位密码输入对,就会显示"right!!!"welcome back!!!"	
			 如果错误会显示 "wrong!!!""Input afresh!!!",直到密码输入正确。

*********************************************************************/
#include<reg51.h>
#include<intrins.h>

#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long

uchar code table[10] = {0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1f, 0x01, 0x09};

//这三个引脚参考资料
sbit E=P2^7;		//1602使能引脚
sbit RW=P2^6;		//1602读写引脚	
sbit RS=P2^5;		//1602数据/命令选择引脚


/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
void Delay_1ms(uint i)//1ms延时
{
	uint x,j;
	for(j=0;j<i;j++)
	for(x=0;x<=148;x++);	
}

/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间大概为5US。
* 输入 : 无
* 输出 : 无
***********************************************************************/

void delay()
{
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
}
/********************************************************************
* 名称 : bit Busy(void)
* 功能 : 这个是一个读状态函数,读出函数是否处在忙状态
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
bit Busy(void)
{
	bit busy_flag = 0;
	RS = 0;
	RW = 1;
	E = 1;
	delay();
	busy_flag = (bit)(P0 & 0x80);
	E = 0;
	return busy_flag;
}
/********************************************************************
* 名称 : wcmd(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void wcmd(uchar del)
{
	while(Busy());
	RS = 0;
	RW = 0;
	E = 0;
	delay();
	P0 = del;
	delay();
	E = 1;
	delay();
	E = 0;
}

/********************************************************************
* 名称 : wdata(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/

void wdata(uchar del)
{
	while(Busy());
	RS = 1;
	RW = 0;
	E = 0;
	delay();
	P0 = del;
    delay();
	E = 1;
	delay();
	E = 0;
}

/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void L1602_init(void)
{
	wcmd(0x38);
	Delay_1ms(5);
	wcmd(0x38);
	Delay_1ms(5);
	wcmd(0x38);
	Delay_1ms(5);
	wcmd(0x38);
	wcmd(0x08);	
	wcmd(0x0c);
	wcmd(0x04);
	wcmd(0x01);
}

/********************************************************************
* 名称 : L1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
		 L1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_char(uchar hang,uchar lie,char sign)
{
	uchar a;
	if(hang == 1) a = 0x80;
	if(hang == 2) a = 0xc0;
	a = a + lie - 1;
	wcmd(a);
	wdata(sign);
}

/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
	 	 L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
	uchar a,b=0;
	if(hang == 1) a = 0x80;
	if(hang == 2) a = 0xc0;
	a = a + lie - 1;
	while(1)
	{
		wcmd(a++);
		b++;
		if((*p == '\0')||(b==16)) break;
		wdata(*p);
		p++;
	}
}

/********************************************************************
* 名称 : Keyscan()
* 功能 : 实现按键的读取。下面这个子程序是按处理 矩阵键盘 的基本方法处理的。
* 输入 : 无
* 输出 : 按键值
***********************************************************************/
uchar Keyscan(void)
{
	uchar i,j, temp, Buffer[4] = {0xfe, 0xfd, 0xfb, 0xf7};
	for(j=0; j<4; j++)
	{
		P1 = Buffer[j];
		temp = 0x10;                                                                                                                                                                    
		for(i=0; i<4; i++)
		{
			if(!(P1 & temp)) 
			{
				return (i+j*4);
			}
			temp <<= 1;
		}	
	}
	return 10;
}

/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main(void)
{
	uchar i=6,j=0;  //读出的键值
	uchar SLED[6]={0};
	ulong Key_Value;
	ulong code6wei = 0x123456;
	ulong codebijiao = 0;
	L1602_init();
	L1602_string(1,1,"  The code is:");
	while(1)
	{
		Key_Value=10;
		P1 = 0xf0;
		if(P1 != 0xf0)
		{
			Delay_1ms(20);	//按键消抖
			if(P1 != 0xf0)
			{
				Delay_1ms(20);	//按键消抖
				if(P1 != 0xf0)
				{
					Key_Value = Keyscan();					
				}
			}
		}
		if(Key_Value < 10)
		{
			L1602_char(2,i,Key_Value + 48);
			codebijiao = codebijiao | (Key_Value <<((5-j)*4));
			i++;
			j++;
			Delay_1ms(300);
		}
		if(j==6)
		{
			if(codebijiao == code6wei)
			{
				wcmd(0x01);
				L1602_string(1,1,"right!!!");
				L1602_string(2,1,"welcome back!!!");
				while(1);
			}
			else
			{
				wcmd(0x01);
				L1602_string(1,1,"wrong!!!");
				L1602_string(2,1,"Input afresh!!!");
				Delay_1ms(2000);
				j = 0;
				i = 6;
				wcmd(0x01);
				L1602_string(1,1,"  The code is:");
			}
		}
	}
}

 


菜鸟
2014-05-24 21:32:16     打赏
2楼
学习收藏。。。。。

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]