C51键盘检测相关问题总结

附注:
原理图各接口连接关系可参考代码中的端口定义;
P0口数据锁存器为两片74HC573芯片;
1.对独立键盘的检测

/*--------------------------
功能:用数码管实现60s计时器
上电时,数码管显示00
key4控制开始/暂停计时
暂停状态下,key1进行加1操作
key2进行减1操作
key3进行清零操作
---------------------------
Author: Zhang Kaizhou
Date: 2019-5-19 19:14:20
--------------------------*/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
	
sbit key1 = P3^4;
sbit key2 = P3^5;
sbit key3 = P3^6;
sbit key4 = P3^7;
sbit wei_address = P2^7;
sbit duan_address = P2^6;
uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f,
					  0x66, 0x6d, 0x7d, 0x07,
				      0x7f, 0x6f, 0x77, 0x7c,
				      0x39, 0x5e, 0x79, 0x71}; // 定义一个无符号字符型数组table[],存放在单片机内部的ROM或Flash中

uchar n1 = 0, n2 = 0;							
	
void init();
void display(uchar num);
void keyScan();	
void delay(uchar xms);											
											
void main()
{
	init();
	while(1)
	{
		keyScan();
		display(n1);
	}
}

/*初始化函数*/
void init()
{
	TMOD = 0x01; // 定时器0,方式1
	TH0 = (65536 - 45872) / 256; // 定时50ms
	TL0 = (65536 - 45872) % 256;
	EA = 1; // 开全局中断
	ET0 = 1; // 开定时器0溢出中断
}

/*定时器0中断服务程序*/
void T0_interrupt() interrupt 1
{
	TH0 = (65536 - 45872) / 256; // 定时器0重装初值
	TL0 = (65536 - 45872) % 256;
	n2++;
	if(n2 == 20) // 定时到1s
	{
		n2 = 0;
		n1++;
		if(n1 == 60)
		{
			n1 = 0;
		}
	}
}

/*数码管显示函数*/
void display(uchar num)
{
	uchar shi, ge;
	shi = num / 10;
	ge = num % 10;
	
	duan_address = 1; // 在数码管上显示十位的数字
	P0 = table[shi];
	duan_address = 0;
	P0 = 0xff;
	wei_address = 1;
	P0 = 0xfe;
	wei_address = 0;
	delay(5);
	
	duan_address = 1; // 在数码管上显示个位的数字
	P0 = table[ge];
	duan_address = 0;
	P0 = 0xff;
	wei_address = 1;
	P0 = 0xfd;
	wei_address = 0;
	delay(5);
}

/*键盘扫描函数*/
void keyScan()
{
	if(!key1) // key1按下,加1
	{
		delay(10);
		if(!key1) 
		{
			n1++;
			if(n1 == 60)
			{
				n1 = 0;
			}
			while(!key1);
		}
	}
	
	if(!key2) // key2按下,减1
	{
		delay(10);
		if(!key2) 
		{
			if(!n1)
			{
				n1 = 60;				
			}
			n1--;
			while(!key2);
		}
	}
	
	if(!key3) // key4按下,暂停或开始定时器0
	{
		delay(10);
		if(!key3) 
		{
			n1 = 0;
			while(!key3);
		}
	}
	
	if(!key4)
	{
		delay(10);
		if(!key4)
		{
			while(!key4);
			TR0 = ~TR0;
		}
	}
}

/*延时函数*/
void delay(uchar xms)
{
	uchar i, j;
	for(i = 0; i < xms; i++)
		for(j = 0; j < 110; j++);
}

2.对矩阵键盘进行扫描

/*------------------------
功能:扫描4x4矩阵键盘
Author: Zhang Kaizhou
Date: 2019-5-21 21:37:31
-------------------------*/
#include <reg52.h>
#define uchar unsigned char
	
sbit wei_address = P2^7;
sbit duan_address = P2^6;

uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f,
					  0x66, 0x6d, 0x7d, 0x07,
  				      0x7f, 0x6f, 0x77, 0x7c,
					  0x39, 0x5e, 0x79, 0x71}; // 定义一个无符号字符型数组table[],存放在单片机内部的ROM或Flash中

uchar buffer, key;											
	
void init_digitron();											
void array_scan_oneline(uchar address);											
void array_scan();	
void display(uchar key);											
void delay(uchar xms);											
											
void main()
{
	init_digitron(); // 初始化数码管
	while(1) // 循环逐行扫描按键是否按下
	{
		array_scan();
	}
}

/*数码管初始化函数*/
void init_digitron()
{
	P0 = 0; // 关闭所有数码管
	duan_address = 1;
	duan_address = 0;
	
	P0 = 0x00; // 选中所有数码管
	wei_address = 1;
	wei_address = 0;
}

/*矩阵键盘扫描函数*/
void array_scan()
{
	array_scan_oneline(0xfe);
	array_scan_oneline(0xfd);
	array_scan_oneline(0xfb);
	array_scan_oneline(0xf7);
}

/*矩阵键盘扫描一行的函数*/
void array_scan_oneline(uchar address)
{
	P3 = address;
	buffer = P3;
	buffer = buffer & 0xf0;
	if(buffer != 0xf0) // 有键按下
	{
		delay(10); // 消抖
		buffer = P3;
		buffer = buffer & 0xf0;
		if(buffer != 0xf0)
		{
			buffer = P3;
			switch(buffer)
			{
				case 0xee: key = 0; break;
				case 0xde: key = 1; break;
				case 0xbe: key = 2; break;
				case 0x7e: key = 3; break;
				
				case 0xed: key = 4; break;
				case 0xdd: key = 5; break;
				case 0xbd: key = 6; break;
				case 0x7d: key = 7; break;
				
				case 0xeb: key = 8; break;
				case 0xdb: key = 9; break;
				case 0xbb: key = 10; break;
				case 0x7b: key = 11; break;
				
				case 0xe7: key = 12; break;
				case 0xd7: key = 13; break;
				case 0xb7: key = 14; break;
				case 0x77: key = 15; break;
			}
			while(buffer != 0xf0) // 等待按键释放
			{
				buffer = P3;
				buffer = buffer & 0xf0;
			}
			display(key);
		}
	}
}

/*延时函数*/
void delay(uchar xms)
{
	uchar i, j;
	for(i = 0; i < xms; i++)
		for(j = 0; j < 110; j++);
}

/*数码管显示函数*/
void display(uchar key)
{
	P0 = table[key];
	duan_address = 1;
	duan_address = 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值