51单片机入门:独立按键(02)

标题:

​ 51单片机入门:独立按键(02)

一、独立按键的基本结构和功能

二、独立按键在单片机的位置

三、初次使用独立按键

设计第1个程序,使用按键K1控制D1的亮灭

C 复制代码
#include<regx52.h>

void main()
{
	while(1)
	{
		if(P3_1 == 0)  // 按下按钮相当于接地 P3_1 == 0; 
		{
			P2_0 = 0;  // 亮
		}
		else
		{
			P2_0 = 1;  // 灭
		}
	}	
}

解释一下为什么是P3_1==0,看原理图可以发现按下后P3_1接地,此时为低电平,且此时P3_1为读取值,所以等于零表示按下独立按键

实现现象:

需要指出的是,由于Proteus软件是在最理想的情况下仿真,完全消除了按键抖动的影响,所以这段简单的代码无法有效实现单次点击后LED常亮或熄灭,关于按键抖动下面会介绍到。

四、新的知识点也是重点:抖动

在我们按下或松开"独立按键"时,由于材料原因金属弹片就会在极短的时间内上下波动,造成整个电路的频繁开关。这段抖动时间极短,大约只有10ms(不会察觉到),但由于单片机运行频率都在兆赫兹,所以这种抖动可以被单片机检测到并做出反应,所以如果不消除抖动的影响就会造成按键"失灵"的现象。

抖动的消除:可以分成硬件消抖和软件消抖(这些图片都是在网上找到的,对于原作者在这里表示感谢。)

硬件消抖原理: 利用电容充/放电需要时间起到延时的作用消抖,这种方式也可以使用软件来实现,下面将会介绍到。

当按下按钮K1后电容开始放电,此时引脚KeyIn1检测到的依然是高电平1,当电容放电结束「在这段时间中按键抖动已消除」KeyIn1接地导通检测到低电平0;当松开按钮K1后电容开始充电,此时引脚keyIn1检测到的依然是低电平0,当电容充电结束「在这段时间中按键抖动已消除」KeyIn1接地导通检测到高电平1。

软件消抖原理:添加延时函数,在按键按下后延时一段时间(一般为20ms)跳过抖动。(重点)

这也是第2个程序:独立按键控制LED状态

C 复制代码
#include<regx52.h>  // 头文件

void Delay(unsigned int n) //设置延时函数,实现软件消抖,这个函数执行依次大约延时1ms
{
	unsigned char j;
	while(n--)
	{
		for(j = 0; j < 113; j++);
	}
}

void main()
{
	while(1)
	{	
		if(P3_1 == 0)
		{
			Delay(20);					//按下按键延时20ms消抖
			while(P3_1 == 0);			//如果按键持续按下,就进入这个循环直到松开,进入下面的延时函数
			Delay(20);					//松开按键延时20ms消抖
			
			P2_0 = ~P2_0;				//取反,实现按键控制LED状态
		}
	}
}

实验现象:

五、独立按键控制LED灯显示二进制

第3个程序:

C 复制代码
#include<regx52.h>

void Delay(unsigned int n)  // 延时函数
{
	unsigned char j;
	while(n--)
	{
		for(j = 0; j < 113; j++);
	}
}

void main()
{
	unsigned char NUM = 0;  //0000 0000 定义初始值
	while(1)
	{
		if(P3_1 == 0)
		{
			Delay(20);
			while(P3_1 == 0);
			Delay(20);
			
			NUM++;		 //举例: 0000 0001  每次加1 实现二进制  如下次为 0000 0010
			P2 = ~NUM;   //举例: 1111 1110  将NUM取反变成 1111 1101 只点亮特定的LED	
		}
	}
}

感觉上面说的不明白,在下面详细解释下:

C 复制代码
// 首先定义无符号字符型变量NUM
// 将 NUM 赋初值为 0  换算为二进制就为 0000 0000 
// 进入 while 循环
	// 按键按下 NUM + 1  此时NUM等于1 二进制表示 0000 0001   取反  1111 1110  点亮D1
	// 按键按下 NUM + 1  此时NUM等于2 二进制表示 0000 0010   取反  1111 1101  点亮D2
	// 按键按下 NUM + 1  此时NUM等于3 二进制表示 0000 0011   取反  1111 1100  点亮D1、D2
	// 依次类推......
	// 按键按下 NUM + 1  此时NUM等于15 二进制表示 1111 1111   取反  0000 0000  点亮D1、D2、D3、D4、D5、D6、D7、D8
	
	// 按下按键 NUM + 1  此时NUM等于16 数据溢出 NUM等于0 开始重新计数

实验现象:

六、独立按键控制LED灯左右移动

这个部分需要重点介绍移位运算符,第4个程序:

C 复制代码
#include<regx52.h>

void Delay(unsigned int n)  // 延时函数
{
	unsigned char j;
	while(n--)
	{
		for(j = 0; j < 113; j++);
	}
}

unsigned char LEDNum = 0; // 定义无符号字符型变量 LEDNum

void main()
{
	P2_0 = 0; // 初始化,点亮第一个LED
	while(1)
	{
		if(P3_0 == 0)
		{
			Delay(20);
			while(P3_0 == 0); // 这部分都是按键操作,下面不再注释
			Delay(20);
			
			LEDNum++;  // 设置移位数
			if(LEDNum >= 8) // 由于是从D1(不是D0)开始移位 LEDNum 等于 7 就是D8点亮,所以当LEDNum等于8时要使其制0归位
				LEDNum = 0; // LEDNum 置0
			
			P2 = ~(0X01 << LEDNum); // << 左移位运算符 举例: 0000 0001  <<  2 就成为 0000 0100 取反 1111 1011
		}
		
		if(P3_1 == 0)
		{
			Delay(20);
			while(P3_1 == 0); // 按键
			Delay(20);
			
			if(LEDNum == 0) // 由于LEDNum是无符合字符型,小于0时LEDNum会从1111 1111倒数,所以要防止其小于0置7,使D8点亮
				LEDNum = 7;
			else
				LEDNum--;   // LEDNum依次递减
			
			P2 = ~(0X01 << LEDNum); // << 左移位运算符 举例: 0000 0001  <<  7 就成为 1000 0000 取反 0111 1111
		}		
	}
}

实验现象:

相关推荐
大梦百万秋3 小时前
嵌入式系统与单片机工作原理详解
单片机·嵌入式硬件
陌夏微秋3 小时前
硬件基础22 反馈放大电路
单片机·嵌入式硬件·硬件架构·硬件工程·智能硬件
电子工程师UP学堂5 小时前
电子应用设计方案-24:智能防火系统方案设计
人工智能·单片机·嵌入式硬件
Winter、rui5 小时前
STM32F103C8T6实时时钟RTC
stm32·单片机·嵌入式硬件
BigShark8886 小时前
2025蓝桥杯(单片机)备赛--扩展外设之PWM的原理与应用(十三)
单片机·职场和发展·蓝桥杯
六壹班班长8 小时前
STM32 外设简介
stm32·单片机·嵌入式硬件
小殷学长8 小时前
【单片机毕业设计12-基于stm32c8t6的智能称重系统设计】
stm32·单片机·课程设计
广药门徒10 小时前
stm32内部高速晶振打开作为主时钟
单片机·嵌入式硬件
陌夏微秋10 小时前
51单片机基础 06 串口通信与串口中断
单片机·嵌入式硬件·51单片机