单片机——矩阵按键模块

该文介绍了一个基于单片机的矩阵按键扫描程序,包括延时函数用于消除按键抖动,通过行列扫描确定按下按键的位置,以及使用数码管显示按键数值。在按键扫描过程中,首先进行列扫描,然后进行行扫描,结合两者信息确定具体按键。数码管显示模块通过段选和位选控制数码管显示按键号码。
摘要由CSDN通过智能技术生成

主要目的
学会按键扫描
1.延时函数
延时函数部分详见链接: 单片机控制一盏灯的亮与灭程序解释

 void delay (uint k)		   //定义延时函数
 {
 uint i,j;
 for(i<0;i<k;i++)
    {
	for(j=0;j<113;j++)
	  {
	   ;
	  }
    }
 }

这个程序里面的延时函数的目的是按键消抖。
2.按键扫描模块
这是本次实验的重点,将详细介绍。
先来观察矩阵按键模块的连接
在这里插入图片描述
总共8个口。
先实现关于列的扫描,设置初始值(0xf0),从高到低为

端口Value
P3.71
P3.61
P3.51
P3.41
P3.30
P3.20
P3.10
P3.00

那么当按下按键0,4,8,c时,P3.4变成了0,于是P3就变成了0xe0

端口Value
P3.71
P3.61
P3.51
P3.40
P3.30
P3.20
P3.10
P3.00

从而由0xe0我们可以判断是那一列按键按下,但还是不知道具体是哪一个按键按下,于是我们需要继续进行行扫描。
此时初始化P3

端口Value
P3.70
P3.60
P3.50
P3.40
P3.31
P3.21
P3.11
P3.01

在这里插入图片描述
同时现在当按键0按下后

端口Value
P3.70
P3.60
P3.50
P3.40
P3.31
P3.21
P3.11
P3.00

经过行列扫描之后就可以确定具体是哪个按键按下,有了上面的基础之后,我们来学习按键扫描的程序。

void keyscan()   //这个实验的重点
 { uchar a; 
   P3=0xf0;
   if(P3!=0xf0)
     {
	  delay(10);
	  if(P3!=0xf0)
	  {
	   P3=0xf0;		  //进行列扫描
	   switch(P3)
	   {
	   case(0xe0):keynumber=0;break;	//11100000
	   case(0xd0):keynumber=1;break;//11010000
	   case(0xb0):keynumber=2;break;//10110000
	   case(0x70):keynumber=3;break;//01110000
	   }
	    P3=0x0f;
	   switch(P3)
	   {
	   case(0x0e):keynumber=keynumber;break;   //switch case后面是冒号
	   case(0x0d):keynumber=keynumber+4;break;
	   case(0x0b):keynumber=keynumber+8;break;
	   case(0x07):keynumber=keynumber+12;break;
	   }
	   
	  while ((a<50)&&(P3!=0x0f))
	  {
	  delay(10);
	  a++ ;
	  }	
	  }

	 }
   
  
 }

程序的逻辑是
让P3的高四位为0,进行列检测,为什么是列检测呢,很简单,因为区分不出行。
如果按键按下,延时10ms,判断是不是按键抖动,延时之后继续判断,发现仍然不为0xf0,说明按键确实按下了,然后还是给P3幅初始值0xf0,接下来进行switch,case,不同P3情况下,对设置的keynumber进行赋值,记得每一个case结束要加break。
只有列扫描,无法判断是哪个按键按下,接下来进行行扫描。
基本原理和上面一样,但是注意按键值的变化。
最后当两个情况同时不成立后跳出循环。这两个情况就是a>50和P3=0xf0,具体解释就是a>50,按键还没有松开,就认为松开了,P3=0xf0按键按下之后松开了。
3.数码管显示模块
这一部分也相对简单,我的博客里面也有相应的博文。在这里主要就是P0口接的是数码管。这里进行段选和位选。段选是根据keynumber的值,位选这里选了六个数码管,则对应11000000,再转换为16进制。
在这里插入图片描述

 void display(uchar num)
 {
   P0=table[num];
   duan=1;
   duan=0;
   P0=0xc0;//11000000
   wei=1;
   wei=0;
 }

4.主函数
主要是设置段和位初始状态,之后调用前面的按键扫描和数码管显示模块。

 void main()
 {
 duan=0;
 wei=0;
 while(1)
 {
  keyscan();
  display(keynumber);
 }
 }

完整代码

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int	   //注意宏定义不能加分号


sbit duan = P2^6; 
sbit wei = P2^7;

uchar keynumber; 
uchar code table[]=	{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
 
 void delay (uint k)		   //定义延时函数
 {
 uint i,j;
 for(i<0;i<k;i++)
    {
	for(j=0;j<113;j++)
	  {
	   ;
	  }
    }
 }

  void keyscan()   //这个实验的重点
 { uchar a; 
   P3=0xf0;
   if(P3!=0xf0)
     {
	  delay(10);
	  if(P3!=0xf0)
	  {
	   P3=0xf0;		  //进行列扫描
	   switch(P3)
	   {
	   case(0xe0):keynumber=0;break;	//11100000
	   case(0xd0):keynumber=1;break;//11010000
	   case(0xb0):keynumber=2;break;//10110000
	   case(0x70):keynumber=3;break;//01110000
	   }
	    P3=0x0f;
	   switch(P3)
	   {
	   case(0x0e):keynumber=keynumber;break;   //switch case后面是冒号
	   case(0x0d):keynumber=keynumber+4;break;
	   case(0x0b):keynumber=keynumber+8;break;
	   case(0x07):keynumber=keynumber+12;break;
	   }
	   
	  while ((a<50)&&(P3!=0x0f))
	  {
	  delay(10);
	  a++ ;
	  }	
	  }

	 }
   
  
 }

  void display(uchar num)
 {
   P0=table[num];
   duan=1;
   duan=0;
   P0=0xc0;//11000000
   wei=1;
   wei=0;
 }

 void main()
 {
 duan=0;
 wei=0;
 while(1)
 {
  keyscan();
  display(keynumber);
 }
 }

运行结果
无法一一展示,这里只展示一部分。
在这里插入图片描述
好啦,今天矩阵按键模块的学习就到这里啦。你学废了吗?有问题的话,欢迎共同交流。最近在准备研究生复试,内容比较粗糙,但个人比较喜欢有输出的学习。以后有机会的话,会继续更新完善的!!!

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值