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=13
		time = (TH0 * 256 + TL0) * 1.085; //us为单位
		//34000cm/s = 34cm/ms = 0.034cm/us
		dis = 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)
{
	//使用定时器1
	TMOD &= 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=13
		time = (TH1 * 256 + TL1) * 1.085; //us为单位
		//34000cm/s = 34cm/ms = 0.034cm/us
		return (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口,使用外部中断0

int 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初始化
{
	//使用定时器1
	TMOD &= 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=13
		time = (TH1 * 256 + TL1) * 1.085; //us为单位
		//34000cm/s = 34cm/ms = 0.034cm/us
		return (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。

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

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

相关文章

win10 docker-compose搭建ELK日志收集

elk的威名大家都知道&#xff0c;以前前司有专门的人维护&#xff0c;现在换了环境&#xff0c;实在不想上服务器看&#xff0c;所以就摸索下自己搭建&#xff0c;由于现场服务器是需要类似向日葵那样连接&#xff0c;我还是把日志弄回来&#xff0c;自己本地filebeat上传到es中…

WPF学习(2) -- 样式基础

一、代码 <Window x:Class"学习.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/2008&…

jenkins系列-02.配置jenkins

首先&#xff1a;我们要给jenkins配备jdkmaven: 从上一节我们知道 ~/dockerV/jenkins/jenkins/data目录 就是 容器中jenkins的home目录 所以把jdkmaven 放在当前宿主机上的 ~/dockerV/jenkins/jenkins/data目录下即可 容器内&#xff1a; 开始配置jenkins: 注意是在jenkins…

护网HW面试常问——组件中间件框架漏洞(包含流量特征)

apache&iis&nginx中间件解析漏洞 参考我之前的文章&#xff1a;护网HW面试—apache&iis&nginx中间件解析漏洞篇-CSDN博客 log4j2 漏洞原理&#xff1a; 该漏洞主要是由于日志在打印时当遇到${后&#xff0c;以:号作为分割&#xff0c;将表达式内容分割成两部…

时间轮算法理解、Kafka实现

概述 TimingWheel&#xff0c;时间轮&#xff0c;简单理解就是一种用来存储若干个定时任务的环状队列&#xff08;或数组&#xff09;&#xff0c;工作原理和钟表的表盘类似。 关于环形队列&#xff0c;请参考环形队列。 时间轮由两个部分组成&#xff0c;一个环状数组&…

韦东山嵌入式linux系列-驱动设计的思想(面向对象/分层/分离)

1 面向对象 字符设备驱动程序抽象出一个 file_operations 结构体&#xff1b; 我们写的程序针对硬件部分抽象出 led_operations 结构体。 2 分层 上下分层&#xff0c;比如我们前面写的 LED 驱动程序就分为 2 层&#xff1a; ① 上层实现硬件无关的操作&#xff0c;比如注册…

WPF学习(3) -- 控件模板

一、操作过程 二、代码 <Window x:Class"学习.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expressio…

css基础(1)

CSS CCS Syntax CSS 规则由选择器和声明块组成。 CSS选择器 CSS选择器用于查找想要设置样式的HTML元素 一般选择器分为五类 Simple selectors (select elements based on name, id, class) 简单选择器&#xff08;根据名称、id、类选择元素&#xff09; //页面上的所有 …

WEB前端03-CSS3基础

CSS3基础 1.CSS基本概念 CSS是Cascading Style Sheets&#xff08;层叠样式表&#xff09;的缩写&#xff0c;它是一种对Web文档添加样式的简单机制&#xff0c;是一种表现HTML或XML等文件外观样式的计算机语言&#xff0c;是一种网页排版和布局设计的技术。 CSS的特点 纯C…

Oracle使用fetch first子句报错:ORA-00933 SQL命令未正确结束

问题背景 今天在统计终端厂商告警次数Top10的时候使用SQL查询使用到了fetch first子句&#xff0c;结果执行报错&#xff1a;ORA-00933 SQL命令未正确结束。 报错原因 Oracle数据库中&#xff0c;使用 FETCH FIRST 子句需要启用 Oracle 12c 及以上版本。如果在较低版本的 Or…

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

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

ISO 45001:提升职业健康与安全管理水平的关键

在现代企业管理中&#xff0c;员工的职业健康与安全&#xff08;OH&S&#xff09;已经成为不可忽视的重要议题。ISO 45001作为国际标准化组织&#xff08;ISO&#xff09;制定的职业健康与安全管理体系标准&#xff0c;为企业提供了科学有效的管理规范和指南。实施这一标准…

Go-知识测试-子测试

Go-知识测试-子测试 1. 介绍2. 例子3. 子测试命名规则4. 选择性执行5. 子测试并发6. testing.T.Run7. testing.T.Parallel8. 子测试适用于单元测试9. 子测试适用于性能测试10. 总结10.1 启动子测试 Run10.2 启动并发测试 Parallel 建议先看&#xff1a;https://blog.csdn.net/a…

探索“搭旅万物皆可搭”小程序——构建旅行搭伴平台的创新实践

摘要 随着旅游市场的不断发展和个性化需求的日益增长&#xff0c;旅行搭伴平台逐渐成为连接志同道合旅者的桥梁。本文旨在介绍“搭旅万物皆可搭”小程序的设计理念、核心功能及其背后的技术实现&#xff0c;探讨如何通过算法优化、安全保障、社交互动等手段&#xff0c;打造一…

手撕Vue中的RouterLink和RouterView,深入理解其底层原理(一)

RouterLink和RouterView的作用 我们可以通过RouterLink绑定好指向的路径 点击就能够实现在RouterView中将页面显示出来 我们首先使用官方的vue-router展示一下效果 App.vue <template><div><router-link to"/">Home</router-link><ro…

51单片机STC89C52RC——17.2 红外遥控数字加减、电机调速

目的/效果 1&#xff1a;按VOL-键数字减、按VOL加数字加 2&#xff1a;按键 0&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;4 电机调速 一&#xff0c;STC单片机模块 二&#xff0c;红外遥控 详细了解红外遥控控制原理请参考《51单片机STC89C52RC——17.1 红外线遥控…

UE4 解决创建布料报错:三角形退化

**【问题】**创建创建布料时报错&#xff1a;三角形退化 【方法】 1.要重新绑定&#xff1a;导入到ue4为静态网格体&#xff0c;勾选“移除退化”&#xff0c;再导出fbx&#xff0c;再重新绑定 2.不用重新绑定&#xff1a;使用排除法&#xff08;费时&#xff09;&#xff0c…

Spring Boot快速上手

一&#xff0c;什么是spring 首先登陆Spring官网&#xff0c;看一下官网如何形容的&#xff0c; 可以看出Spring是为了使java程序更加快速&#xff0c;方便&#xff0c;安全所做出的java框架。 1.Spring Boot Spring Boot的诞生就是为了简化Spring的开发&#xff0c;也就是更…

【Quart 框架——来源于Flask的强大且灵活的异步Web框架】

目录 前言一、Quart简介1-1、简介1-2、与flask的区别 二、快速开始2-1、安装2-2、基本用法 三、核心功能3-1、异步路由3-2、WebSockets 支持3-3、中间件3-4、蓝图 (Blueprints) 四、部署4-1、使用uvicorn部署4-2、使用hypercorn部署 五、案例分析总结 前言 Quart 是一个基于 Py…

taocms 3.0.1 本地文件泄露漏洞(CVE-2021-44983)

前言 CVE-2021-44983 是一个影响 taoCMS 3.0.1 的远程代码执行&#xff08;RCE&#xff09;漏洞。该漏洞允许攻击者通过上传恶意文件并在服务器上执行任意代码来利用这一安全缺陷。 漏洞描述 taoCMS 是一个内容管理系统&#xff08;CMS&#xff09;&#xff0c;用于创建和管…