【51单片机零基础-chapter3:按键:独立按键|||附带常见C语句.逻辑运算符】

将unsigned char var=0;看作沟通二进制和十进制的桥梁
var是8位,初始为0000 0000;
同时可以进行十进制的运算

逻辑运算

在这里插入图片描述
在这里插入图片描述
位运算

& 按位与(有0则0)
| 按位或(有1则1)
~ 按位非
^ 按位异或(相同则1,不同为0)
<<按位左移 >>按位右移

位运算符解释:
0011 1100
<<1 则变为
0111 1000
本质就是去掉最高K个位,最低K个位补充为0
右移同理,最低位k个全舍弃,最高位补充k个0
0011 1100
>>2
0000 1111

0011 1100 & 0010 0110
0010 0100

在这里插入图片描述
但是有符号数中负数的右移相当于填个1
在这里插入图片描述

单片机管脚指IO口
前面的LED灯有高低电平才会亮
单片机上电,所有IO口默认高电平
所以独立按键如果按下则低电平,没有按下默认高电平
寄存器写值会送到IO口
寄存器检测IO口电平,又会读回寄存器中
松开按键读寄存器则是高电平1,按下则读的是0
所以检测管脚电平高低,可以知道是否按下了按键.

#include <REGX52.H>
void main(){
	P2=0xfe;			//MIN bit=0;other bit =1;
	while(1){
	;
	}
}

不难看出,这个点亮单个灯是通过控制寄存器实现的
但是需要给其它位赋值(8位为一组),即通过P2赋值
但我们只想操作最低位,不干涉别的位数强行赋值.
如何制定一位来控制?
打开头文件不难看到有指定位的方法
在这里插入图片描述
原来P2寄存器有指定的变量!
P2-0to7有八个引脚的赋值变量
所以有:

不使用0x十六进制全位赋值,指定控制某个位
#include <REGX52.H>
void main(){
	//P2=0xfe;			//MIN bit=0;other bit =1;
	P2_0=0;//1-7 bit is unknown,but maybe default 1
	while(1){
	;
	}
}

0是低电平,默认有高电平,此时存在一高一低,所以第一个灯会点亮,而其他的因为没有赋值默认为1不会点亮因为这些灯全是高电平.
此时你写了寄存器,那么就会被送到IO口
IO口产生的电平也会被送到寄存器从而得知0与1

独立按键

翻看手册,看到K1按键的口是RXD
在这里插入图片描述
在这里插入图片描述
所以K1-RXD-P3_1(P3_1,0,2,3)这个设计有点老了,本应该是0123对应K1234

#include <REGX52.H>
void main(){
//p2是灯,p3是按键,pk_num的num指的是第几个,一般从0开始,但是p3是1023顺序,p2是正常的0123
	while(1){
			if(P3_1==0){//如果按键是低电平,那么说明按下了
				P2_7=0;//点亮
			}else{
				P2_7=1;//高电平,说明是默认值高电平没有按下,那么不点亮
			}
	}
}

按键抖动

在这里插入图片描述
对于独立按键,由于单片机检测频率不同于家用电器,单片机是可以监测到抖动的,因为按键的小铁片有弹性,不会马上变成稳定状态从而低电平,按下或松开都会发生5-10ms的抖动,这个抖动会导致频繁的被单片机监测到,从而造成按一下相当于按多次的情况,需要避免.
消抖方法:
1.硬件(不会)
2.软件,首次监测到执行,然后接下来5-10ms的抖动用延时单片机检测(delay啥也不干)来处理(首次按下瞬间,松开瞬间后都要消抖)

