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

02:项目二:感应开关盖垃圾桶

感应开关盖垃圾桶

  • 1、PWM开发SG90
    • 1.1、怎样通过C51单片机输出PWM波?
    • 1.2、通过定时器输出PWM波来控制SG90
  • 2、超声波测距模块的使用
  • 3、感应开关盖垃圾桶

需要材料:
1、SG90舵机模块
2、HC-SR04超声波模块
3、震动传感器
4、蜂鸣器
5、若干杜邦线

1、PWM开发SG90

  • PWM波为脉冲宽度调制,对模拟信号电平进行数字编码。通过调节占空比的变化来调节信号。
  • 占空比:高电平的时间/整个信号的周期。

1.1、怎样通过C51单片机输出PWM波?

如果芯片内部模块能集成输出,一般观察手册或者芯片IO口都会标明这个是否是PWM口
如果没有集成PWM功能,可以通过IO口软件模拟,

1.2、通过定时器输出PWM波来控制SG90

在这里插入图片描述
如图为SG90舵机模块,黄色为PWM信号控制,红色和褐色分别为VCC和GND。当输入的PWM的占空比不同的时候,舵机模块的摆头幅度不同。一般情况如下:

  • PWM波的频率不能太高,大约50HZ,即周期=1/频率=1/50=0.02s,20ms左右
    0.5ms-------------0度; 2.5% 对应1/40,
    1.0ms------------45度; 5.0% 对应2/40
    1.5ms------------90度; 7.5% 对应3/40
    2.0ms-----------135度; 10.0% 对应4/40
    2.5ms-----------180度; 12.5% 对应5/40

接下来通过C51单片机输出PWM波控制舵机的摆头(黄线连接P1.1口)代码如下:

#include <REGX52.H>sbit sg_90 = P1^1;//黄线连接P1.1口
int cnt = 0;	//标志位
int jd;			//占空比的分子void Delay300ms()		//@11.0592MHz
{unsigned char i, j, k;i = 3;j = 26;k = 223;do{do{while (--k);} while (--j);} while (--i);
}void Delay2000ms()		//@11.0592MHz
{unsigned char i, j, k;i = 15;j = 2;k = 235;do{do{while (--k);} while (--j);} while (--i);
}void Timer0_Init(void)
{TMOD = 0x01;//配置定时器T0为16位定时器TL0 = 0x33;	//定时器计1个数为1.085us,则当舵机为0度的时候,需要0.5ms,            TH0 = 0xFE;	//则定一个0.5ms的定时器TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时ET0 = 1;EA = 1;
}void main(void)
{ Delay300ms();//给硬件准备时间Timer0_Init();jd = 1;//一上电,开始占空比为1/40,为0度cnt = 0;sg_90 = 1;//先给输出引脚一个高电平while(1){//角度由135度到0度来回摆动jd = 4;cnt = 0;Delay2000ms();jd = 1;cnt = 0;Delay2000ms();}
}void Timer0_Handler() interrupt 1//中断函数
{cnt++;TL0 = 0x33;	           TH0 = 0xFE;//控制PWM波的占空比if(cnt < jd){sg_90 = 1;}else{sg_90 = 0;}if(cnt == 40){cnt = 0;sg_90 = 1;}
}

2、超声波测距模块的使用

在这里插入图片描述

  • 怎么让它发送波
    Trig ,给Trig端口至少10us的高电平
  • 怎么知道它开始发了
    Echo信号,由低电平跳转到高电平,表示开始发送波
  • 怎么知道接收了返回波
    Echo,由高电平跳转回低电平,表示波回来了
  • 怎么算时间
    Echo引脚维持高电平的时间!
    波发出去的那一下,开始启动定时器。波回来的那一下,我们开始停止定时器,计算出中间经过多少时间。距离 = 速度 (340m/s)* 时间/2

在这里插入图片描述

