C语言课设项目-51单片机-独立按键与矩阵按键

 (创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)

目录

一、独立按键

1.按键介绍

2.独立按键原理

3.编写独立按键控制程序

二、矩阵按键

1.矩阵按键的由来

2.矩阵按键扫描原理

3.编写矩阵按键控制程序


一、独立按键

1.按键介绍

轻触开关是一种电子开关,使用时,轻轻按开关按钮就可使开关接通,当松开手时,开关断开。我们使用的开关如下图:

2.独立按键原理

如下图所示:当k1按下以后,由于接地,IO接口和内部输入口就会变成低电平,当按键不按下且内部没有输出时,IO口默认为高电平

 按键在闭合和断开时,触点会存在抖动现象

硬件消抖电路:

3.编写独立按键控制程序

#include"reg51.h"
#include<intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
sbit led =P2^0;
 //如原理图所示:k1接的是RXD接口,而RXD接的是P3.1
sbit k1=P3^1;


void delay(u16 i)	//延时函数
{
 
 	while(i--);  //当i=1时,可以延时10微秒
}
void keypros()
{
	//判断按键是否按下
 	if(k1==0)
 	{
 	   	delay(1000);  //通过延时时间实现消抖处理
		if(k1==0)	//判断是否按下
		{  
			//对其进行循环取反实现按键控制功能
			led = ~led; 
		}
		while(!k1);//判断按键是否松开
 	}
}
void main()
{
 	while(1)  //通过循环实现按键控制LED
 	{
   		keypros();
 	}

}

二、矩阵按键

1.矩阵按键的由来

由图可得:同样是8个IO接口,独立按键只能连接8个按钮,而矩阵键盘可以连接16个接口,所以矩阵键盘经常用于按键比较多的情况

2.矩阵按键扫描原理

方法一:      逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。

方法二:     行列扫描:我们可以通过高四位全部输出低电平,低四位输出高电平。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。

3.编写矩阵按键控制程序

//通过行列扫描实现矩阵按键
#include"reg51.h"
typedef unsigned char u8;
typedef unsigned int u16;

u8 code smgduan[16]={0x3f,0x05,0x5b,0x4f,0x66,0x6d,
					0x7d,0x07,0x7f,0x6f,0x77,0x7c,
					0x39 , 0x5e , 0x79 , 0x71}; //共阴

u8 KeyValue;  //创建变量作为smgduan数组的下标
void delay(u16 i)
{
 	while(i--);
}

void KeyDown()
{
	
	char a = 0;
	
	//首先使高四位全部输出低电平,低四位输出高电平
	P1=0x0f;
	if(P1!=0x0f)  //说明有按键按下
	{
		delay(1000);//消除抖动
		if(P1!=0x0f) 
		{
		 	switch(P1) //对每一列进行测试
			{
			 	case(0x07):	//转换为二进制为00000111,说明P-13接口有按键按下
					KeyValue=0;
					break;
				case(0x0b): //P-12接口有按键按下
					KeyValue=1;
					break;
				case(0x0d): //P-11接口有按键按下
					KeyValue=2;
					break;
				case(0x0e): //P-10接口有按键按下
					KeyValue=3;
					break;
			}
			P1=0xf0;  //高四位输出高电平,低四位输出低电平
		 	switch(P1)	//测试每一行
			{
			//从每一列的测试跳出后,进入每一行的测试,此时的KeyValue为每一列的值,要想与每一行对应,只需要在每一行+4即可
			 	case(0x70):	//转换为二进制为01110000,说明P-17接口有按键按下
					KeyValue=KeyValue;
					break;
				case(0xb0): //P-16接口有按键按下
					KeyValue=KeyValue+4;
					break;
				case(0xd0): //P-15接口有按键按下
					KeyValue=KeyValue+8;
					break;
				case(0xe0): //P-14接口有按键按下
					KeyValue=KeyValue+16 ;
					break;
			 }
			 //按键松开的判断
			 while((a<50)&&(P1!=0xf0))
			 {
			 	delay(1000);
				a++;
			 }
		}
	}
}