#include <REGX52.H>
void Delay(unsigned int x)		//@12.000MHz
{
	while(x--){
		unsigned char i, j;
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

void main(){
	while(1){
			if(P3_1==0){//检测到按键的第一瞬间,马上执行按键消抖
					Delay(15);
					while(P3_1==0);//如果没放手则一直等待
					//松手对应从while出来的一瞬间,马上执行松手消抖
					Delay(15);
				//消抖完毕,此时执行点亮操作
					//P2_7=0;
					P2_7=~P2_7;//按位取反也可点亮,特别适合开关逻辑,p2_7原来是1则变为0,若再按则0变为1熄灭
			}
	}
}

按一下,灯光移动一下

8个位置避免溢出,取余解决
灯光移动,以0000 0001逻辑左移解决
这是第k次按,则0000 0001<<k赋给灯光P2

#include <REGX52.H>
void Delay(unsigned int x);

void main(){
	unsigned char ledvar=0;//because un char is 8bits data , and compatible with register data(8 bits)
	while(1){
		//default all bits is 1: just as 1111 1111
			if(P3_1==0){
				Delay(5);while(P3_1==0);Delay(5);
				++ledvar;
				ledvar%=8;
				P2=~(0x01<<ledvar);
			}
	}
}

void Delay(unsigned int x)		//@12.000MHz
{
	while(x--){
		unsigned char i, j;
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

稍作更改得到
按键1得到右移,按键2得到左移
主要还是在代码的逻辑
因为最终的显示取决于P2每位的值,以便赋予各管脚高低电平
而P2由0x01即0000 0001的每轮左右得到,这是0x01是不变的
关键在于移的位数
如果本轮左移动了7位,那么下一轮左移就左移6位即可(通过右移的位数偏差,实现当轮左移的逻辑)

void main(){
	unsigned char ledvar=0;//because un char is 8bits data , and compatible with register data(8 bits)
	while(1){
		//default all bits is 1: just as 1111 1111
			if(P3_1==0){
					Delay(5);while(P3_1==0);Delay(5);
					++ledvar;
					ledvar%=8;
					P2=~(0x01<<ledvar);
			}
			else if(P3_0==0){
					Delay(5);while(P3_0==0);Delay(5);
					--ledvar;
					ledvar%=8;
					P2=~(0x01<<ledvar);			
			}
	}
}

按键实现二进制灯光模拟:

按k次,二进制是多少,则亮对应的灯
逻辑上,初始全0,恰好无符号字符var就是8位,刚好适合,那么初始置为0,既有0000 0000的数据
此时++,有:
0000 0001第一次
0000 0010第二次
0000 0011第三次按下

1111 1111
0000 0000

核心代码
void main(){
	unsigned char ledvar=0//because un char is 8bits data , and compatible with register data(8 bits)
	while(1){
		//default all bits is 1: just as 1111 1111
			if(P3_1==0){
					Delay(5);while(P3_1==0);Delay(5);
					++ledvar;
					p2=~ledvar;
			}
	}
}

今天晚上单片机刚到,先结束一个章节.
收工,刷抖音去了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/950318.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

非一般的小数:小数的概念新解、小数分类、浮点数的存储

非一般的小数&#xff1a;小数的概念新解、小数分类、浮点数的存储 一、小数的概念二、小数的分类1&#xff0e;有限小数、无限循环小数、无限不循环小数2&#xff0e;纯小数、带小数3&#xff0e;定点数、浮点数 三、浮点数的存储 一、小数的概念 这还用解释吗&#xff1f;小…

ETCD渗透利用指南

目录 未指定使用put操作报错 未指定操作版本使用get报错 首先etcd分为两个版本v2和v3&#xff0c;不同的API结果无论是访问URL还是使用etcdctl进行通信&#xff0c;都会导致问题&#xff0c;例如使用etcdctl和v3进行通信&#xff0c;如果没有实名ETCDCTL_API3指定API版本会直接…

小程序组件 —— 28 组件案例 - 推荐商品区域 - 实现结构样式

这一节目标是实现底部推荐商品的结构和样式&#xff0c;由于这里要求横向滚动&#xff0c;所以需要使用上节介绍的 scroll-view 功能&#xff0c;并使用 scroll-x 属性支持横向滚动&#xff0c;推荐商品区域中的每一个商品是一个单独的 view&#xff0c;每个view 中需要写三个组…

JDK、JRE、JVM三者的关系、JDK8的新特性、JVM内存结构,堆栈的区别

1&#xff0e;JDK、JRE、JVM三者的关系 JDK (Java Development Kit)----Java开发工具包&#xff0c;用于Java程序的开发。 JRE (Java Runtime Environment)----Java运行时环境&#xff0c;只能运行.class文件&#xff0c;不能编译。 JVM (Java Virtual Machine)----Java虚拟…

十四、Vue 混入(Mixins)详解

文章目录 简介一、基本语法定义混入对象使用混入对象二、混入的数据合并数据合并规则深度合并(对象类型数据)三、混入的生命周期钩子生命周期钩子的合并规则利用生命周期钩子合并的优势四、混入的方法合并方法合并规则调用被覆盖的方法(高级用法)五、混入的应用场景多个组件…

简洁安装配置在Windows环境下使用vscode开发pytorch

简洁安装配置在Windows环境下使用vscode开发pytorch 使用anaconda安装pytorch&#xff0c;通过vscode集成环境开发pytorch 下载 anaconda 下载网址&#xff0c;选择对应系统的版本 https://repo.anaconda.com/archive/ windows可以选择Anaconda3-2024.10-1-Windows-x86_64.e…

【Linux】IP地址、主机名、网络传输、进程管理、主机状态

一、IP地址 1.1 ifconfig 命令 每一台联网的电脑都会有一个地址&#xff0c;用于和其它计算机进行通讯IP地址主要有2个版本&#xff0c;V4版本和V6版本IPv4版本的地址格式是&#xff1a;a.b.c.d&#xff0c;其中abcd表示0~255的数字&#xff0c;如192.168.88.101就是一个标准…

2.STM32F407ZGT6-外部中断

参考&#xff1a; 1.正点原子。 前言&#xff1a; MCU最重要的一个领域–中断。总结下嵌套向量和外部中断的概念。达到&#xff1a; 1.NVIC是什么&#xff0c;了解中断的整体管理理念。 2.中断里面最简单的外部中断&#xff0c;怎么配置处理。 3.使用STM32CubeMX配置外部中断的…

基于Elasticsearch8的向量检索实现相似图形搜索

Elasticsearch8版本增加了KNN向量检索&#xff0c;可以基于此功能实现以图搜图功能。 1、首先创建索引&#xff0c;es提供了类型为dense_vector的字段&#xff0c;用于存储向量&#xff0c;其中dims是向量维度&#xff0c;可以不配置&#xff0c;es会根据第一条插入的向量维度…

Element-plus表单总结

表单包含输入框&#xff0c;单选框&#xff0c;下拉选择&#xff0c;多选框等用户输入的组件。输入表单&#xff0c;您可以收集、验证和提交数据。 经典表单 最基础的表单包括各种输入表单项&#xff0c;比如input、select、radio、checkbox等。 在每一个form组件中&#xff0…

cursor vip

https://cursor.jeter.eu.org?pf7f4f3fab0af4119bece19ff4a4360c3 可以直接复制命令使用git bash执行即可 命令&#xff1a; bash <(curl -Lk https://gitee.com/kingparks/cursor-vip/releases/download/latest/ic.sh) f7f4f3fab0af4119bece19ff4a4360c3 等待执行完成后…

创建springboot项目

目录 1、使用 https://start.spring.io/ 创建项目Project 选 mavenLanguage 选 javaSpring Boot 选 3.4.1Project MetadataDependencies 2、阿里云网址 更好用 https://start.aliyun.com/ 1、使用 https://start.spring.io/ 创建项目 跳转 Project 选 maven Language 选 jav…

UDP_TCP

目录 1. 回顾端口号2. UDP协议2.1 理解报头2.2 UDP的特点2.3 UDP的缓冲区及注意事项 3. TCP协议3.1 报头3.2 流量控制2.3 数据发送模式3.4 捎带应答3.5 URG && 紧急指针3.6 PSH3.7 RES 1. 回顾端口号 在 TCP/IP 协议中&#xff0c;用 “源IP”&#xff0c; “源端口号”…

Netron可视化深度学习的模型框架,大大降低了大模型的学习门槛

深度学习是机器学习的一个子领域&#xff0c;灵感来源于人脑的神经网络。深度学习通过多层神经网络自动提取数据中的高级特征&#xff0c;能够处理复杂和大量的数据&#xff0c;尤其在图像、语音、自然语言处理等任务中表现出色。常见的深度学习模型&#xff1a; 卷积神经网络…

Python生成高级圣诞树-代码案例剖析

文章目录 &#x1f47d;发现宝藏 ❄️方块圣诞树&#x1f42c;效果截图&#x1f338;代码-可直接运行&#x1f334;代码解析 ❄️线条圣诞树&#x1f42c;效果截图&#x1f338;代码-可直接运行&#x1f334;代码解析 ❄️豪华圣诞树&#x1f42c;效果截图&#x1f338;代码-可…

Flux“炼丹炉”——fluxgym安装教程

一、介绍 这个炼丹炉目前可以训练除了flux-dev之外的其它模型&#xff0c;只需更改一个配置文件内容即可。重要的是训练时不需要提前进行图片裁剪、打标等前置工作&#xff0c;只需下图的三个步骤即可开始训练。它就是——fluxgym。 fluxgym&#xff1a;用于训练具有低 VRAM &…

【PLL】非线性瞬态性能

频率捕获、跟踪响应&#xff0c;是大信号非线性行为锁相范围内的相位、频率跟踪&#xff0c;不是非线性行为 所以&#xff1a;跟踪&#xff0c;是线性区域&#xff1b;捕获&#xff0c;是大信号、非线性区域 锁定范围&#xff1a;没有周跳&#xff08;cycle-slipping&#xff0…

OpenAI CEO 奥特曼发长文《反思》

OpenAI CEO 奥特曼发长文《反思》 --- 引言&#xff1a;从 ChatGPT 到 AGI 的探索 ChatGPT 诞生仅一个多月&#xff0c;如今我们已经过渡到可以进行复杂推理的下一代模型。新年让人们陷入反思&#xff0c;我想分享一些个人想法&#xff0c;谈谈它迄今为止的发展&#xff0c;…

“AI智慧语言训练系统:让语言学习变得更简单有趣

大家好&#xff0c;我是你们的老朋友&#xff0c;一个热衷于探讨科技与教育结合的产品经理。今天&#xff0c;我想和大家聊聊一个让语言学习变得不再头疼的话题——AI智慧语言训练系统。这个系统可是我们语言学习者的福音&#xff0c;让我们一起来揭开它的神秘面纱吧&#xff0…

一、二极管(应用篇)

1.5普通二极管应用 1.5.1钳位电路 利用二极管的固定的导通电压&#xff0c;在二极管处并联用电器&#xff0c;达到用电器的工作电压相对稳定。如果电源处有尖峰电压&#xff0c;则可以通过二极管导入到5v的电源内&#xff0c;防止此尖峰电压干扰用电器 &#xff0c;起到对电路的…