教程:用8051单片机实现矩阵式键盘控制

前言

在嵌入式系统设计中,键盘输入与LED显示是常见的交互方式,特别是在基于8051微控制器的项目中。本文将深入探讨一个具体的实现案例:如何使用8051微控制器配合8255并行接口芯片,实现一个4x4矩阵键盘的扫描与译码,并将扫描到的键值实时显示在LED显示器上。

正文

首先,明确我们的目标:

现在,让我们打开仿真软件和编程软件。再次明确我们的目标,然后就可以画出如下仿真图:

接下来就可以准备编程了。

首先,我们需要对8255芯片进行初始化,设置其控制寄存器(COM8255)以配置PA、PB为输出端口(用于LED显示和可能的控制信号),PC的高四位为输出(用于键盘行扫描),低四位为输入(用于读取键盘列状态)。这些配置通过向8255的控制寄存器写入特定的值来完成。

arduino 复制代码
#include <reg51.h>
#include <stdio.h>
xdata unsigned char COM8255   _at_  0x8006;
xdata unsigned char PA8255   _at_  0x8000;
xdata unsigned char PB8255   _at_  0x8002;
xdata unsigned char PC8255   _at_  0x8004;

unsigned char tab[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
unsigned char dat,col,rol;

在键盘扫描和LED显示过程中,需要用到延时函数来控制扫描速度和显示稳定性。我们定义了两个延时函数:delay20ms用于较长的延时(如LED显示),而delay用于较短的延时(如键盘扫描中的去抖动)。这些函数通过嵌套循环实现,具体的延时时间取决于循环次数和微控制器的时钟频率。

arduino 复制代码
void  delay20ms(unsigned char  t)
{
   unsigned char a,b;
   a=0xff;
   b=t;
   while(b)
   { while(a--);
      b--;
   }
}
void delay(unsigned char m)
{
   unsigned char n;
   while(m)
   {
      for(n=110;n>0;n--);
	 m--;
   }
}

keyscan函数是键盘扫描的核心。它通过逐行将PC端口的高四位设置为低电平(其余为高电平),模拟键盘的逐行扫描。然后,读取PC端口的低四位来检测哪一列有按键被按下(被按下的键会将对应列拉低)。根据读取到的列值和当前扫描的行号,可以计算出被按下键的索引值,并返回该值。

ini 复制代码
unsigned char  keyscan(void)
{
   unsigned char i,t,k,m;
   m=0xef;           //扫描初值。   PC4输出0,即扫描PC4线
   for(i=0;i<4;i++)
   {
   PC8255=m;     //输出行线(高四位) 
   delay(1);
   t=PC8255;     //读取列线(低四位)
   t|=0xf0;
   switch(t)
   {
      case 0xfe: k=4*i;
	         break;
      case 0xfd: k=4*i+1;
	         break;
      case 0xfb: k=4*i+2;
	         break;
      case 0xf7: k=4*i+3;
	         break;
    
   }
   m=m<<1;       //"0"向左移动,扫描下一行
   m|=0x01;
 }
 return(k);
}

display函数负责将扫描到的键值显示在LED显示器上。首先,它设置PB端口(或另一个控制信号端口,取决于电路设计)以启用LED显示。然后,根据键值从预设的LED编码表(tab数组)中查找对应的编码,并将该编码输出到PA端口。最后,通过延时保持显示稳定。

ini 复制代码
void  display(unsigned char ch)
{
   PB8255=0x1;
  
   PA8255=tab[ch];
   delay20ms(100);
  
}

main函数中,我们首先完成系统的初始化工作,包括设置8255的控制寄存器。然后,进入一个无限循环,不断调用keyscan函数扫描键盘,并将扫描到的键值通过display函数显示在LED显示器上。这样,就实现了键盘输入与LED显示的实时交互。

scss 复制代码
void main(void)
 { 
    COM8255=0x81;         //8255 PA、PB输出,PC7--PC4输出,PC3--PC0输入
   
   // Write your code here
   while (1)
   {     
      dat=keyscan();
      display(dat);
   }
}

结语

这样,通过精心设计的扫描算法和显示逻辑,我们最终实现了高效的键盘输入和直观的LED显示。希望这个讲解能帮到你,如果你有任何疑问,欢迎留言!

相关推荐
努力努力再努力wz21 小时前
【C++进阶系列】:万字详解智能指针(附模拟实现的源码)
java·linux·c语言·开发语言·数据结构·c++·python
凤年徐21 小时前
【C++】string的模拟实现
c语言·开发语言·c++
嘿嘿嘿x31 天前
什么是输入寄存器 什么是输出寄存器 什么是写输入寄存器 什么是读保持寄存器
单片机
hazy1k1 天前
K230基础-获取触摸坐标
图像处理·stm32·单片机·嵌入式硬件·k230
迎風吹頭髮1 天前
UNIX下C语言编程与实践59-UNIX TCP 数据传输:send 与 recv 函数的使用与数据处理
c语言·网络·unix
迎風吹頭髮1 天前
UNIX下C语言编程与实践55-TCP 协议基础:面向连接的可靠传输机制与三次握手、四次挥手
c语言·网络·unix
迎風吹頭髮1 天前
UNIX下C语言编程与实践35-UNIX 守护进程编写:后台执行、脱离终端、清除掩码与信号处理
java·c语言·unix
酷飞飞1 天前
掌握DMA基于GD32F407VE的天空星的配置
stm32·单片机·嵌入式硬件·arm
清风6666661 天前
基于单片机的Boost升压斩波电源电路
单片机·嵌入式硬件·毕业设计·课程设计
qiuiuiu4131 天前
正点原子RK3568学习日记-GIT
linux·c语言·开发语言·单片机