/***
*顺序:按键为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++);
}
上一篇:C51单片机四位数码管动态显示2020
下一篇:一块51单片机能做出些什么东西?
推荐阅读最新更新时间:2026-03-19 10:42
- 基于 Blackfin 数字信号处理器 (DSP) 的 ADZS-BF518F-EZLITE、ADSP-BF518F EZ-Kit Lite 评估系统
- 使用 ON Semiconductor 的 CAT3200Z 的参考设计
- LTC2162 演示板,16 位 65Msps ADC,LVDS 输出,5-140MHz
- 使用 Analog Devices 的 LTC3526BEDC-2 的参考设计
- LT3091HT7 在极低输出电压下低压降操作的典型应用
- 蓝牙协议分析工具nRF52840 MDK USB Dongle
- NCV2902DR2G 维恩桥振荡器运算放大器的典型应用
- LTC4100EGN 演示板,智能电池充电器 DCIN = 15V-20V / 3.5V
- TC78H620FNG 双桥直流有刷电机驱动器评估板
- 带有 DRP w/Try.SRC 和 Type-C 插座的 PTN5110 USB PD 的典型应用

89s51单片机USB-ISP下载线制作教程
51单片机产生高频方波信号的方法
基于51单片机的压力检测报警
非常经典的关于LLC的杨波博士论文
NJM5532S
1-292148-8






京公网安备 11010802033920号