0


智能垃圾桶项目【课程设计】【全套开源】

手把手带做【智能垃圾桶项目】【全套开源】

1.项目介绍

1.1 功能描述

  • 当物体接近垃圾桶时,垃圾桶自动打开,并有" 嘀"的一声;当远离垃圾桶后,自动关闭;
  • 当按下按键时,垃圾桶也可以自动打开,并有" 嘀"的一声;
  • 当感受到震动时,也自动打开,(同上)
  • 垃圾桶开时,led1 灯开,led2 灯关;当垃圾桶关时,led1 灯关,led2 灯开

1.2 所需器件

  • SG90舵机,超声波模块HC-SR04,震动传感器,蜂鸣器

模块不熟悉没关系,下面的描述和代码都很详细;

2.元器件器件描述

2.1 STC89C51/52

为了快速做出项目,我们一边介绍项目所需元器件,一边写代码,原理类的东西带过一下。

首先,基本的led1、led2,key1。

#include<reg51.h>

sbit led1 = P3^7;//固定的口  
sbit led2 = P3^6;//固定的口
sbit key1 = P2^1;//固定的口

这些口请参考你使用的单片机的原理图,不同单片机不一样

比如我使用的单片机

在这里插入图片描述

大家根据自己使用的单片机原理图接对应硬件的引脚。

  • 代码块
voidled1_ON()//led1亮,led2灭{
    led1 =1;
    led2 =0;}voidled2_ON()//led2灭,led2亮{
    led1 =0;
    led2 =1;}

这两个点灯函数之后也会用到,用来做为开关垃圾桶的标志。

1.2 超声波测距模块

我使用的是HC-SR04
在这里插入图片描述

大家在某宝或者某夕夕上面买就ok了,几块钱。

  • 接线参考:- 四个引脚VCC接 5/3.3V,GND 接地。- Trig、Echo 两个引脚随便接没有被占用的引脚,我接的是 P1.5 和 P1.6;sbit Trig = P1^5;//发生超声波sbit Echo = P1^6;//接收超声波
  • 超声波测距原理> 超声波测距模块是用来测量距离的一种产品,通过发送和收超声波,利用时间差和声音传播速度, 计算出模块到前方障碍物的距离.

配置好引脚后,trig 和 echo 就可以在软件成面,就是通过代码的方式进行操作。

  • 怎么发送和接收超声波呢?- 1、发送波的条件:给trig一个至少10us的高电平,也就是 trig = 1的状态至少10us;- 2、已经发送波了的标志(也就是开始计时的标志):Echo信号,自动由低电平跳到高电平,表示开始发送波了;- 3、当波接触到物体,波会返回过来,当波返回过来被HC-SR01接收到后,Echo信号就会跳转到低电平,表示回来了;- 4、我们可以利用计数器,以及Echo的信号变化来计算距离;当发出波,Echo第一次变化,启动计数器;当接收到信号,Echo第二次变化,关闭计数器;从而得出来回所需时间。- 通过时间,音度340m/s,距离 = (速度*时间)/ 2;

大家看着看不懂也没关系,我们有代码

  • 模块代码介绍

先获取一下延时函数
在这里插入图片描述

打开STC-ISP,按照我的操作就ok了

不会用STC-ISP也没关系,直接复制代码一样得

voidDelay10us()//@11.0592MHz  //发射超声波最短时间{unsignedchar i;

    i =2;while(--i);}

下面是这个器件操作的大头:利用到了定时器/计数器1

定时器/计数器如果不太明白,大家可以参考我之前写的博客:

<定时器中断&外部中断 区别联系-CSDN博客>

  • 模块参考代码介绍
