当前位置: 首页 > article >正文

51单片机按键数码管(简单设计)

        51单片机按键数码管是一个简单的设计项目,使用四位数码管进行显示,矩阵按键加独立按键输入,将读取到据显示在数码管上。

一、参考PCB图

二、参考代码

#include <reg51.h>
// LED数码管引脚定义
sbit LED1 = P2 ^ 0;
sbit LED2 = P2 ^ 1;
sbit LED3 = P2 ^ 2;
sbit LED4 = P2 ^ 3;
// 矩阵按键引脚定义
sbit P1_0 = P1 ^ 0;
sbit P1_1 = P1 ^ 1;
sbit P1_2 = P1 ^ 2;
sbit P1_3 = P1 ^ 3;
sbit P1_4 = P1 ^ 4;
sbit P1_5 = P1 ^ 5;
// 独立按键引脚定义
sbit KEY1 = P1 ^ 6;
sbit KEY2 = P1 ^ 7;
// 按键扫描变量
unsigned char KeyNumber = 0;
unsigned char Matrix_KeyNumber = 0;
// 定义变量存放数码管的数据
unsigned char Dig_Buf[] = {0x00, 0x00, 0x00, 0x00};
// 共阴极数码管表
unsigned char code tab[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C};
//--------------------------------定时器1--------------------------------
void Timer1Init(void)
{
	TMOD &= 0x0F; // 设置定时器16位 2ms
	TMOD |= 0x10;

	TL1 = 0x30;
	TH1 = 0xF8;

	TF1 = 0;
	ET1 = 1;
	EA = 1;
	TR1 = 1;
}

//--------------------------------动态扫描数码管-------------------------------
void Dig_Loop()
{
	// 声明静态变量,每次进入函数值不变
	static unsigned char CNT0 = 0;
	CNT0++;
	if (CNT0 > 3)
	{
		CNT0 = 0;
	}

	P0 = 0x00; // 段码清0,消影
	P2 = 0XFF;

	switch (CNT0) // 位码输出
	{
	case 0:
		LED1 = 0;
		break;
	case 1:
		LED2 = 0;
		break;
	case 2:
		LED3 = 0;
		break;
	case 3:
		LED4 = 0;
		break;
	}
	P0 = Dig_Buf[CNT0]; // 段码输出
}

//--------------------------------矩阵按键部分--------------------------------
unsigned char MatrixKey()
{
	unsigned char KeyNumber = 0;

	P1 = 0xFF;
	P1_0 = 0; // 依次发送低电平扫描按键 先拉高P1,再拉低某一端口

	if (P1_3 == 0)
	{
		KeyNumber = 1;
	}
	if (P1_4 == 0)
	{
		KeyNumber = 2;
	}
	if (P1_5 == 0)
	{
		KeyNumber = 3;
	}

	P1 = 0xFF;
	P1_1 = 0;

	if (P1_3 == 0)
	{
		KeyNumber = 4;
	}
	if (P1_4 == 0)
	{
		KeyNumber = 5;
	}
	if (P1_5 == 0)
	{
		KeyNumber = 6;
	}

	P1 = 0xFF;
	P1_2 = 0;

	if (P1_3 == 0)
	{
		KeyNumber = 7;
	}
	if (P1_4 == 0)
	{
		KeyNumber = 8;
	}
	if (P1_5 == 0)
	{
		KeyNumber = 9;
	}

	return KeyNumber;
}

void Loop_MatrixKey()
{

	static unsigned char LastKey = 0;
	static unsigned char NowKey = 0;

	LastKey = NowKey;
	NowKey = MatrixKey();

	if (LastKey == 0 && NowKey != 0)
	{
		Matrix_KeyNumber = NowKey;
	};
}