/*通过超声波模块控制LED1灯的亮灭,当手靠近超声波模块时,灯亮*/
#include <REGX52.H>sbit Trig = P1^5;
sbit Echo = P1^6;
sbit LED1 = P3^7;void Delay10us()		//@11.0592MHz
{unsigned char i;i = 2;while (--i);
}void Timer0_Init(void)
{TMOD = 0x01;TL0 = 0;TH0 = 0;//设置定时器T0从0开始数数
}void Delay200ms()		//@11.0592MHz
{unsigned char i, j, k;i = 2;j = 103;k = 147;do{do{while (--k);} while (--j);} while (--i);
}void main(void)
{double time;double dis;Timer0_Init();while(1){Delay200ms();//先给单片机准备时间//1、开始发波Trig = 0;Trig = 1;Delay10us();Trig = 0;//2、检测ECHO引脚电平while(Echo == 0);TR0 = 1;													//启动定时器while(Echo == 1);TR0 = 0;													//关闭定时器//3、计算定时开到定时关的时间(计算数的个数),//2位二进制11,01。合并位1101怎么算?1101为(11*2^2)+01=13time = (TH0 * 256 + TL0) * 1.085; //us为单位//34000cm/s = 34cm/ms = 0.034cm/usdis = time * 0.017;							  //cm为单位if(dis < 10){LED1 = 0;}else{LED1 = 1;}TL0 = 0;TH0 = 0;//定时器清零,以便下次测距}
}

代码优化②:

/**优化:将定时器0改为定时器1,然后将超声波测距封装成为一个函数*/
#include <REGX52.H>sbit Trig = P1^5;
sbit Echo = P1^6;
sbit LED1 = P3^7;void Delay10us()		//@11.0592MHz
{unsigned char i;i = 2;while (--i);
}void Delay200ms()		//@11.0592MHz
{unsigned char i, j, k;i = 2;j = 103;k = 147;do{do{while (--k);} while (--j);} while (--i);
}void Timer1_Init(void)
{//使用定时器1TMOD &= 0x0F;TMOD |= 0x10;TL1 = 0;TH1 = 0;//设置定时器T1从0开始数数
}double get_distance()//超声波获得距离的函数
{double time;TL1 = 0;TH1 = 0;//定时器清零,以便下次测距//1、开始发波Trig = 0;Trig = 1;Delay10us();Trig = 0;//2、检测ECHO引脚电平while(Echo == 0);TR1 = 1;													//启动定时器while(Echo == 1);TR1 = 0;													//关闭定时器//3、计算定时开到定时关的时间(计算数的个数),//2位二进制11,01。合并位1101怎么算?1101为(11*2^2)+01=13time = (TH1 * 256 + TL1) * 1.085; //us为单位//34000cm/s = 34cm/ms = 0.034cm/usreturn (time * 0.017);							  //cm为单位;
}void main(void)
{double dis;Timer1_Init();while(1){Delay200ms();//先给单片机准备时间dis = get_distance();if(dis < 10){LED1 = 0;}else{LED1 = 1;}}
}

3、感应开关盖垃圾桶

舵机和超声波代码整合,舵机用定时器0,超声波用定时器1。
1、实现物体靠近后,自动开盖,2秒后关盖。
2、查询的方式添加按键控制
3、 查询的方式添加震动控制

#include <REGX52.H>sbit SW1   =   P2^1;//按键SW1连接的是P2.1口
sbit Trig  =   P1^5;
sbit Echo  =   P1^6;
sbit LED1  =   P3^7;
sbit sg_90 =   P1^1;//黄线连接P1.1口
sbit vibrate = P3^2;//震动传感器连接P3.2口,使用外部中断0int cnt = 0;	//标志位
int jd;			//占空比的分子
int vib_mark;   //震动传感器的标志位void Delay10us()		//@11.0592MHz
{unsigned char i;i = 2;while (--i);
}void Delay200ms()		//@11.0592MHz
{unsigned char i, j, k;i = 2;j = 103;k = 147;do{do{while (--k);} while (--j);} while (--i);
}void Delay2000ms()		//@11.0592MHz
{unsigned char i, j, k;i = 15;j = 2;k = 235;do{do{while (--k);} while (--j);} while (--i);
}void EX0_Init()//触发中断0初始化
{EX0 = 1;EA = 1;IT0 = 0;//低电平触发
}void Timer0_Init(void)//定时器T0中断初始化
{TMOD &= 0xF0;//配置定时器T0为16位定时器TMOD |= 0x01;TL0 = 0x33;	//定时器计1个数为1.085us,则当舵机为0度的时候,需要0.5ms,            TH0 = 0xFE;	//则定一个0.5ms的定时器TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时ET0 = 1;EA = 1;
}void Timer1_Init(void)//定时器T1初始化
{//使用定时器1TMOD &= 0x0F;TMOD |= 0x10;TL1 = 0;TH1 = 0;//设置定时器T1从0开始数数
}double get_distance()
{double time;TL1 = 0;TH1 = 0;//定时器清零,以便下次测距//1、开始发波Trig = 0;Trig = 1;Delay10us();Trig = 0;//2、检测ECHO引脚电平while(Echo == 0);TR1 = 1;													//启动定时器while(Echo == 1);TR1 = 0;													//关闭定时器//3、计算定时开到定时关的时间(计算数的个数),//2位二进制11,01。合并位1101怎么算?1101为(11*2^2)+01=13time = (TH1 * 256 + TL1) * 1.085; //us为单位//34000cm/s = 34cm/ms = 0.034cm/usreturn (time * 0.017);							  //cm为单位;
}void sg90_0(void)	//舵机0度
{sg_90 = 1;//先给输出引脚一个高电平jd = 1;//一上电,开始占空比为1/40,为0度cnt = 0;
}void sg90_90(void)//舵机90度
{sg_90 = 1;//先给输出引脚一个高电平jd = 3;//一上电,开始占空比为3/40,为90度cnt = 0;
}void main(void)
{double dis;Timer0_Init();Timer1_Init();EX0_Init();sg90_0();while(1){Delay200ms();//先给单片机准备时间dis = get_distance();if(dis < 10 || SW1 == 0 || vib_mark == 1){vib_mark = 0;LED1 = 0;sg90_90();Delay2000ms();}else{LED1 = 1;sg90_0();Delay200ms();}	}
}void Timer0_Handler() interrupt 1//中断函数
{cnt++;TL0 = 0x33;	           TH0 = 0xFE;//控制PWM波的占空比if(cnt < jd){sg_90 = 1;}else{sg_90 = 0;}if(cnt == 40){cnt = 0;sg_90 = 1;}
}void EX0_Handler() interrupt 0//触发中断0函数
{vib_mark = 1;
}
 为什么我们使用震动传感器控制的时候不直接if(dis < 10 || SW1 == 0 ||  vibrate== 0)喃?这样判断不是跟简单吗?原因:因为震动传感器因为震动而发出的低电平0不仅微弱,而且时间比较断。当震动传感器给出低电平的时候,而单片机还在执Delay2000ms();而当进入判断的时候,可能震动传感器发出的低电平已经消失了,已经变成高电平了。这样就会导致震动传感器不灵敏。所以,通过外部中断来改变标志位,这样就会规避这个问题。当震动时,触发中断,标志位变为1,等待判断。只有进入判断后标志位才变回0。

相关文章:

02:项目二:感应开关盖垃圾桶

感应开关盖垃圾桶 1、PWM开发SG901.1、怎样通过C51单片机输出PWM波&#xff1f;1.2、通过定时器输出PWM波来控制SG90 2、超声波测距模块的使用3、感应开关盖垃圾桶 需要材料&#xff1a; 1、SG90舵机模块 2、HC-SR04超声波模块 3、震动传感器 4、蜂鸣器 5、若干杜邦线 1、PWM开…...

eNsp公司管理的网络NAT策略搭建

实验拓扑图 实验需求&#xff1a; 7&#xff0c;办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换) 8&#xff0c;分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的http服务器 9&#xff0c;多出口环境基于带…...

MUR2060CTR-ASEMI无人机专用MUR2060CTR

编辑&#xff1a;ll MUR2060CTR-ASEMI无人机专用MUR2060CTR 型号&#xff1a;MUR2060CTR 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220 批号&#xff1a;最新 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;20A 最大循环峰值反向电压&#xff08;VRRM&#…...

Manim的代码练习02:在manim中Dot ,Arrow和NumberPlane对象的使用

Dot&#xff1a;指代点对象或者表示点的符号。Arrow&#xff1a;指代箭头对象&#xff0c;包括直线上的箭头或者向量箭头等。NumberPlane&#xff1a;指代数轴平面对象&#xff0c;在Manim中用来创建包含坐标轴的数学坐标系平面。Text&#xff1a;指代文本对象&#xff0c;用来…...

datawhale - 基于术语词典干预的机器翻译挑战赛 (一)

文章目录 torchtext 库是干什么用的 &#xff1f;TranslationDataset 类定义 Seq2Seq模型EncoderDecoderSeq2Seq 类 load_terminology_dictionary 函数示例用法 train 函数主程序代码模型评价load_sentences 函数translate_sentence 函数evaluate_bleu 函数主程序 测试集上进行…...

【JavaScript脚本宇宙】提升用户体验:探索 JavaScript 命令行界面开发工具

构建交互式命令行&#xff1a;JavaScript 中的 CLI 开发利器 前言 在现代软件开发中&#xff0c;命令行界面&#xff08;CLI&#xff09;和终端应用程序的开发变得越来越重要。为了提高用户体验和交互性&#xff0c;使用合适的工具和库是至关重要的。本文将介绍一些用于构建命…...

ubuntu18.04安装显卡驱动后无法进入桌面的解决办法

我没有尝试完美恢复的方法&#xff0c;只尝试了卸载nvidia显卡的方法 1.第一步 进 安开机键进入 1 开机进入 选项界面&#xff0c;选择高级模式(ubuntu 高级选项&#xff09; 2.第二步 进去以后选择一个括号里面带recovery mode的选项&#xff0c;数字选最高最大的。 3.然后…...

javaScript的面试重点--预解析

目录 一.前言 二.预解析案例 一.前言 关于预解析&#xff0c;我们通过今天学习就能够知道解析器运行JS分为哪两步&#xff1b;能够说出变量提升的步骤和运行过程&#xff1b;能够说出函数提升的步骤和运行过程。 二.预解析案例 预解析&#xff0c;简而言之&#xff0c;也就是…...

Gitea 仓库事件触发Jenkins远程构建

文章目录 引言I Gitea 仓库事件触发Jenkins远程构建1.1 Jenkins配置1.2 Gitea 配置引言 应用场景:项目部署 I Gitea 仓库事件触发Jenkins远程构建 Gitea支持用于仓库事件的Webhooks 1.1 Jenkins配置 高版本Jenkins需要关闭跨域限制和开启匿名用户访问 在Jenkins启动前加入…...

springboot+vue 开发记录(九)后端打包部署运行

本篇文章主要内容是后端项目写好了&#xff0c;怎么打包部署到服务器上运行。 文章目录 1. 在服务器上安装Docker2. 在Docker中装MySQL3. 在Docker中设置网桥&#xff0c;实现容器间的网络通信4. 修改后端配置文件5. 修改pom.xml文件6. 打包7. 编写DockerFile文件8. 上传文件到…...

昇思25天学习打卡营第20天 | 基于MindNLP+MusicGen生成自己的个性化音乐

基于MindNLPMusicGen生成个性化音乐 实验简介 MusicGen是Meta AI提出的音乐生成模型&#xff0c;能够根据文本描述或音频提示生成高质量音乐。该模型基于Transformer结构&#xff0c;分为三个阶段&#xff1a;文本编码、音频token预测和音频解码。此实验将演示如何使用MindSpo…...

windows USB 设备驱动开发-USB主控制开发(一)

下面介绍主机驱动程序开发的高级概念和任务。 如果你正在编写与 Microsoft 提供的 USB 主机控制器扩展驱动程序 (Ucx01000.sys) 通信的新主机控制器驱动程序&#xff0c;则这部分内容适用于你。 下面是 Windows 中 USB 主机端驱动程序中显示的图表的修改版本。 此版本隐藏 USB…...

Dubbo 负载均衡(Load Balance)

在分布式系统中&#xff0c;负载均衡是确保系统高效稳定运行的关键技术之一。Dubbo 作为一款高性能的 RPC 框架&#xff0c;提供了多种负载均衡策略以满足不同场景的需求。本文将深入介绍 Dubbo 中常用的几种负载均衡策略&#xff1a;随机&#xff08;Random&#xff09;、轮询…...

ArcGIS Pro SDK (九)几何 3 点

ArcGIS Pro SDK &#xff08;九&#xff09;几何 3 点 文章目录 ArcGIS Pro SDK &#xff08;九&#xff09;几何 3 点1 构造地图点2 地图点生成器属性3 地图点的相等性4 缩放至指定点 环境&#xff1a;Visual Studio 2022 .NET6 ArcGIS Pro SDK 3.0 1 构造地图点 // 使用生…...

基于神经网络的分类和预测

基于神经网络的分类和预测 一、基础知识&#xff08;一&#xff09;引言&#xff08;二&#xff09;神经网络的基本概念&#xff08;1&#xff09;神经网络&#xff08;2&#xff09;神经元&#xff08;3&#xff09;常用的激活函数&#xff08;非线性映射函数&#xff09;&…...

VR头显如何低延迟播放8K的RTSP|RTMP流

技术背景 我们在做Unity平台RTSP、RTMP播放器的时候&#xff0c;有公司提出来这样的技术需求&#xff0c;希望在头显播放全景的8K RTSP|RTMP直播流&#xff0c;8K的数据&#xff0c;对头显和播放器&#xff0c;都提出了新的要求&#xff0c;我们从几个方面&#xff0c;探讨下V…...

2、ASPX、.NAT(环境/框架)安全

ASPX、.NAT&#xff08;环境/框架&#xff09;安全 源自小迪安全b站公开课 1、搭建组合&#xff1a; WindowsIISaspxsqlserver .NAT基于windows C开发的框架/环境 对抗Java xx.dll <> xx.jar 关键源码封装在dll文件内。 2、.NAT配置调试-信息泄露 功能点&#xf…...

在家上网IP地址是固定的吗?

在数字化时代&#xff0c;互联网已成为我们日常生活中不可或缺的一部分。无论是工作、学习还是娱乐&#xff0c;我们都离不开网络的支持。然而&#xff0c;当我们在家中接入互联网时&#xff0c;可能会产生这样一个疑问&#xff1a;在家上网IP地址是固定的吗&#xff1f;下面一…...

交换机和路由器的工作流程

1、交换机工作流程&#xff1a; 将接口中的电流识别为二进制&#xff0c;并转换成数据帧&#xff0c;交换机会记录学习该数据帧的源MAC地址&#xff0c;并将其端口关联起来记录在MAC地址表中。然后查看MAC地址表来查找目标MAC地址&#xff0c;会有一下一些情况&#xff1a; MA…...

算法笔记——LCR

一.LCR 152. 验证二叉搜索树的后序遍历序列 题目描述&#xff1a; 给你一个二叉搜索树的后续遍历序列&#xff0c;让你判断该序列是否合法。 解题思路&#xff1a; 根据二叉搜索树的特性&#xff0c;二叉树搜索的每一个结点&#xff0c;大于左子树&#xff0c;小于右子树。…...

ChatGPT对话:如何制作静态网页?

【编者按】编者在很早以前制作过静态网页&#xff0c;之后长期没有使用&#xff0c;已完全不知道最新现状了。所以&#xff0c;从制作工具开始询问ChatGPT&#xff0c;回答非常全面&#xff0c;完全可以解决初学者的问题。 编者虽然长期不制作网页&#xff0c;但一直在编程&…...

k8s(二)

五、kubernetes架构(K8S的架构也是master和node模式&#xff09; 集群里至少需要有一个master节点&#xff0c;即就是主节点。node节点可以多个。 若是多个master节点&#xff0c;worker节点和master的apiserverr进行交互时&#xff0c;就需要通过LB(load banlance&#xff09;…...

ClickHouse表引擎概述

ClickHouse表引擎概述 表引擎的功能&#xff1a; 数据的存储方式 数据的存储位置 是否可以使用索引 是否可以使用分区 是否支持数据副本 并发数据访问 ClickHouse在建表时必须指定表引擎。 表引擎主要分为四大类&#xff1a;MergeTree系列、Log系列、与其他存储/处理系…...

jenkins系列-04-jenkins参数化构建

使用maven build之前&#xff0c;先checkout 指定分支或标签&#xff1a; 拖拽调整顺序&#xff1a;shell执行在前&#xff0c;构建在后&#xff1a; gitee新建标签tag:...

Flutter框架时间线梳理

Flutter是一个开源的UI工具包&#xff0c;它用于构建高质量的原生移动应用。Flutter的版本历史如下&#xff1a; Flutter 0.1.2&#xff1a; 2018年发布&#xff0c;这是第一个正式发布的版本&#xff0c;包含了基本的框架和工具。 Flutter 1.0.0&#xff1a; 2019年发布&…...

RAG 效果提升的最后一步—— 微调LLM

如果说&#xff0c;rerank能够让RAG的效果实现百尺竿头更进一步&#xff0c;那么LLM微调应该是RAG效果提升的最后一步。 把召回的数据&#xff0c;经过粗排&#xff0c;重排序后&#xff0c;送给模型&#xff0c;由模型最后总结答案。LLM的确已经是RAG的最后一步了。 这里还是会…...

C语言 | Leetcode C语言题解之第230题二叉搜索树中第K小的元素

题目&#xff1a; 题解&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/int search_num(struct TreeNode* root, int k, int *result, int num) {if(num k 1){retu…...

YOWOv2(yowov2)动作识别+Fastreid身份识别 详细安装与实现

首先yowov2是一款简单且实时的时空动作检测方案&#xff0c;fastreid是行人重识别&#xff08;身份识别&#xff09; yowov2介绍链接直达fastreid链接直达为时空动作检测任务设计实时框架仍然是一个挑战。YOWOv2 提出了一种新颖的实时动作检测框架&#xff0c;利用三维骨干和二…...

【微服务】Spring Cloud中如何使用Eureka

摘要 Eureka作为Netflix开源的服务发现框架&#xff0c;在Spring Cloud体系中扮演着至关重要的角色。本文详细介绍了Eureka的基本概念、工作原理以及如何在Spring Cloud中集成和使用Eureka进行服务发现和管理。通过深入分析Eureka的注册与发现机制、区域感知和自我保护等高级特…...

【Neo4j】实战 (数据库技术丛书)学习笔记

Neo4j实战 (数据库技术丛书) 第1章演示了应用Neo4j作为图形数据库对改进性能和扩展性的可能性, 也讨论了对图形建模的数据如何正好适应于Neo4j数据模型,现在到了该动 手实践的时间了。第一章 概述 Neo4j将数据作为顶点和边存储(或者用Neo4j术语,节点和关系存 储)。用户被定…...