sbit Trig = P1^5;//发生超声波
sbit Echo = P1^6;//接收超声波voidTimer1Init()// @11.0592MHz {
    
    TMOD &=0x0F;//设置定时器模式  //选择定时器1
    TMOD |=0x10;//与运算,可以参考我另一篇博客(下面会介绍),看不懂也没关系,直接C、V就好
    TL1 =0x00;//设置定时初始值
    TH1 =0x00;//设置定时初始值//不着急开始计数,寄存器的操作在后面 getDis( )函数}voidstartHC()//发射超声波{
    Trig =0;//Trig 硬件层面接好后,软件 sbit 了 一个引脚后,就可以直接赋值;
    Trig =1;Delay10us();//延时10us,//前面介绍过,直接copy
    Trig =0;}floatgetDis()//获得距离 //这里是难点,根据Echo信号的变化来获取距离{float TIME;//时间
    TL1 =0x00;//设置定时初始值
    TH1 =0x00;//设置定时初始值startHC();//准备启动while(Echo==0);//等待高电平,跳出循环
    TR1 =1;while(Echo==1);//等待低电平,跳出循环
    TR1 =0;
    TIME =(TH1 *256+ TL1)*1.085;//us//340m/s == 340 00cm/1000ms == 34cm/ms == 0.034cm/us == 0.017cm/us//计数器的计数一次最大的时间是71ms,根据公式可以知道,一次计数,超声波最远可以传播12mreturn TIME *0.017;//最大12m来回,器件HC-SR04说明书的测量距离是 2cm-4m;}

超声波测距模块就这么一些,在后面我们会在垃圾桶上装一共这样的模块,来检查我们的的手离垃圾桶的距离,通过距离来控制下面我们要讲的舵机,通过舵机控制垃圾桶的开关。

2.3 舵机模块

我使用的是SG90
在这里插入图片描述

网上都可以买的到的

  • 参考接线- 三个引脚VCC接 5V,GND 接地。舵机需要的电压大一点;- PWM信号脚 随便接没有被占用的引脚,我接的是 P1.1; sbit sg90_con = P1^1; //舵机
  • 怎么控制舵机呢?通过PWM信号来控制- PWM波的频率不能太高,大约50HZ,即周期=1/频率=1/50=0.02s,20ms左右0.5ms-------------0度; 2.5% 占空比1.0ms------------45度; 5.0% 占空比1.5ms------------90度; 7.5% 占空比2.0ms-----------135度; 10.0% 占空比2.5ms-----------180度; 12.5% 占空比

占空比:占空比指的是在一个周期中,高电平状态占整个周期的百分比。

给PWM信号引脚 不同频率的脉冲,便可以调控PWM的占空比;

我们设置20ms为一个周期,0.5ms 为最小单元,定义标识符

int cnt

来计数,没过0.5ms,计数加一

cnt++

;这样一来,我们就可以通过标识符来方便的控制舵机旋转角度;

在这里插入图片描述

  • 模块参考代码介绍sbit sg90_con = P1^1;//舵机int jd,jd_bak;//0.5的倍数//用jd,和jd_bak 标识符来控制舵机旋转角度,jd指的是(角度),jd_bak指的是(之前的角度)//jd_bak的设置,是为了让使各各模块结合在一起后,舵机更加稳定所做出的操作;int cnt;//计数voidTime0Init()//定时器0来配合舵机PWM操作 @11.0592MHz{//最小时间单元0.5ms(人为设置的)//1. 配置定时器0工作模式位16位计时 TMOD &=0xF0;//设置定时器模式 //选择定时器1 TMOD |=0x01;//2. 给初值,定一个0.5出来 TL0=0x33; TH0=0xFE;//3. 开始计时 TR0 =1; TF0 =0;//4. 打开定时器0中断 ET0 =1;//5. 打开总中断EA EA =1;}voidsg90_0_Init()//初始化舵机{ jd =1;//初始角度是0度(使舵机恢复原始状态),0.5ms,溢出1就是0.5ms,高电平 cnt =0; sg90_con =1;//一开始从高电平开始}voidTime0Handler() interrupt 1//舵机 定时器0-中断{ cnt++;//统计爆表的次数. cnt=1的时候,报表了1//重新给初值,定时器复位; TL0=0x33; TH0=0xFE;//控制PWM波if(cnt < jd)//jd是全局变量,比较方便{ sg90_con =1;//控制舵机PWM信号的高低电平}else{ sg90_con =0;}if(cnt ==40){//爆表40次,经过了20ms cnt =0;//40 * 0.5ms = 20ms sg90_con =1;}}

2.4 震动传感器模块

我用的是SW-18010P
在这里插入图片描述

  • 引脚介绍- VCC 和 GND 就不说了,当不震动时,AO 口输出高电平;当产品震动时,AO口输出低电平;DO口在这里不用;- 我们可以用四角螺丝刀条件传感器的灵敏度;当传感器触发后,开关信号指示灯就会亮起。
  • 参考接线- AO口可以,随便接没有被占用的引脚,我是将AO口接在P3.2上 sbit vibrate = P3^2;
  • 为了使程序更加稳定,防高灵敏度误触影响程序运行,我们使用外部中断0,来对震动传感器的触发进行操作
  • 模块参考代码介绍
