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

news2024/9/24 11:27:21

感应开关盖垃圾桶

  • 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.coloradmin.cn/o/1924470.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习 pytorch】迁移学习 (迁移ResNet18)

李宏毅深度学习笔记 《深度学习原理Pytorch实战》 https://blog.csdn.net/peter6768/article/details/135712687 迁移学习 实际应用中很多任务的数据的标注成本很高&#xff0c;无法获得充足的训练数据&#xff0c;这种情况可以使用迁移学习(transfer learning)。假设A、B是两…

第三期闯关基础岛

1、 Linux 基础知识 任务描述完成所需时间闯关任务完成SSH连接与端口映射并运行hello_world.py10min可选任务 1将Linux基础命令在开发机上完成一遍10min可选任务 2使用 VSCODE 远程连接开发机并创建一个conda环境10min可选任务 3创建并运行test.sh文件10min 1.1、SSH连接 使用…

Android Spinner

1. Spinner Spinner是下拉列表&#xff0c;如图3-14所示&#xff0c;通常用于为用户提供选择输入。Spinner有一个重要的属性&#xff1a;spinnerMode&#xff0c;它有2种情况&#xff1a; 属性值为dropdown时&#xff0c;表示Spinner的数据下拉展示&#xff0c;如图1&#xf…

自己动手写一个滑动验证码组件(后端为Spring Boot项目)

近期参加的项目&#xff0c;主管丢给我一个任务&#xff0c;说要支持滑动验证码。我身为50岁的软件攻城狮&#xff0c;当时正背着双手&#xff0c;好像一个受训的保安似的&#xff0c;中规中矩地参加每日站会&#xff0c;心想滑动验证码在今时今日已经是标配了&#xff0c;司空…

jenkins系列-06.harbor

https://github.com/goharbor/harbor/releases?page2 https://github.com/goharbor/harbor/releases/download/v2.3.4/harbor-offline-installer-v2.3.4.tgz harbor官网&#xff1a;https://goharbor.io/ 点击 Download now 链接&#xff0c;会自动跳转到上述github页面&am…

采用自动微分进行模型的训练

自动微分训练模型 简单代码实现&#xff1a; import torch import torch.nn as nn import torch.optim as optim# 定义一个简单的线性回归模型 class LinearRegression(nn.Module):def __init__(self):super(LinearRegression, self).__init__()self.linear nn.Linear(1, 1) …

python:使用matplotlib库绘制图像(四)

作者是跟着http://t.csdnimg.cn/4fVW0学习的&#xff0c;matplotlib系列文章是http://t.csdnimg.cn/4fVW0的自己学习过程中整理的详细说明版本&#xff0c;对小白更友好哦&#xff01; 四、条形图 1. 一个数据样本的条形图 条形图&#xff1a;常用于比较不同类别的数量或值&…

DockerCompose介绍,安装,使用

DockerCompose 1、Compose介绍 将单机服务-通过Dockerfile 构建为镜像 -docker run 成为一个服务 user 8080 net 7000 pay 8181 admin 5000 监控 .... docker run 单机版、一个个容器启动和停止问题&#xff1a; 前面我们使用Docker的时候&#xff0c;定义 Dockerfil…

深入理解Java泛型:概念、用法与案例分析

个人名片** &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4…

Transformer模型:Encoder的self-attention mask实现

前言 这是对Transformer模型的Word Embedding、Postion Embedding内容的续篇。 视频链接&#xff1a;19、Transformer模型Encoder原理精讲及其PyTorch逐行实现_哔哩哔哩_bilibili 文章链接&#xff1a;Transformer模型&#xff1a;WordEmbedding实现-CSDN博客 Transformer模型…

docker-compose安装PolarDB-PG数据库

文章目录 一. Mac1.1 docker-compose.yaml1.2 部署1.3 卸载4. 连接 二. Win102.1 docker-compose.yaml2.2 部署2.3 卸载 参考官方文档 基于单机文件系统部署 一. Mac 1.1 docker-compose.yaml mkdir -p /Users/wanfei/docker-compose/polardb-pg && cd /Users/wanfei…

Linux - 综合使用shell脚本,输出网站有效数据

综合示例: shell脚本实现查看网站分数 使用编辑器编辑文件jw.sh为如下内容: #!/bin/bash save_file"score" # 临时文件 semester20102 # 查分的学期, 20102代表2010年第二学期 jw_home"http://jwas3.nju.edu.cn:8080/jiaowu" # 测试网站首页地址 jw_logi…

zigbee开发工具:2、zigbee工程建立与配置

本文演示基于IAR for 8051&#xff08;版本10.10.1&#xff09;如何建立一个开发芯片cc2530的zigbee的工程&#xff0c;并配置这个工程&#xff0c;使其能够将编译的代码进行烧录&#xff0c;生成.hex文件。IAR for 8051&#xff08;版本10.10.1&#xff09;支持工程使用C语言&…

STM32智能交通灯系统教程

目录 引言环境准备智能交通灯系统基础代码实现&#xff1a;实现智能交通灯系统 4.1 数据采集模块 4.2 数据处理与控制模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;交通管理与优化问题解决方案与优化收尾与总结 1. 引言 智能交通灯系统通过STM…

Python游戏开发:四连珠(内附完整代码)

四连珠&#xff08;Connect Four&#xff09;是一款经典的棋类游戏&#xff0c;由两名玩家在7列6行的网格上轮流下棋。玩家的目标是将自己的棋子在垂直、水平或对角线上连成一条线&#xff0c;通常是四个棋子。如果一方成功做到这一点&#xff0c;那么他就赢得了游戏。如果所有…

视频监控汇聚平台:通过SDK接入大华DSS视频监控平台的源代码解释和分享

目录 一、视频监控汇聚平台 1、概述 2、视频接入能力 3、视频汇聚能力 二、大华DSS平台 1、DSS平台概述 2、大华DSS平台的主要特点 &#xff08;1&#xff09;高可用性 &#xff08;2&#xff09;高可靠性 &#xff08;3&#xff09;易维护性 &#xff08;4&#xf…

《昇思25天学习打卡营第2天|02快速入门》

课程目标 这节课准备再学习下训练模型的基本流程&#xff0c;因此还是选择快速入门课程。 整体流程 整体介绍下流程&#xff1a; 数据处理构建网络模型训练模型保存模型加载模型 思路是比较清晰的&#xff0c;看来文档写的是比较连贯合理的。 数据处理 看数据也是手写体数…

【算法】平衡二叉树

难度&#xff1a;简单 题目 给定一个二叉树&#xff0c;判断它是否是 平衡二叉树 示例&#xff1a; 示例1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;true 示例2&#xff1a; 输入&#xff1a;root [1,2,2,3,3,null,null,4,4] 输出&…

炒鸡清晰的防御综合实验(内含区域划分,安全策略,用户认证,NAT认证,智能选路,域名访问)

实验拓扑图如下&#xff1a; 前面六个条件在之间的实验中做过了&#xff0c;详细步骤可以去之前的文章看 这里简写一下大致步骤 第一步&#xff1a; 先将防火墙之外的配置给配置好&#xff0c;比如&#xff0c;PC的IP,交换上的Vlan划分。 第二步&#xff1a; 在浏览器上登…

用SurfaceView实现落花动画效果

上篇文章 Android子线程真的不能刷新UI吗&#xff1f;(一&#xff09;复现异常 中可以看出子线程更新main线程创建的View&#xff0c;会抛出异常。SurfaceView不依赖main线程&#xff0c;可以直接使用自己的线程控制绘制逻辑。具体代码怎么实现了&#xff1f; 这篇文章用Surfa…