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波?1.2、通过定时器输出PWM波来控制SG90 2、超声波测距模块的使用3、感应开关盖垃圾桶 需要材料: 1、SG90舵机模块 2、HC-SR04超声波模块 3、震动传感器 4、蜂鸣器 5、若干杜邦线 1、PWM开…...
eNsp公司管理的网络NAT策略搭建
实验拓扑图 实验需求: 7,办公区设备可以通过电信链路和移动链路上网(多对多的NAT,并且需要保留一个公网IP不能用来转换) 8,分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的http服务器 9,多出口环境基于带…...
MUR2060CTR-ASEMI无人机专用MUR2060CTR
编辑:ll MUR2060CTR-ASEMI无人机专用MUR2060CTR 型号:MUR2060CTR 品牌:ASEMI 封装:TO-220 批号:最新 最大平均正向电流(IF):20A 最大循环峰值反向电压(VRRM&#…...
Manim的代码练习02:在manim中Dot ,Arrow和NumberPlane对象的使用
Dot:指代点对象或者表示点的符号。Arrow:指代箭头对象,包括直线上的箭头或者向量箭头等。NumberPlane:指代数轴平面对象,在Manim中用来创建包含坐标轴的数学坐标系平面。Text:指代文本对象,用来…...
datawhale - 基于术语词典干预的机器翻译挑战赛 (一)
文章目录 torchtext 库是干什么用的 ?TranslationDataset 类定义 Seq2Seq模型EncoderDecoderSeq2Seq 类 load_terminology_dictionary 函数示例用法 train 函数主程序代码模型评价load_sentences 函数translate_sentence 函数evaluate_bleu 函数主程序 测试集上进行…...
【JavaScript脚本宇宙】提升用户体验:探索 JavaScript 命令行界面开发工具
构建交互式命令行:JavaScript 中的 CLI 开发利器 前言 在现代软件开发中,命令行界面(CLI)和终端应用程序的开发变得越来越重要。为了提高用户体验和交互性,使用合适的工具和库是至关重要的。本文将介绍一些用于构建命…...
ubuntu18.04安装显卡驱动后无法进入桌面的解决办法
我没有尝试完美恢复的方法,只尝试了卸载nvidia显卡的方法 1.第一步 进 安开机键进入 1 开机进入 选项界面,选择高级模式(ubuntu 高级选项) 2.第二步 进去以后选择一个括号里面带recovery mode的选项,数字选最高最大的。 3.然后…...
javaScript的面试重点--预解析
目录 一.前言 二.预解析案例 一.前言 关于预解析,我们通过今天学习就能够知道解析器运行JS分为哪两步;能够说出变量提升的步骤和运行过程;能够说出函数提升的步骤和运行过程。 二.预解析案例 预解析,简而言之,也就是…...
Gitea 仓库事件触发Jenkins远程构建
文章目录 引言I Gitea 仓库事件触发Jenkins远程构建1.1 Jenkins配置1.2 Gitea 配置引言 应用场景:项目部署 I Gitea 仓库事件触发Jenkins远程构建 Gitea支持用于仓库事件的Webhooks 1.1 Jenkins配置 高版本Jenkins需要关闭跨域限制和开启匿名用户访问 在Jenkins启动前加入…...
springboot+vue 开发记录(九)后端打包部署运行
本篇文章主要内容是后端项目写好了,怎么打包部署到服务器上运行。 文章目录 1. 在服务器上安装Docker2. 在Docker中装MySQL3. 在Docker中设置网桥,实现容器间的网络通信4. 修改后端配置文件5. 修改pom.xml文件6. 打包7. 编写DockerFile文件8. 上传文件到…...
昇思25天学习打卡营第20天 | 基于MindNLP+MusicGen生成自己的个性化音乐
基于MindNLPMusicGen生成个性化音乐 实验简介 MusicGen是Meta AI提出的音乐生成模型,能够根据文本描述或音频提示生成高质量音乐。该模型基于Transformer结构,分为三个阶段:文本编码、音频token预测和音频解码。此实验将演示如何使用MindSpo…...
windows USB 设备驱动开发-USB主控制开发(一)
下面介绍主机驱动程序开发的高级概念和任务。 如果你正在编写与 Microsoft 提供的 USB 主机控制器扩展驱动程序 (Ucx01000.sys) 通信的新主机控制器驱动程序,则这部分内容适用于你。 下面是 Windows 中 USB 主机端驱动程序中显示的图表的修改版本。 此版本隐藏 USB…...
Dubbo 负载均衡(Load Balance)
在分布式系统中,负载均衡是确保系统高效稳定运行的关键技术之一。Dubbo 作为一款高性能的 RPC 框架,提供了多种负载均衡策略以满足不同场景的需求。本文将深入介绍 Dubbo 中常用的几种负载均衡策略:随机(Random)、轮询…...
ArcGIS Pro SDK (九)几何 3 点
ArcGIS Pro SDK (九)几何 3 点 文章目录 ArcGIS Pro SDK (九)几何 3 点1 构造地图点2 地图点生成器属性3 地图点的相等性4 缩放至指定点 环境:Visual Studio 2022 .NET6 ArcGIS Pro SDK 3.0 1 构造地图点 // 使用生…...
基于神经网络的分类和预测
基于神经网络的分类和预测 一、基础知识(一)引言(二)神经网络的基本概念(1)神经网络(2)神经元(3)常用的激活函数(非线性映射函数)&…...
VR头显如何低延迟播放8K的RTSP|RTMP流
技术背景 我们在做Unity平台RTSP、RTMP播放器的时候,有公司提出来这样的技术需求,希望在头显播放全景的8K RTSP|RTMP直播流,8K的数据,对头显和播放器,都提出了新的要求,我们从几个方面,探讨下V…...
2、ASPX、.NAT(环境/框架)安全
ASPX、.NAT(环境/框架)安全 源自小迪安全b站公开课 1、搭建组合: WindowsIISaspxsqlserver .NAT基于windows C开发的框架/环境 对抗Java xx.dll <> xx.jar 关键源码封装在dll文件内。 2、.NAT配置调试-信息泄露 功能点…...
在家上网IP地址是固定的吗?
在数字化时代,互联网已成为我们日常生活中不可或缺的一部分。无论是工作、学习还是娱乐,我们都离不开网络的支持。然而,当我们在家中接入互联网时,可能会产生这样一个疑问:在家上网IP地址是固定的吗?下面一…...
交换机和路由器的工作流程
1、交换机工作流程: 将接口中的电流识别为二进制,并转换成数据帧,交换机会记录学习该数据帧的源MAC地址,并将其端口关联起来记录在MAC地址表中。然后查看MAC地址表来查找目标MAC地址,会有一下一些情况: MA…...
算法笔记——LCR
一.LCR 152. 验证二叉搜索树的后序遍历序列 题目描述: 给你一个二叉搜索树的后续遍历序列,让你判断该序列是否合法。 解题思路: 根据二叉搜索树的特性,二叉树搜索的每一个结点,大于左子树,小于右子树。…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...
ThreadLocal 源码
ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物,因为每个访问一个线程局部变量的线程(通过其 get 或 set 方法)都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段,这些类希望将…...
算法—栈系列
一:删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...