//--------------------------------独立按键部分--------------------------------
// 获取当前按键状态
unsigned char KeyState()
{
	unsigned char KeyNum = 0; // 没有按键按下返回0
	if (KEY1 == 0)
	{
		KeyNum = 1;
	}
	if (KEY2 == 0)
	{
		KeyNum = 2;
	}
	return KeyNum;
}
// 循环扫描,相当于沿检测
void Loop_Key()
{
	static unsigned char LastKey = 0, NowKey = 0;
	LastKey = NowKey;	 // 更新按键值
	NowKey = KeyState(); // 获取当前按键状态
	if (LastKey)		 // 判断有无按键按下
	{
		if (NowKey == 0) // 如果按下,获取按键编号
		{
			KeyNumber = LastKey;
		}
	}
}
//--------------------------------数码管显存左移函数--------------------------------
void Dig_Shift(unsigned char NewKey)
{
	Dig_Buf[0] = Dig_Buf[1];
	Dig_Buf[1] = Dig_Buf[2];
	Dig_Buf[2] = Dig_Buf[3];
	Dig_Buf[3] = NewKey;
}
//----------------------------主函数-----------------------------//
void main(void)
{
	// 定时器初始化
	Timer1Init();

	while (1)
	{

		// 按键响应
		if (KeyNumber)
		{ // 独立按键
			if (KeyNumber == 1)
			{ // 按键0
				Dig_Shift(tab[0]);
			}
			if (KeyNumber == 2)
			{ // 清零按键
				Dig_Buf[0] = 0x00;
				Dig_Buf[1] = 0x00;
				Dig_Buf[2] = 0x00;
				Dig_Buf[3] = 0x00;
			}

			KeyNumber = 0;
		}

		if (Matrix_KeyNumber)
		{ // 矩阵按键
			Dig_Shift(tab[Matrix_KeyNumber]);
			Matrix_KeyNumber = 0;
		}
	}
}

//----------------------------定时计数器1的中断服务子程序-----------------------------//
void Time1_ISR(void) interrupt 3
{
	// 重新装载定时器
	static unsigned char T0Count, T1Count = 0;

	TL1 = 0x30;
	TH1 = 0xF8;

	Dig_Loop(); // 数码管扫描

	T0Count++;
	if (T0Count >= 10)
	{ // 20ms进行一次按键扫描
		T0Count = 0;
		Loop_MatrixKey();
	}

	T1Count++;
	if (T1Count >= 15)
	{ // 30ms进行一次按键扫描
		T1Count = 0;
		Loop_Key();
	}
}

三、参考网址

        由于本次项目过于简单,不做过多描述,详情参考我的bilibili:

51单片机按键数码管_哔哩哔哩_bilibili


http://www.kler.cn/news/310491.html

相关文章:

  • Matlab对状态机建模的方法
  • 【C++】猜数字小游戏
  • 什么是 PHP? 为什么用 PHP? 有谁在用 PHP?
  • 【机器学习导引】ch2-模型评估与选择
  • Spring6梳理9—— 依赖注入之注入对象类型属性
  • array和linked list的区别
  • 从IPC摄像机读取视频帧解码并转化为YUV数据到转化为Bitmap
  • 探索Java中的设计模式:原则与实例
  • ubuntu24系统普通用户免密切换到root用户
  • 整流器制造5G智能工厂物联数字孪生平台,推进制造业数字化转型
  • 【Delphi】知道控件名称(字符串),访问控件
  • 数据结构与算法-18算法专向(hash)
  • 浅显易懂的Git教程
  • c基本知识
  • Windows10电脑右下角时间显示到秒
  • Golang | Leetcode Golang题解之第414题第三大的数
  • C++(学习)2024.9.18
  • Zabbix企业分布式监控(Zabbix Enterprise Distributed Monitoring)
  • Electron 图标修改
  • 深度学习 之 常见损失函数简介:名称、作用及用法
  • mysql 8.0 日期维度表生成(可运行)
  • CSS传统布局方法(补充)——WEB开发系列37
  • 【路径规划】WDM网络中RWA问题的教育网络规划工具(基于MILP和启发式)
  • 图说GPT网络结构(参数量与计算量估计)
  • 何时空仓库
  • 计算机毕业设计 乡村生活垃圾管理系统的设计与实现 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试
  • C++《类和对象》(下)
  • 创意照片比赛点子以及Wishpond如何变革您的活动
  • redis常见类型设置、获取键值的基础命令
  • 【工具变量】气候适应型试点城市DID(2005-2022年)