• C51--项目--感应开关盖垃圾桶


    1、项目概述

    功能描述:
    检测靠近时,垃圾桶自动开盖并伴随滴一声,2s后关盖。
    发生震动时,垃圾桶自动开盖并伴随滴一声,2s后关盖。
    按下按键时,垃圾桶自动开盖并伴随滴一声,2s后关盖。

    硬件说明:
    c52单片机、sg90舵机、超声波模块、震动传感器、蜂鸣器

    接线说明:
    舵机控制口 P1.1
    超声波 Trig 接 P1.5口
    Echo 接 P1.6口
    蜂鸣器接 P2.0口
    震动传感器接 P3.2口(外部中断INT0)

    2、编程实现

    开发步骤
    1、舵机和超声波代码整合,
    舵机用定时器0,
    超声波用定时器1,
    (手册中高 4 位管定时器 1 ,低 4 位管定时器 0。0x0F:F四个一,保持低四位不变,高四位全部为0;0x10:低四位不变,使高四位M0变为16位定时器)
    实现物体靠近自动滴一声开盖,2s后关盖
    2、查询法实现按键控制
    3、查询法实现震动控制
    4、使用外部中断0配合震动控制

    3、优化

    解决靠近超2s抽搐问题,
    添加延时关盖
    优化关盖震动控制开盖问题

    #include "reg52.h"
    #include 
    
    //距离小于10cm,D5亮,D6灭,反之相反
    
    sbit SW1			 = P2^1;	//按键开关接口
    sbit D5		     = P3^7;
    sbit D6 		   = P3^6;
    sbit Trig		   = P1^5;
    sbit Echo		   = P1^6;
    sbit sg90_con  = P1^1;	//舵机
    sbit vibrate   = P3^2;	//振动传感器(外部中断)
    sbit beep			 = P2^0;	//蜂鸣器(低电平响)
    
    //int换为char,节省空间
    char jiaodu;
    char jiaodu_bak;
    char cnt = 0;
    char mark_vibrate = 0;	//外部中断标志位
    
    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 Delay150ms()		//@11.0592MHz
    {
    	unsigned char i, j, k;
    
    	_nop_();
    	i = 2;
    	j = 13;
    	k = 237;
    	do
    	{
    		do
    		{
    			while (--k);
    		} while (--j);
    	} while (--i);
    }
    
    
    void Delay10us()		//@11.0592MHz
    {
    	unsigned char i;
    
    	i = 2;
    	while (--i);
    }
    
    void startHC()
    {
    	Trig = 0;
    	Trig = 1;
    	Delay10us();
    	Trig = 0;
    }
    
    //定时器0初始化
    void Time0Init()
    {
    	TMOD &= 0xF0;		//设置定时器 0 模式
    	TMOD |= 0x01;		
    	TL0 = 0x33;		  //给初值,定一个0.5ms
    	TH0 = 0xFE;									
    	ET0 = 1;				//打开定时器0中断			
    	EA = 1;					//打开总中断EA
    	TR0 = 1;		    //开始计时
    	TF0 = 0;
    }
    
    //定时器1初始化
    void Time1Init()		
    {
    	TMOD &= 0x0F;		//设置定时器 1 模式
    	TMOD |= 0x10;
    	TH1 = 0;
    	TL1 = 0;
    	//设置定时器0工作模式1,初值设定为0开始数数,不着急启动定时器
    }
    
    /*
    十进制左移一位相当于乘以10。例:2左移一位为20
    二进制左移一位相当于乘以2.  例:1左移一位为10(十进制的2)
    左移8位,相当于乘以2的8次方 = 256
    */
    
    double get_distance()		//封装函数距离
    {
    	double time;//时间
    	
    	//定时器数据清零,方便下一次测距
    		TH1 = 0;
    		TL1 = 0;
    	
    	startHC();					//给TRIG一个10us的高电平
    	while(Echo == 0);		//ECHO由**低电平跳转到高电平**表示开始发送波
    	TR1 = 1;						//波发送时启动定时器
    	while(Echo == 1);		//ECHO由**高电平跳转到低电平**表示波返回
    	TR1 = 0;						//波回来时关闭定时器
    	time = (TH1 * 256 + TL1)*1.085;		//计算中间经过的时间,以 um 为单位
    	return (time * 0.017);
    	//距离=(时间)*波的速度(340m/s)/ 2 ; 340m/s = 34cm/ms = 0.034cm/us
    }
    
    void openStatuslight()		//封装函数,状态灯开D5亮,开盖
    {
    	D5 = 0;
    	D6 = 1;
    }
    
    void closeStatuslight()		//封装函数,状态灯关D5灭,关盖
    {
    	D5 = 1;
    	D6 = 0;
    }
    
    void initSG90_0()		//封装函数,舵机角度
    {
    	jiaodu = 1;	//初始化角度,0°,0.5ms的高电平
    	cnt = 0;		//角度变化,cnt从0计算
    	
    	sg90_con = 1;//给高电平
    }
    
    void openDustbin()//封装函数,舵机转动角度--打开垃圾桶
    {
    	char n;
    	jiaodu = 4;//爆表4次,0.5*4=2ms高电平,转135度
    	if(jiaodu_bak != jiaodu){
    		cnt = 0;
    	
    		beep = 0;		//蜂鸣器响
    		for(n = 0;n < 2;n++);
    			Delay150ms();
    		beep = 1;
    		Delay2000ms();	//每隔两秒转一次
    	}
    	
    	jiaodu_bak = jiaodu;
    
    }
    
    void closeDustbin()//封装函数,舵机转动角度--关闭垃圾桶
    {
    	jiaodu = 1;
    	jiaodu_bak = jiaodu;
    	cnt = 0;
    	Delay150ms();
    }
    
    void EX0_Init()	//封装函数,外部中断
    {
    	EX0 = 1;		//打开外部中断  (下降沿触发IT0/TCON.0 = 1 ;低电平触发IT0/TCON.0 = 0 )
    	IT0 = 0;		//低电平触发
    }
    
    void main()
    {
    	
    	double dis;//距离
    	
    	Time0Init();//定时器0初始化
    	Time1Init();//定时器1初始化
    	
    	EX0_Init();
    	initSG90_0();//舵机角度
    	
    	while(1){
    		
    		dis = get_distance();//超声波测距
    		
    		if(dis < 10 || SW1 == 0 || mark_vibrate == 1){			//小于10cm,或者sw1按键被按下,或者震动产生
    			//振动产生有可能发生在延时期间,电频转变急促,不稳定,所以要使用外部中断(INIT0 )
    			openStatuslight();	//D5亮,开盖
    			openDustbin();			//打开垃圾桶
    			mark_vibrate = 0;		//恢复
    			
    		}else{
    				closeStatuslight();	//D5灭,关盖
    				closeDustbin();			//关闭垃圾桶
    				
    			}
    	}
    	
    } 
    
    //定时器0中断
    void Time0Handler() interrupt 1
    {
    		cnt++;				//统计爆表的次数
    		TL0 = 0x33;		//重新给初值
    		TH0 = 0xFE;
    		if(cnt < jiaodu){		//PWM波形控制
    			sg90_con = 1;
    		}else{
    				sg90_con = 0;
    			}
    	
    		if(cnt == 40){ //爆表40次,经过20ms
    			cnt = 0;			//重新计算cnt
    			sg90_con = 1;
    		}
    }
    
    //外部中断
    void EX0_Handler() interrupt 0
    {
    	mark_vibrate = 1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
  • 相关阅读:
    C++设计模式-装饰器(Decorator)
    Unity 灯光组件Light
    C语言编写一个程序采集招聘信息
    jira搜索search issue条目rest实用脚本
    Linux驱动.之I2C,iic驱动层(二)
    Vue.js+SpringBoot开发生活废品回收系统
    Flink系列之Flink中Checkpoint容错机制
    使用Go的encoding/asn1库处理复杂数据:技巧与最佳实践
    机器学习_类偏斜的误差度量
    Python也能在web界面写爬虫了
  • 原文地址:https://blog.csdn.net/weixin_48208102/article/details/134066412