int make_vibrate =0;//震动标志位(全局)voidEX0_Init()//外部中断初始化{//EA = 1;//因为前面以及打开过    EA 中断总开关了,我们这边就把他省略
    EX0 =1;//打开外部中断0 开关
    IT0 =0;//IT0 = 0时 低电平触发//IT = 1 的话就是下降言触发}voidEx0_Handler() interrupt 0//震动传感器,外部中断0{
     make_vibrate =1;//震动 标志位改变,进而影响震动传感器的状态;}

2.5 蜂鸣器模块

我使用的是低电平触发的蜂鸣器,都大差不差,随便到某宝买就行。
在这里插入图片描述

  • 接线参考- VCC GND就不说了,I/O口,随便接没有被占用的引脚,我将 I/O 接在了P2.3sbit beep = P2^3; // 蜂鸣器 开盖就响

蜂鸣器比较简单;

接下来我们把上述各种器件整合,写开盖函数,关盖函数,和main函数;

3.开关盖函数和main

3.1 开关盖函数

直接上代码

voidopenDustbin()//开盖{
    jd =3;//90度 1.5ms高电平;根据前面讲得,20ms里面,1.5ms高电平,舵机转90度if(jd_bak != jd)//当当前设置的角度标志位,与前一个角度标志位不一样时,执行给语句;//目的解决物体一直放在垃圾桶前面时,舵机抽搐的问题。{
        cnt =0;//抽搐的原因
        beep =0;//蜂鸣器响一下Delay150ms();//响150ms
        beep =1;//蜂鸣器停Delay1000ms();//延时1s,开关也要时间
        jd_bak = jd;//这一次的角度,变成了下一次的上一次。}}voidcloseDustbin()//关盖{
     jd =1;//0度,归位
     cnt =0;//计数的标志位置零
     jd_bak = jd;//这一次的角度,变成了下一次的上一次。Delay150ms();}

再补几个延时函数

voidDelay1000ms()//@11.0592MHz{unsignedchar i, j, k;

    i =8;
    j =1;
    k =243;do{do{while(--k);}while(--j);}while(--i);}voidDelay150ms()//@11.0592MHz{unsignedchar i, j, k;
    
    i =2;
    j =13;
    k =237;do{do{while(--k);}while(--j);}while(--i);}

3.2 main函数

下面我们写最主要的代码,来调用前面的函数;

  • 调节距离函数
voidsetDis(float distance)//设置想要的距离,物体到达传感器多长距离,触发开盖{Delay150ms();//这边加一个延时,目的是怕当物体一直在超声波传感器前面时,传感器启动频繁,导致产生过载;让传感器休息一下;if(Dis < distance || key1 ==0|| make_vibrate ==1)//小于10cm 或者按下按键key1 开盖{led1_ON();//点灯led1,关灯led2,标志,开盖成功!openDustbin();//开盖函数
            make_vibrate =0;//震动传感器的标志位置零,重新开始}else{led2_ON();//点灯led2,关灯led1,标志,关盖closeDustbin();//关盖函数//make_vibrate = 0;}}
  • main()函数中调用这个函数,通过传参便捷调节触发距离;
  • main() 函数
