一、利用超声波模块发送和接受超声波,计算物体与超声波模块之间的距离,最终换算成厘米单位。
二、通过lcd1602液晶显示屏实时显示距离信息。
三、通过判断物体与超声波模块之间的距离,再通过单片机的P1^0引脚产生pwm控制信号 使舵机的默认转角为90度 当距离小于等于20厘米时,产生另一角度的pwm控制信号,使舵机转角转至180度。
四、舵机可通过机械装置连接至水龙头或者其他控制水流开关的闸阀,当物体距离装置小于等于20厘米时闸阀自动开启,开始放水;当物体距离装置大于20厘米时闸阀自动关闭 停止放水
五、20厘米的控制距离和舵机的转角均可通过软件编程再次调整以适应实际的功能需求。
(附加:程序在P3^0引脚加了继电器控制)
(文件里的舵机控制原理的原文地址写一下在附件)
超声波
Trig ------- P2^1;
Echo ------- P2^0;
VCC -------- +5v
GND -------- GND
继电器-----P3^0
舵机
VCC-----+5v
GND-----GND
PWM-----P1^0
请在上电之前,检查好接线是否正确。
图片是简易的自动放水装置 用矿泉水瓶和吸管做的 比较简陋
实物
单片机源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- #include"lcd.h"
- sbit Trig = P2^1;
- sbit Echo = P2^0;
- sbit on=P3^0; //继电器
- sbit pwm=P1^0;//舵机
- unsigned char PuZh[]="SaveWaterSystem ";
- unsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-','M'};
- static unsigned char DisNum = 0; //显示用指针
- unsigned int time=0;
- unsigned long S=0;
- bit flag =0;
- unsigned char disbuff[4] ={ 0,0,0,0,};
-
- int jd;
- int count;
-
-
-
- void Time0_Init() //定时器初始化
- {
-
- TH1 = 0xfe;
- TL1 = 0x33; //11.0592MZ晶振,0.5ms
- TR1=1; //定时器开始
- ET1=1;
- }
- void Time0_Int() interrupt 3 //中断程序
- {
- TH1 = 0xfe; //重新赋值
- TL1 = 0x33;
- if(count< jd) //判断0.5ms次数是否小于角度标识
- pwm=1; //确实小于,PWM输出高电平
- else
- pwm=0; //大于则输出低电平
- count=(count+1); //0.5ms次数加1
- count=count%40; //次数始终保持为40 即保持周期为20ms
- }
-
-
-
- void Conut(void)
- {
- time=TH0*256+TL0;
- TH0=0;
- TL0=0;
-
- S=(time*1.7)/100; //算出来是CM
-
-
- //如果距离小于等于20cm 则继电器打开 舵机转至180度
-
- if(S<=20){
- on=0;
- jd=5;
- count=0;
- }else{
- on=1;
- jd=3; //默认舵机转角为90度
- count=0;
- }
-
-
-
-
-
-
-
-
-
- if((S>=700)||flag==1) //超出测量范围显示“-”
- {
- flag=0;
-
- DisplayOneChar(0, 1, ASCII[11]);
- DisplayOneChar(1, 1, ASCII[10]); //显示点
- DisplayOneChar(2, 1, ASCII[11]);
- DisplayOneChar(3, 1, ASCII[11]);
- DisplayOneChar(4, 1, ASCII[12]); //显示M
- }
- else
- {
- disbuff[0]=S%1000/100;
- disbuff[1]=S%1000%100/10;
- disbuff[2]=S%1000%10 %10;
- DisplayOneChar(0, 1, ASCII[disbuff[0]]);
- DisplayOneChar(1, 1, ASCII[10]); //显示点
- DisplayOneChar(2, 1, ASCII[disbuff[1]]);
- DisplayOneChar(3, 1, ASCII[disbuff[2]]);
- DisplayOneChar(4, 1, ASCII[12]); //显示M
- }
- }
- void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
- {
- flag=1; //中断溢出标志
- }
- void StartModule() //启动模块
- {
- Trig=1; //启动一次模块
- _nop_();
- _nop_(); //表示空循环一个机器指令的时间,12M中表示1us; 21次 大约20us 用于硬件初始化
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- Trig=0;
- }
- void delayms(unsigned int ms)
- {
- unsigned char i=100,j;
- for(;ms;ms--)
- {
- while(--i)
- {
- j=10;
- while(--j);
- }
- }
- }
- void main(void)
- {
- //默认继电器关闭
- on=1;
-
- TMOD=0x11; //设T0为方式1,GATE=1;
- TH0=0;
- TL0=0;
-
-
- ET0=1; //允许T0中断
- EA=1; //开启总中断
-
- jd=3;
- count=0;
- Time0_Init();
- InitLcd1602();
- LcdShowStr(0,0,PuZh);
- while(1)
- {
- StartModule();
- while(!Echo); //当RX为零时等待
- TR0=1; //开启计数
- while(Echo); //当RX为1计数并等待
- TR0=0; //关闭计数
- Conut(); //计算
- delayms(80);
- }
-
- }
复制代码
压缩包里面的内容
所有资料51hei提供下载:
课设(节水系统).rar
(87.39 KB, 下载次数: 44)
|