矩阵按键&8*8点阵

矩阵按键

1.主要内容(扫描原理):
在这里插入图片描述
方法一:
逐行扫描:通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。
方法二:
行列扫描:通过高四位全部输出低电平,低四位输出高电平。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。
2.编写程序:

#include<reg52.h>
typedef	unsigned	char	u8;
typedef	unsigned	int	u16;
sbit	LSA=P2^2;
sbit	LSB=P2^3;
sbit	LSC=P2^4;
#define	GPIO_KEY	P1			       //定义矩阵键盘接口
#define	GPIO_DIG	P0			       //发送断码端口
u8	keyvalue;
u8	code		smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
											0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void	delay(u16	i)
{
	while(i--);
}
void	KeyDown()						//实现行列扫描
{
	u8	a;
	GPIO_KEY=0x0f;
	if(GPIO_KEY!=0x0f)			       //判断是否按下
	{
		delay(1000);
		if(GPIO_KEY!=0x0f)
		{
			GPIO_KEY=0x0f;
			switch(GPIO_KEY)
			{
				case(0x07):keyvalue=0;break;
				case(0x0b):keyvalue=1;break;
				case(0x0d):keyvalue=2;break;
				case(0x0e):keyvalue=3;break;
			}
			GPIO_KEY=0xf0;
			switch(GPIO_KEY)
			{
				case(0x70):keyvalue=keyvalue;break;
				case(0xb0):keyvalue=keyvalue+4;break;
				case(0xd0):keyvalue=keyvalue+8;break;
				case(0xe0):keyvalue=keyvalue+12;break;
		}
			while((a<50)&&(GPIO_KEY!=0xf0))
			{
				delay(1000);
				a++;
			}
		}
	}
}
void	main()
{
	LSA=0;
	LSB=0;
	LSC=0;
	while(1);
	{
		KeyDown();
		GPIO_DIG=smgduan[keyvalue];
	}
}

8×8点阵

1.主要内容:
在这里插入图片描述
在这里插入图片描述
注:P0控制第七列,D0控制第八行。
原理:显示汉字与数字:通过LED拼接数字图形,采用动态扫描的方式,发送断选数据,循环点亮每一列,点亮一列,发送一列数据。
2.编写程序:
a.点亮左上角第一个:

#include<reg51.h>
#include<intrins.h>							//定义左移右移,调用该头文件
typedef	unsigned	char	u8;
typedef	unsigned	int	u16;
sbit	SRCLK=P3^6;
sbit	RCLK=P3^5;
sbit	SER=P3^6;
void	Hc595SendByte(u8	dat)
{
	u8	a;
	SRCLK=0;
	RCLK=0;
	for(a=0;a<8;a++)
	{
		SER=dat>>7;				//595芯片SER最先传送最高位,移七次位
		dat<<=1;					//左移一位传送次高位eg.1001	1001右移七次后变为1,左移一位后变为0011	0010
		SRCLK=1;
		_nop_();								//延时
		_nop_();
		SRCLK=0;					//让电平拉低,循环形成高电平,由高低循环形成上升沿
	}
		RCLK=1;
	  _nop_();
	  _nop_();
		RCLK=0;					//原理同上
}
void	main()
{
	Hc595SendByte(0x80);				//D7s输出高电平,其余为低电平
	P0=0x7f;			//0111	1111
	while(1);
}

b.点亮0:

#include<reg51.h>
#include<intrins.h>							//定义左移右移,调用该头文件
typedef	unsigned	char	u8;
typedef	unsigned	int	u16;
sbit	SRCLK=P3^6;
sbit	RCLK=P3^5;
sbit	SER=P3^6;
u8	ledduan[]={0x00,0x00,0x41,0x41,0x41,0x3e};								//列
u8	ledwei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};				//保存每一列的数据//定义数组进行扫描
void	delay(u16	i)									//采用动态扫描,有延时函数
{
	while(i--);
}
void	Hc595SendByte(u8	dat)
{
	u8	a;
	SRCLK=0;
	RCLK=0;
	for(a=0;a<8;a++)
	{
		SER=dat>>7;				//595芯片SER最先传送最高位,移七次位
		dat<<=1;					//左移一位传送次高位eg.1001	1001右移七次后变为1,左移一位后变为0011	0010
		SRCLK=1;
		_nop_();								//延时
		_nop_();
		SRCLK=0;					//让电平拉低,循环形成高电平,由高低循环形成上升沿
	}
		RCLK=1;
	  _nop_();
	  _nop_();
		RCLK=0;					//原理同上
}
void	main()
{
	u8	i;
	while(1)								//动态显示,用for循环实现发送八个字节
	{
		P0=0x7f;							//第一列选通(最高位为零),再进行循环
		for(i=0;i<8;i++)
		{
			P0=ledwei[i];				//控制wei
			Hc595SendByte(ledduan[i]);		//发送数据,调用ledduan[i]
			delay(100);
			Hc595SendByte(0x00);					//断选数据不显示(清零),进行消隐
		}
	}
}
  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值