intmain(){Time0Init();//初始化定时器Timer1Init();EX0_Init();//外部中断 震动传感器sg90_0_Init();//舵机的初始化while(1){
        Dis =getDis();setDis(10);//设置开盖距离参数,}}

我们用到了定时器0 控制制舵机PWM,定时器1 计算超声波传播路径,外部中断0 结合了震动传感器

4.代码整合

#include<reg51.h>

sbit led1 = P3^7;//固定的口 
sbit led2 = P3^6;//固定的口
sbit key1 = P2^1;//固定的口

sbit Trig = P1^5;//发生超声波
sbit Echo = P1^6;//接收超声波
sbit sg90_con = P1^1;//舵机
sbit vibrate = P3^2;
sbit beep = P2^3;// 蜂鸣器 开盖就响int jd,jd_bak;//0.5的倍数int cnt;//计数int make_vibrate =0;float Dis;//超声波距离voidDelay10us()//@11.0592MHz  //发射超声波最短时间{unsignedchar i;

    i =2;while(--i);}voidDelay150ms()//@11.0592MHz{unsignedchar i, j, k;

    i =2;
    j =13;
    k =237;do{do{while(--k);}while(--j);}while(--i);}voidDelay1000ms()//@11.0592MHz{unsignedchar i, j, k;

    i =8;
    j =1;
    k =243;do{do{while(--k);}while(--j);}while(--i);}voidTimer1Init()//10微秒  //10us 超声波  @11.0592MHz{
    
    TMOD &=0x0F;//设置定时器模式  //选择定时器1
    TMOD |=0x10;
    TL1 =0x00;//设置定时初始值
    TH1 =0x00;//设置定时初始值//不着急开始计数}voidTime0Init()//舵机定时器0 0.5ms  @11.0592MHz{//1. 配置定时器0工作模式位16位计时
    TMOD &=0xF0;//设置定时器模式  //选择定时器1
    TMOD |=0x01;//2. 给初值,定一个0.5出来
    TL0=0x33;
    TH0=0xFE;//3. 开始计时
    TR0 =1;
    TF0 =0;//4. 打开定时器0中断
    ET0 =1;//5. 打开总中断EA
    EA =1;}voidsg90_0_Init(){
    jd =1;//初始角度是0度,0.5ms,溢出1就是0.5,高电平
    cnt =0;
    sg90_con =1;//一开始从高电平开始}voidEX0_Init(){
    EX0 =1;
    IT0 =0;//低电平触发//1的话就是下降言触发}voidstartHC()//发射超声波{
    Trig =0;
    Trig =1;Delay10us();
    Trig =0;}floatgetDis()//获得距离{float TIME;//时间
    TL1 =0x00;//设置定时初始值
    TH1 =0x00;//设置定时初始值startHC();//准备启动while(Echo==0);//等待高电平,跳出循环
    TR1 =1;while(Echo==1);//等待低电平,跳出循环
    TR1 =0;
    TIME =(TH1 *256+ TL1)*1.085;//us//340m/s = 340 00cm/1000ms == 34cm/ms == 0.034cm/us == 0.017cm/usreturn TIME *0.017;//最大12m来回,器件HC是 2cm-4m}voidled1_ON()//亮led1{
    led1 =1;
    led2 =0;}voidled2_ON()//亮led2{
    led1 =0;
    led2 =1;}voidopenDustbin()//开盖{
    jd =3;//90度 1.5ms高电平if(jd_bak != jd){
        cnt =0;//抽搐的原因
        beep =0;Delay150ms();
        beep =1;Delay1000ms();
        jd_bak = jd;}}voidcloseDustbin()//关盖{
     jd =1;//0度
     cnt =0;
     jd_bak = jd;Delay150ms();}voidsetDis(float distance)//设置距离{Delay150ms();if(Dis < distance || key1 ==0|| make_vibrate ==1)//小于10cm 或者按下按键key1 开盖{led1_ON();openDustbin();
            make_vibrate =0;}else{led2_ON();closeDustbin();//make_vibrate = 0;}}intmain(){Time0Init();//初始化定时器Timer1Init();EX0_Init();//外部中断 震动传感器sg90_0_Init();//舵机的初始化while(1){
        Dis =getDis();setDis(10);//设置开盖距离参数,}}voidTime0Handler() interrupt 1//舵机 _中断{
    cnt++;//统计爆表的次数. cnt=1的时候,报表了1//重新给初值
    TL0=0x33;
    TH0=0xFE;//控制PWM波if(cnt < jd){ 
        sg90_con =1;}else{
        sg90_con =0;}if(cnt ==40){//爆表40次,经过了20ms
        cnt =0;//当100次表示1s,重新让cnt从0开始,计算下一次的1s
        sg90_con =1;}}voidEx0_Handler() interrupt 0//震动传感器,外部中断0{
     make_vibrate =1;//震动 标志位改变}

主要还是大家要注意接线,代码模块还是比较简单的;
请添加图片描述


本文转载自: https://blog.csdn.net/Super_Fisher_man/article/details/135577251
版权归原作者 半条-咸鱼 所有, 如有侵权,请联系我们删除。

“智能垃圾桶项目【课程设计】【全套开源】”的评论:

还没有评论