基于51单片机控制的智能垃圾桶

        这个智能垃圾桶由51单片机,SG90舵机,超声波传感器,蜂鸣器,振动传感器组成。当人靠近距离小于10厘米或者按下单片机的key1键或者振动传感器震动,灯盖就会打开,蜂鸣器响600ms,盖子打开2600ms,然后盖子自动关闭。

      我们选择了Timer0定时器及其中断用在输出pwm波来控制舵机的角度。用Timer1来计算超声波测距的来回时间,用INT0触发外部中断来为震动传感器低电平触发中断服务,这样就不会有那么大的延迟效果。下面是代码:

#include"reg52.h"
#include<intrins.h>

sbit D5=P3^7;
sbit D6=P3^6;
sbit Trig=P2^2;
sbit Echo=P2^3;
sbit sg90_con=P3^4;
sbit KEY1=P2^1;
sbit vibrate=P3^2;
sbit beep=P2^5;

int cnt=0;
int jd;
double dis;
int mark_vib=0;//自设标志位
int jd_back ;

void Delay10us()        //@11.0592MHz
{
    unsigned char i;

    i = 2;
    while (--i);
}
void Delay300ms()        //@11.0592MHz
{
    unsigned char i, j, k;

    _nop_();
    
    
    i = 3;
    j = 26;
    k = 223;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}

void Delay2000ms()        //@11.0592MHz
{
    unsigned char i, j, k;

    _nop_();
    i = 15;
    j = 2;
    k = 235;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}


void startHC()//开始条件,给Trig一个10us的高电平,让传感器启动
{
    Trig=0;
    Trig=1;
    Delay10us();
    Trig=0;

}
void Timer0Init()        //500微秒@11.0592MHz
{
    
    TMOD &= 0xF0;        //设置定时器模式为16位
    TMOD |= 0x01;        //设置定时初值
    TL0 = 0x33;        //设置定时初值
    TH0 = 0xFE;
    TF0 = 0;        //清除TF0标志
    TR0 = 1;    //定时器0开始计时
    EA=1;
    ET0=1;
}

void Timer1Init()        //
{
    TMOD &= 0x0F;        //设置定时器模式为16位
    TMOD |= 0x10;
    TL1 = 0x00;        //设置低八位定时初值
    TH1 = 0x00;        //设置高八位定时初值
    
}

double get_distance()
{
    double time;
    startHC();
      while(Echo==0);//Echo由低电平变为高电平时,结束循环,硬件开发送波
        TR1 = 1;//开启计数器计数模式
      while(Echo==1);//Echo由高电平变为低电平时,结束循环,表明硬件接受到返回波
        TR1 = 0;//关闭计数器计数模式
        time=(TH1 * 256 + TL1)*1.085;//计算次数,乘以一次的时间1.085us,得到来回的总时间
        return (0.017 * time);//速度是340m/s=0.034cm/us
    
}

void OpenStatusLight()//D5打开,D6关闭
{
        D5=0;
        D6=1;
}

void CloseStatusLight()//D6打开,D5关闭
{
        D5=1;
        D6=0;
}

void intiSG90_0()//初始化舵机为0度
{
    sg90_con=1;
    jd=1;
    cnt=0;
}

void openDusbin()//舵机旋转90度,顶开垃圾盖。
{
     jd=3;
    if(jd_back!=jd)//添加jd_back!=jd是为了防止舵机抽搐,因为如果手长时间不开超声波传感器
    {              //openDusbin()会被不断地调用,这样就会cnt的值就会不断变化,电平周期会遭到破坏
        cnt=0;
    beep=0;//蜂鸣器报警600ms
    Delay300ms();
    Delay300ms();
    beep=1;//关闭蜂鸣器
        Delay2000ms();//开盖延迟2000ms,方便扔垃圾
    }
    jd_back=jd;
}

void closeDusdin()//舵机为0度,关闭垃圾盖
{
    jd=1;
    jd_back=jd;
        cnt=0;
        Delay300ms();
    
}

void EX0_Init()//INT0外部中断,为震动传感器低电平触发中断服务,这样就不会有那么大的延迟效果
{
    EX0=1;
    IT0=0;//选择低电平触发
}

void main()
{
    
    double dis;
    Timer0Init();
    Timer1Init();
    EX0_Init();
    intiSG90_0();
    while(1)
    {
        Delay300ms();//让硬件稳定
        Timer1Init();//每次都初始化低八位与高八位的值
     dis=get_distance();
        
    if(dis<10.00||KEY1==0||mark_vib==1)//距离小于10,或者按下按键一或者振动传感器震动D5灯亮,D6灯灭
    {
        OpenStatusLight();
      openDusbin();
        mark_vib=0;
  }
    else
    {
        CloseStatusLight();
    closeDusdin();
    }
 }

}

void Time0Handler() interrupt 1
{
      cnt++;
      TL0 = 0x33;        //设置定时初值
      TH0 = 0xFE;
    if(cnt<jd)//控制占空比
    {sg90_con=1;}//sg90_con高电位
    else
    {sg90_con=0;}
        if(cnt==40)//20ms的周期到了,cnt要置0
        {
            cnt=0;
            sg90_con=1;
        }
}

void EX0_Handler() interrupt 0 
{
    mark_vib=1;
}

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值