void main()
{	

 	while(1)  
	{
	 	KeyDown();
		P0=~smgduan[KeyValue];
	}
}
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是基于51单片机利用矩阵按键实现密码锁的C语言代码,你可以参考一下: ``` #include <reg52.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int sbit RS = P2^6; // LCD1602液晶显示屏接口定义 sbit RW = P2^5; sbit EN = P2^7; sbit KEY_IN_1 = P1^0; // 矩阵按键接口定义 sbit KEY_IN_2 = P1^1; sbit KEY_IN_3 = P1^2; sbit KEY_IN_4 = P1^3; sbit KEY_OUT_1 = P1^4; sbit KEY_OUT_2 = P1^5; sbit KEY_OUT_3 = P1^6; sbit KEY_OUT_4 = P1^7; uchar password[4] = {1, 2, 3, 4}; // 设置初始密码 uchar keyvalue = 0; uchar keyflag = 0; uchar input_pwd[4] = {0, 0, 0, 0}; uchar input_count = 0; uchar error_count = 0; void init_lcd1602() // LCD1602液晶显示屏初始化 { delay(20); write_com(0x38); delay(5); write_com(0x38); delay(5); write_com(0x38); delay(5); write_com(0x38); delay(5); write_com(0x08); delay(5); write_com(0x01); delay(5); write_com(0x06); delay(5); write_com(0x0c); delay(5); } void delay(uint x) // 延时函数 { uint i, j; for(i = x; i > 0; i--) for(j = 110; j > 0; j--); } void write_com(uchar com) // 写指令函数 { RS = 0; RW = 0; P0 = com; EN = 1; _nop_(); EN = 0; } void write_data(uchar dat) // 写数据函数 { RS = 1; RW = 0; P0 = dat; EN = 1; _nop_(); EN = 0; } void keyscan() // 矩阵按键扫描函数 { KEY_OUT_1 = 0; if(KEY_IN_1 == 0) { keyvalue = 1; keyflag = 1; } if(KEY_IN_2 == 0) { keyvalue = 2; keyflag = 1; } if(KEY_IN_3 == 0) { keyvalue = 3; keyflag = 1; } if(KEY_IN_4 == 0) { keyvalue = 4; keyflag = 1; } KEY_OUT_1 = 1; KEY_OUT_2 = 0; if(KEY_IN_1 == 0) { keyvalue = 5; keyflag = 1; } if(KEY_IN_2 == 0) { keyvalue = 6; keyflag = 1; } if(KEY_IN_3 == 0) { keyvalue = 7; keyflag = 1; } if(KEY_IN_4 == 0) { keyvalue = 8; keyflag = 1; } KEY_OUT_2 = 1; KEY_OUT_3 = 0; if(KEY_IN_1 == 0) { keyvalue = 9; keyflag = 1; } if(KEY_IN_2 == 0) { keyvalue = 10; keyflag = 1; } if(KEY_IN_3 == 0) { keyvalue = 11; keyflag = 1; } if(KEY_IN_4 == 0) { keyvalue = 12; keyflag = 1; } KEY_OUT_3 = 1; KEY_OUT_4 = 0; if(KEY_IN_1 == 0) { keyvalue = 13; keyflag = 1; } if(KEY_IN_2 == 0) { keyvalue = 14; keyflag = 1; } if(KEY_IN_3 == 0) { keyvalue = 15; keyflag = 1; } if(KEY_IN_4 == 0) { keyvalue = 16; keyflag = 1; } KEY_OUT_4 = 1; } void display_pwd() // 显示密码函数 { uchar i; write_com(0x80); write_data('I'); write_data('n'); write_data('p'); write_data('u'); write_data('t'); write_data(':'); for(i = 0; i < 4; i++) { write_data(input_pwd[i] + '0'); } } void main() { init_lcd1602(); // 初始化LCD1602液晶显示屏 while(1) { keyscan(); // 扫描矩阵按键 if(keyflag == 1 && input_count < 4) // 如果有按键按下且密码未输入完整 { input_pwd[input_count++] = keyvalue; // 记录输入的密码 display_pwd(); // 显示输入的密码 keyflag = 0; } if(input_count == 4) // 如果密码输入完整 { if(input_pwd[0] == password[0] && input_pwd[1] == password[1] && input_pwd[2] == password[2] && input_pwd[3] == password[3]) // 如果密码正确,开锁 { write_com(0xc0); write_data('W'); write_data('e'); write_data('l'); write_data('c'); write_data('o'); write_data('m'); write_data('e'); delay(1000); input_count = 0; error_count = 0; write_com(0x01); } else // 如果密码错误 { error_count++; // 记录错误次数 if(error_count >= 3) // 如果错误次数超过3次,锁定系统 { write_com(0x01); write_com(0x80); write_data('S'); write_data('y'); write_data('s'); write_data('t'); write_data('e'); write_data('m'); write_data(' '); write_data('L'); write_data('o'); write_data('c'); write_data('k'); delay(5000); error_count = 0; write_com(0x01); } else // 如果错误次数未超过3次,显示错误信息 { write_com(0xc0); write_data('E'); write_data('r'); write_data('r'); write_data('o'); write_data('r'); write_data('!'); delay(1000); input_count = 0; write_com(0x01); } } } } } ``` 以上代码仅供参考,实际应用中可能还需要根据具体情况进行修改和完善。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小周不摆烂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值