单片机
返回首页

51单片机day3——矩阵键盘控制数码管显示

2025-09-30 来源:bilibili

/***

*矩阵键盘控制数码管显示

*顺序:按键为4*4矩阵键盘,左上角为1号、横向排列

*数码管用单片机P0^0-P0^7引脚控制

*矩阵键盘接口:

*       1.单片机P1^0接口连接到第四列的右端

*       2.单片机P1^1接口连接到第三列的右端

*       3.单片机P1^2接口连接到第二列的右端

*       4.单片机P1^3接口连接到第一列的右端

*       4.单片机P1^4接口连接到第四行的左端

*       4.单片机P1^5接口连接到第三行的左端

*       4.单片机P1^6接口连接到第二行的左端

*       4.单片机P1^7接口连接到第一行的左端

*原理:

*   1.独立按键扫描原理是向其两端输入高低不同的电平,按键未按下时电平高低不动,按键按下时低电平会把高电平拉低,检测高电平引脚状态可得知按键是否按下

*   2.矩阵键盘是将按键n*n进行排列,每列的右端相连再连接到单片机的一个引脚上,每行的左端相连再连接到单片机的一个管脚上,使用时向按键的左右引脚发送不同的高低电平信息,检测高电平引脚电平是否被拉低(按键按下),若高电平引脚被拉低可以确定此行/列有按键被按下,然后向按键的左右引脚发送与原来相反的高低电平确定具体是哪个按键被按下

*思路:

*   1.定义行和列两个变量来确定被按下的具体是哪个按键

*   2.用两位数码管显示被按下的按键

***/


#include "reg52.h"


void delay(int a);     //延时函数

void ajpd(void);      //按键判断

void smgxs(void);  //数码管显示


sbit YMQA=P2^2;       //接到译码器A角

sbit YMQB=P2^3;       //接到译码器B角

sbit YMQC=P2^4;       //接到译码器C角


int smg[10]={0x3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};   //显示0-9的编码数组


int key=0;         //存放按键的值

void main(void)

 while(1)

 {

  ajpd();         //判断是否有按键,有按键的话把按键编号记录到变量key里

  smgxs();        //用数码管显示按键的编号,未按过键则显示key初始值(00)

 }

}


void ajpd(void)

{

 int hang=-1,lie=-1;    //存放按键的行和列

  P1 = 0X0F;       //向矩阵键盘的列发送高电平、行发送低电平,先确认被按下的列

  if(P1 != 0X0F)     //如果有按键按下(高电平被拉低)

  {

   delay(4000);     //消抖

   if(P1 != 0X0F)    //再次判断是否被按下

   {

    switch (P1)     //判断P1(矩阵键盘接口)的状态(哪列被按下(高电平被拉低))

    {

     case 0x0E : lie = 4; break;    //第四列被按下(P1^0接口电平被拉低)

     case 0x0D : lie = 3; break;    //第三列被按下(P1^1接口电平被拉低)

     case 0x0B : lie = 2; break;    //第二列被按下(P1^2接口电平被拉低)

     case 0x07 : lie = 1; break;    //第一列被按下(P1^3接口电平被拉低)

    }

    P1 = 0XF0;     //确认按下的列后给矩阵键盘的行发送高电平,列发送低电平,确认哪行被按下

    if(P1 != 0XF0)   //如果按键被按下

    {

     switch (P1)    //判断P1(矩阵键盘接口)的状态(哪行被按下(高电平被拉低))

     {

      case 0xE0 : hang = 4; break;  //第四行被按下(P1^4接口电平被拉低)

      case 0xD0 : hang = 3; break;  //第三行被按下(P1^5接口电平被拉低)

      case 0xB0 : hang = 2; break;  //第二行被按下(P1^6接口电平被拉低)

      case 0x70 : hang = 1; break;  //第一行被按下(P1^7接口电平被拉低)

     }

    }

   }

  }

   while((P1 != 0xF0) && (P1 != 0X0F)) ; //等待按键松手

  if(lie != -1 && hang != -1)       //如果列和行都有数据(判定是一次完整的按键)

  {

  key = lie + ((hang-1)*4);       //把按键的行和列转换为编号赋值给key(列+(行-1)*4)(4*4的矩阵键盘的第列个+上面行的行数*上面每行的个数)

  }

}


void smgxs(void)       //数码管后两位显示按键的数值

{

     /*显示最后一个个数码管(个位)*/

 YMQA = 0;          //给译码器的A引脚输送数据选中数码管的最后一个数码管

 YMQB = 0;          //给译码器的B引脚输送数据选中数码管的最后一个数码管

 YMQC = 0;          //给译码器的C引脚输送数据选中数码管的最后一个数码管

 P0 = smg[key%10];      //给P0口(控制数码管显示字符)输送数据显示key%10的数值(个位数)

 delay(5);          //延时以方便观察(延时后数码管亮度提高)

 P0=0X00;          //数码管消隐(多个数码管同时显示的时候不消隐会互相干扰)

     /*显示倒数第二个数码管(十位)*/

 YMQA = 1;          //给译码器的A引脚输送数据选中数码管的倒数第二个数码管

 YMQB = 0;          //给译码器的B引脚输送数据选中数码管的倒数第二个数码管

 YMQC = 0;          //给译码器的C引脚输送数据选中数码管的倒数第二个数码管

 P0 = smg[key/10];      //给P0口(控制数码管显示字符)输送数据显示key/10的数值(十位数)

 delay(5);          //延时以方便观察(延时后数码管亮度提高)

 P0=0X00;          //数码管消隐(多个数码管同时显示的时候不消隐会互相干扰

}


void delay(int a)  //延时函数

{

  int i;

  for(i=0;i<a;i++);

}


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦线性调频增强器

  • 家用电器遥控器

  • 12V 转 28V DC-DC 变换器(基于 LM2585)

  • 红外开关

  • DS1669数字电位器

  • HA1377 桥式放大器 BCL 电容 17W(汽车音频)

    相关电子头条文章