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

51单片机-第十节-独立按键及数码管优化

一、优化独立按键:

独立按键的实现中,为了解决抖动问题(在按下和抬起时,按键会在高低电平之间抖动10ms),我们在按下后Delay(20),随后进入循环,直到检测到按键抬起,再Delay(20),跳出循环。

(1)问题

如果按住按键不抬,程序会停止在独立按键的函数中。

unsigned char Key()
{
	unsigned char KeyNumber = 0;

	if (P3_1 == 0) { Delay(20); while (P3_1 == 0); Delay(20); KeyNumber = 1; }
	if (P3_0 == 0) { Delay(20); while (P3_0 == 0); Delay(20); KeyNumber = 2; }
	if (P3_2 == 0) { Delay(20); while (P3_2 == 0); Delay(20); KeyNumber = 3; }
	if (P3_3 == 0) { Delay(20); while (P3_3 == 0); Delay(20); KeyNumber = 4; }
	//这里顺序是乱的,是单片机型号决定的

	return KeyNumber;
}

(2)优化

利用定时器,每隔20ms(跳过抖动)检测一次独立按键情况,当按键抬起再执行操作。 

//获取独立按键键码,无按下时返回0
unsigned char Key()
{
	unsigned char Temp;
	Temp = Key_KeyNumber;
	Key_KeyNumber = 0;
	return Temp;
}
unsigned char Key_GetState()
{
	unsigned char KeyNumber = 0;

	if (P3_1 == 0) { KeyNumber = 1; }
	if (P3_0 == 0) { KeyNumber = 2; }
	if (P3_2 == 0) { KeyNumber = 3; }
	if (P3_3 == 0) { KeyNumber = 4; }
	//这里顺序是乱的,是单片机型号决定的

	return KeyNumber;
}
unsigned char Key_KeyNumber;
//独立按键中断,必须将此函数放入main的中断函数中,且中断时长20ms
void Key_Loop()
{
	static unsigned char NowState, LastState;
	LastState = NowState;
	NowState = Key_GetState();
	if (LastState == 1 && NowState == 0) { Key_KeyNumber = 1; }
	if (LastState == 2 && NowState == 0) { Key_KeyNumber = 2; }
	if (LastState == 3 && NowState == 0) { Key_KeyNumber = 3; }
	if (LastState == 4 && NowState == 0) { Key_KeyNumber = 4; }
}

中断函数:

void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count1, T0Count2 = 0;
	T0Count1++; 
	TH0 = 64535 / 256;
	TL0 = 64535 % 256 + 1;
	if (T0Count1 >= 20)
	{
		T0Count1 = 0;
		//需执行的操作
		Key_Loop();
	}
}

二、优化数码管:

在实现数码管时, 我们实现了在指定位置显示指定数字,并在显示一下后清零。

(1)问题:

由于每次数码管显示只显示一下,因此当一次while循环的时间过长,会导致数码管帧率过低,发生闪烁现象。

//数码管,在指定位置(1-8)显示指定数字
void Nixie(unsigned char Location, int Number)
{
	switch (Location)
	{
	case 1:P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
	case 2:P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
	case 3:P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
	case 4:P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
	case 5:P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
	case 6:P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
	case 7:P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
	case 8:P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
	}

	unsigned char NixieTable[10] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F };
	P0 = NixieTable[Number];

	Delay(1);
	P0 = 0x00;//显示一下后清零
}

(2)优化:

unsigned char Nixie_Buf[9] = { 0,10,10, 10, 10, 10, 10, 10, 10, };
void Nixie_SetBuf(unsigned char Location, unsigned char Number)
{
	Nixie_Buf[Location] = Number;
}
//数码管,在指定位置(1-8)显示指定数字
void Nixie_Scan(unsigned char Location, int Number)
{
	P0 = 0x00;//显示一下后清零
	switch (Location)
	{
	case 1:P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
	case 2:P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
	case 3:P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
	case 4:P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
	case 5:P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
	case 6:P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
	case 7:P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
	case 8:P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
	}

	unsigned char NixieTable[11] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00 };
	P0 = NixieTable[Number];
}
void Nixie_Loop()
{
	static unsigned char i = 1;
	Nixie_Scan(i,Nixie_Buf[i]);
	i++;
	if (i >= 9) i = 1;
}


http://www.kler.cn/a/288471.html

相关文章:

  • Vue.js 项目创建流程
  • 前端常用布局模板39套,纯CSS实现布局
  • C++,STL 054(24.11.13)
  • 使用pdfjs加载多页pdf并实现打印
  • Redis高可用-主从复制
  • 猿创征文|Inscode桌面IDE:打造高效开发新体验
  • shell脚本—————局域网IP扫描
  • 开放式耳机漏音有多大?五大超值爆款推荐!
  • 【数据可视化技术】使用Matplotlib、Seaborn进行数据可视化
  • 9、Django Admin优化查询
  • 【2025考研英语高分写作:写作核心词汇】三、人生哲理类
  • Django中的第一个自动化测试编写
  • VS Code CMake tool 配置
  • Apple LLM: 智能基础语言模型(AFM)
  • Apache Struts2开发模式漏洞解析与修复
  • 温湿度传感器和IOT网关的连接 485接口
  • 嵌入式OTG硬件电路分析
  • 矩阵性质简介
  • 51单片机波特率的计算方法
  • kafka单条消息过大发送失败
  • CTF Show逆向4reserve wp--mingyue
  • 滑动窗口系列(不定长滑动窗口长度) 9/2
  • 09--kubernetes持久化存储和StatefulSet控制器
  • Ubuntu最新镜像下载,国内镜像源地址大全
  • RocketMQ集群搭建,及RocketMQ-Dashboard部署(前RocketMQ-Console)
  • vscode远程连接服务器并根据项目配置setting.json