本文主要是介绍感应开关盖垃圾桶,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
感应开关盖垃圾桶
-
功能描述
检测靠近时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
发生震动时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
按下按键时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
-
硬件说明
SG90舵机,超声波模块,震动传感器,蜂鸣器
-
接线说明
舵机控制口 P1.1;超声波Trig接 P1.5 ,Echo接 P1.6 ;蜂鸣器接 P2.0 口; 震动传感器接 P3.2`口(外部中断0)
-
编程实现
-
舵机和超声波代码整合
舵机用定时器0
超声波用定时器1
实现物体靠近后,自动开盖,2秒后关盖
-
查询的方式添加按键控制
-
查询的方式添加震动控制
-
使用外部中断0配合震动控制
-
-
代码
#include "reg52.h" #include <intrins.h> //垃圾桶感应开关盖 sbit Trig = P1^5;//超声波触发 sbit Echo = P1^6;//超声波计时 sbit D5 = P3^7;//led sbit D6 = P3^6; sbit vibrate = P3^2;//振动信号:不震动时输出1,振动输出0 sbit sw1 = P2^1;//按键1 sbit pwm = P1^1;//舵机信号 sbit beep = P2^0;//蜂鸣器int cnt = 0;//定时器0溢出计数 int jd = 0;//舵机旋转角度:1为0°,每增加1,角度增加45° int mark_vibrate = 0;//振动标志 int mark_jd = 0;//角度标志void time0_init()//定时器0初始化函数 {TMOD &= 0xF0;//选择定时器0模式TMOD |= 0x01;TL0 = 0x33;//给定定时器0初值TH0 = 0xFE;TR0 = 1;//开启定时器0TF0 = 0;EA = 1;//开启中断ET0 = 1; }void time1_init()//定时器1初始化函数 {TMOD &= 0x0F;//选择定时器1模式,16位TMOD |= 0x10;TL1 = 0;//定时器1初值为0TH1 = 0; }void sg90_init()//舵机初始化 {jd = 1;//0°cnt = 0;pwm = 1; } void ex0_init()//外部中断0 初始化 {EX0 = 1;//开启中断IT0 = 1;//设置为下降沿触发 } void Delay50ms() //@11.0592MHz {unsigned char i, j;i = 90;j = 163;do{while (--j);} while (--i); }void Delay1000ms() //@11.0592MHz {unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i); }void Delay10us() //@11.0592MHz {unsigned char i;i = 2;while (--i); }void start_HC()//给trig 10us高电平,触发超声波 {Trig = 0;Trig = 1;Delay10us();Trig = 0; }double getDistance() {double time;TL1 = 0;//定时器归零TH1 = 0;start_HC();//给trig一个10us的高电平开启测距 while(Echo == 0);//echo由低到高开始计时TR1 = 1;while(Echo == 1);//echo由高到低结束计时 TR1 = 0;time = (TH1*256 + TL1) * 1.085;//计算时间,单位:us//将TH0和TL0两个8位合成一个16位,需要把TH0向左移8位,则需要将TH0 乘以 2的8次方return (0.017 * time);//计算距离340m/s=34000cm/s=34cm/ms=0.034cm/us 单位:cm} void openLed() {D5 = 1;D6 = 0; }void closeLed() {D5 = 0;D6 = 1; } void openDustbin() {int n;jd = 3;//90°if(mark_jd != jd){//角度不发生变化cnt = 0;beep = 0;for(n=0;n<4;n++){Delay50ms();}beep = 1;while(vibrate == 0);}mark_jd = jd; } void closeDustbin() {Delay1000ms();//延时2s关盖Delay1000ms();jd = 1;cnt = 0;mark_jd = jd;Delay50ms(); } void main() {double dis;Delay1000ms();//稳定一下time1_init();//全部初始化time0_init();sg90_init();ex0_init();mark_jd = 1;beep = 1;while(1){dis = getDistance();if(dis < 10 || sw1 == 0 || mark_vibrate == 1){//接近垃圾桶、按键、振动openLed();openDustbin();mark_vibrate = 0;}else{closeLed();closeDustbin();}Delay50ms();//延时一下,防止程序buzy测不了距离} } void time0_inter() interrupt 1//定时器0中断 {//定时器0溢出后cnt++,同时还原初值cnt++;TL0 = 0x33;TH0 = 0xFE;if(cnt < jd){pwm = 1;}else{pwm = 0;}//cnt=40后,正好20ms一个周期if(cnt == 40){cnt = 0;pwm = 1;} } void ex0_inter() interrupt 0 {mark_vibrate = 1; }
这篇关于感应开关盖垃圾桶的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!