当前位置: 首页 > wzjs >正文

站长工具在线企查查企业信息查询网

站长工具在线,企查查企业信息查询网,网站自己做还是找人做,旅游网站设计基于51单片机液位控制器 (仿真+程序+原理图PCB+设计报告) 功能介绍 具体功能: 1.使用HC-SR04测量液位,LCD1602显示; 2.当水位高于设定上限的时候,对应声光报警报警&…

基于51单片机液位控制器

(仿真+程序+原理图+PCB+设计报告)

功能介绍

具体功能:

1.使用HC-SR04测量液位,LCD1602显示;

2.当水位高于设定上限的时候,对应声光报警报警,继电器控制水泵停止加水;

3.当水位低于设定上限的时候,对应声光报警报警,继电器控制水泵开始加水;

4.按键可以设置液位上下限;

​演示视频:

基于51单片机的超声波液位测量与控制系统 

程序

/***************************************************************
基于51单片机的超声波水位监测报警系统
具体水泵控制和排水控制
***微信公众号:木子单片机****
***************************************************************/
#include <reg52.h>
#include <intrins.h>		// 包含循环移位:_cror_
#include "main.h"     
//----------------------------------------------------------------------uchar code TabNumASCII[10] =    {'0','1','2','3','4','5','6','7','8','9'};bool	g_flag = isNo;		//用于标记超时(65.536ms) 	  
bool	g_flag05s = isNo;	//用于标记0.52秒  
uchar 	ucCount = 0;			//用于计数0.52秒     uint	uiH = 80;			//设定的最高报警水位 H
uint	uiL = 30;			//设定的最低报警水位 L
uint	uiD = 100; 			//检测探头到水库底部的距离 D bool	g_flagSwitch = isNo;		//控制阀门连续开启间隔延时(保护)标志
bool	g_flagBeepTimer = isNo;	//定时提醒标志//-----------------------------------------------------------------------
// 延时10us
void delay10us(void)		//@12MHz
{unsigned char i;_nop_();i = 2;while (--i);
}// 延时100us
void delay100us(void)		//@12MHz
{uchar i;_nop_();i = 47;while (--i);
}// 延时125us
void delay125us(void)		//@12MHz
{unsigned char i;i = 60;while (--i);
}// 延时5ms
void delay5ms(void)		//@12.000MHz
{unsigned char i, j;i = 10;j = 183;do{while (--j);} while (--i);
}// 延时500ms
void delay500ms(void)		//@12MHz
{unsigned char i, j, k;_nop_();i = 4;j = 205;k = 187;do{do{while (--k);} while (--j);} while (--i);
}//-----------------------------------------------------------------------
//初始化IO端口			
void initIO(void)					
{P0 = 0xff;P1 = 0xff;P2 = 0xff;P3 = 0xff;
}// 初始化定时器0,定时器时钟12T模式 模式1,16位 @12.000MHz
void initTimer0(void)		
{TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0;				//定时器初值清零TH0 = 0;				//定时器初值清零//TR0 = 1;   			//开定时器0ET0 = 1;  			//开定时器0中断EA = 1;     			//开总中断    	}// 初始化定时器1,定时器时钟12T模式 模式1,16位 @12.000MHz
void initTimer1(void)		//50毫秒@12.000MHz
{	TMOD &= 0x0F;		//设置定时器模式TMOD |= 0x10;		//设置定时器模式TL1 = 0xB0;		//设置定时初值TH1 = 0x3C;		//设置定时初值	TR1 = 1;		//定时器1开始计时ET1 = 1;  	//开定时器0中断
}//-----------------------------------------------------------------------
//定时器0中断
void zd0(void) interrupt 1 		 
{g_flag = isYes;							//中断溢出标志,g_flag = isYes超过测距范围if(++ucCount >= 8){ucCount = 0;g_flag05s = isYes;					//g_flag05s = isYes定时0.52秒到,用于测量周期延时}TL0 = 0;		//设置定时初值TH0 = 0;		//设置定时初值}//定时器1中断 定时50ms
void tm1_isr() interrupt 3 using 1
{static uchar count = DATA_switchTime;	//50ms的200倍 = 10Sstatic uchar uiCount = 1200;				//			= 1分钟		static uint uiCount_BeepTimer = DATA_BeepTimer;TL1 = 0xB0;		//设置定时初值TH1 = 0x3C;		//设置定时初值if (g_flagSwitch == isNo){if (count-- == 0)               //50ms * 200 -> 10s{count = DATA_switchTime;g_flagSwitch = isYes;// TR1 = 0;}}	if(g_flagBeepTimer == isNo){if (uiCount-- == 0)               //= 1分钟{uiCount = 1200;if(uiCount_BeepTimer-- == 0){uiCount_BeepTimer = DATA_BeepTimer; g_flagBeepTimer = isYes;// TR1 = 0;}			}}
}//-----------------------------------------------//外部中断1
void exint1() interrupt 2 
{EX1 = 0; 			//关闭当前中断TR0 = 0;   			//关闭时器0}
//-----------------------------------------------------------------------//读LCD忙状态并等待忙状态结束
void LCD_waitNotBusy(void)
{IO_LCD_Data = 0xFF; io_LCD_RS = 0;io_LCD_RW = 1;io_LCD_E = 0;_nop_();_nop_();io_LCD_E = 1;while(IO_LCD_Data & 0x80); //检测如果是忙信号,一直等到不忙
}//给LCD写指令
void LCDWriteCommand(uchar command,bool ifReadBusy) //ifReadBusy = 1 时先进行忙检测
{if (ifReadBusy == isReadBusy) LCD_waitNotBusy(); //根据需要检测忙IO_LCD_Data = command;io_LCD_RS = 0;io_LCD_RW = 0;	io_LCD_E = 0;_nop_();_nop_();io_LCD_E = 1;	
}//给LCD写数据
void LCDWriteData(uchar dat) 
{LCD_waitNotBusy(); //等到不忙IO_LCD_Data = dat;io_LCD_RS = 1;io_LCD_RW = 0;io_LCD_E = 0; _nop_();_nop_();io_LCD_E = 1;
}// 初始化LCD1602液晶显示屏
void initLCD1602(void) 
{uchar	i;	IO_LCD_Data = 0;								// 数据端口清零for(i = 0; i < 3; i++)						// 设置三次显示模式{LCDWriteCommand(0x38,isNotReadBusy);	// 不检测忙信号delay5ms();}LCDWriteCommand(0x38,isReadBusy); // 设置显示模式,检测忙信号LCDWriteCommand(0x08,isReadBusy); // 关闭显示LCDWriteCommand(0x01,isReadBusy); // 显示清屏LCDWriteCommand(0x06,isReadBusy); // 显示光标移动设置LCDWriteCommand(0x0F,isReadBusy); // 显示开及光标设置
}//按指定位置显示一个字符
void putOneCharToLCD1602(uchar line, uchar position, uchar ucData)
{line &= DATA_LineMax;position &= DATA_PositionMax;if (line == DATA_LineTow) position |= 0x40; 			//当要显示第二行时地址码+0x40;position |= 0x80; 									//设置两行显示格式 D7 = 1;LCDWriteCommand(position, isReadBusy); 			//发送命令 设置字符地址LCDWriteData(ucData); 							 	//写入字符的数据	
}//按指定位置显示一串字符
void putLineCharsToLCD1602(uchar line, uchar position, uchar count, uchar code *ucData)
{uchar i;for(i = 0; i < count; i++)							//连续显示单个字符{putOneCharToLCD1602(line, position + i, ucData[i]);	}
}//按指定位置连续显示三个字符(三位数字)
void	putThreeCharToLCD1602(uchar line, uchar position, uint uiNumber)
{uiNumber %= 1000;putOneCharToLCD1602(line, position, TabNumASCII[uiNumber / 100]);putOneCharToLCD1602(line, ++position, TabNumASCII[uiNumber % 100 / 10]);putOneCharToLCD1602(line, ++position, TabNumASCII[uiNumber % 100 % 10]);	}// 按键检测子程序,有键按下返回键端口数据,无键返回0
uchar GetKey(void)
{	uchar KeyTemp = (IO_KEY | DATA_KEY_ORL);		//获取按键端口数据	if( KeyTemp != DATA_KEY_Null )				// 如果不为空{uchar CountTemp = 0;do{delay125us();if(KeyTemp != (IO_KEY | DATA_KEY_ORL)) return 0;	//在延时期间检测键,如果不稳定保持则退出	} while(++CountTemp > Data_Key20msCountMax); 				// 延时20ms去抖动 while((IO_KEY | DATA_KEY_ORL) != DATA_KEY_Null); 	//等键释放		return KeyTemp;	// 有键按下返回键端口数据}return 0;	// 无有效键返回0
}//加一
uchar  INC_Number(uchar Number, uchar Min, uchar Max)
{if(Number >= Max) return Min; else return (++ Number);}//减一
uchar  DEC_Number(uchar Number, uchar Min, uchar Max)
{if(Number <= Min) return Max; else return (-- Number);}// 检测到有按键后 这里执行按键任务			
void execute_key_task(uchar ucKeyValue)	
{uchar state = 0;						//定义调整数据的状态变量uchar keyValue = 0;					//定义键值的临时变量if(ucKeyValue != DATA_KEY_Set) return;	//不是设置键退出//是设置键继续-----------------------------------------------------putLineCharsToLCD1602(lineTow, 8, 8, "C:000cm ");	//清零显示当前距离CURRENT		putThreeCharToLCD1602(lineOne, 8 + 2, uiD);		//光标调整到调整总距离(检测探头到水库底部的距离“D:000cm”)	while(1){keyValue = GetKey();	if(keyValue == 0) continue;switch(keyValue){case DATA_KEY_Set:{// 如果按的是设置键,顺序设置总距离D——高水位H——低水位L——退出switch(state){case 0:			// 如果是设置总距离状态,改变为设置高水位状态,并显示高水位,实现移动光标到高水位后面{state = 1;						putThreeCharToLCD1602(lineOne, 0 + 2, uiH);						}break;case 1:{uchar tempMax = uiD - DATA_uiD_Min;if(tempMax < 2 + 2) tempMax = 2 + 2;											if(uiH > tempMax) {uiH = tempMax;putThreeCharToLCD1602(lineOne, 0 + 2, uiH);}else if(uiH < 2 + 2){uiH = 2 + 2;	putThreeCharToLCD1602(lineOne, 0 + 2, uiH);}							state = 2;putThreeCharToLCD1602(lineTow, 0 + 2, uiL);}break;case 2:{if(uiL > uiH - 2) {uiL = uiH - 2;putThreeCharToLCD1602(lineTow, 0 + 2, uiL);}return;	}break;}}break;// 如果按的是增加键,改变相应数据并显示case DATA_KEY_INC:{switch(state){case 0:{uiD = INC_Number(uiD, DATA_uiD_Min, DATA_uiD_Max);putThreeCharToLCD1602(lineOne, 8 + 2, uiD);							}break;case 1:{uchar tempMax = uiD - DATA_uiD_Min;if(tempMax < 2 + 2) tempMax = 2 + 2;uiH = INC_Number(uiH, 2, tempMax);						putThreeCharToLCD1602(lineOne, 0 + 2, uiH);	}break;case 2:{uiL = INC_Number(uiL, 0, uiH - 2);	putThreeCharToLCD1602(lineTow, 0 + 2, uiL);	}break;}}break;// 如果按的是减少键,改变相应数据并显示case DATA_KEY_DEC:{switch(state){case 0:{uiD = DEC_Number(uiD, DATA_uiD_Min, DATA_uiD_Max);					putThreeCharToLCD1602(lineOne, 8 + 2, uiD);}break;case 1:{uchar tempMax = uiD - DATA_uiD_Min;if(tempMax < 2 + 2) tempMax = 2 + 2;uiH = DEC_Number(uiH, 2, tempMax);						putThreeCharToLCD1602(lineOne, 0 + 2, uiH);	}break;case 2:{uiL = DEC_Number(uiL, 0, uiH - 2);	putThreeCharToLCD1602(lineTow, 0 + 2, uiL);	}break;}}break;}}}// 蜂鸣器	
void	buzzerCall(void)
{uchar	i;for(i = 0; i < 90; i++){io_Buzzer = 0;delay100us();io_Buzzer = 1;delay100us();delay100us();		}delay100us();	delay100us();	
}//计算水位
bool CalculatedWaterLevel(void)
{uchar 	i = 8 + 2;					//当前水位的数字在LCD屏显示的起点位置uint  	uiTime;						//声波传播时间ulong 	ulDis;						//实时测量到距离	uiTime = TH0 << 8 | TL0;	ulDis = (uiTime * 3.40) / 200;     	//计算当前测量的距离,单位cmTH0 = 0;TL0 = 0;	if((ulDis > uiD) || (g_flag == isYes )) 	// ulDis > uiD 超出测量范围;g_flag == isYes超时;{	 g_flag = isNo;		TR0 = 0;putLineCharsToLCD1602(lineTow, i, 3, "Err");	// 显示Err 		//阀门动作:		// if(g_flagSwitch == isYes)// {		// io_Control_Inlet = isio_Control_Inlet_OFF;		// io_Control_Outlet = isio_Control_Outlet_ON;// g_flagSwitch = isNo;// }		//指示灯:ioLed_Red = ! ioLed_Red;							// 三个灯同时快速闪亮ioLed_Green = ! ioLed_Green;ioLed_Yellow = ! ioLed_Yellow;// 蜂鸣器叫:	if(buzzerCallFlag == isCall){buzzerCall();					// 蜂鸣器叫	}return isNo;									// 返回错误信息}else{ulDis = uiD - ulDis;					// 当前水位C = 总距离 - 当前检测到的距离if(ulDis > uiH)						// 如果水位超高{//阀门动作:io_Control_Inlet = isio_Control_Inlet_OFF;io_Control_Outlet = isio_Control_Outlet_ON;	g_flagSwitch = isNo;//指示灯:ioLed_Red = ! ioLed_Red;			// 红灯闪ioLed_Green = isLedOFF;		ioLed_Yellow = isLedOFF;				// 蜂鸣器叫:if(ulDis - uiH > (uiD - uiH) / DATA_alarmCoefficient) //当“当前水位”超出最高水位“ ((“总高度减高水位)除以2的值”)时报警{buzzerCall();					// 蜂鸣器叫}}else if(ulDis < uiL)					// 如果水位超低{//阀门动作:	if(g_flagSwitch == isYes){		io_Control_Outlet = isio_Control_Outlet_OFF;	io_Control_Inlet = isio_Control_Inlet_ON;	g_flagSwitch = isNo;}	//指示灯:ioLed_Red = isLedOFF;ioLed_Green = isLedOFF;ioLed_Yellow = ! ioLed_Yellow;	//黄灯闪// 蜂鸣器叫:						if( uiL - ulDis > uiL / DATA_alarmCoefficient)//uiL / 2 当“当前水位”低于“低水位” “低水位除以2的值”时报警{buzzerCall();					// 蜂鸣器叫}
****/*完整资料
***//***微信公众号:木子单片机****			}else								// 水位在正常范围 {	ioLed_Red = isLedOFF;ioLed_Green = ! ioLed_Green;ioLed_Yellow = isLedOFF;	}putThreeCharToLCD1602(lineTow, i, ulDis);return isYes;	}return isYes;
}

硬件设计

使用元器件:

单片机:STC89C51;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

9*15万用板;超声波模块;

40脚IC座;4脚排针;

杜邦线;继电器;

LCD1602液晶;103电位器;

USB电源线(电池盒);

16脚IC座;16脚排针;

蜂鸣器;8550三极管;

1k电阻;10k电阻;

10uf电容;30pf电容;

12M晶振;3mmLED;

轻触按键;自锁开关;

DC电源插口;

直流水泵;

导线:若干;

添加图片注释,不超过 140 字(可选)

结构框图:

添加图片注释,不超过 140 字(可选)

设计资料

01仿真图

本设计使用proteus8.9版本设计,仿真和实物有些差异,有对应的仿真程序!具体如图!

添加图片注释,不超过 140 字(可选)

02原理图

本系统原理图采用Altium Designer19设计,具体如图!

添加图片注释,不超过 140 字(可选)

03程序

本设计使用软件keil5版本编程设计!具体如图!

添加图片注释,不超过 140 字(可选)

04设计报告

一万一千字设计报告,仅供参考,具体如下!

添加图片注释,不超过 140 字(可选)

05设计资料

        资料获取请看前面演示视频,全部资料包括仿真源文件 、AD原理图、程序(含注释)、PCB、任务书、设计报告、结构框图、实物图、元件清单、讲解视频等。具体内容如下,全网最全! !

操作演示请观看前面演示视频!

点赞分享一起学习成长。


文章转载自:

http://IMAbiP6A.jfcbz.cn
http://dayKH9tM.jfcbz.cn
http://ehASZlUq.jfcbz.cn
http://NBbmOAvI.jfcbz.cn
http://79tbqbI2.jfcbz.cn
http://rbxx9V8e.jfcbz.cn
http://ymoJwVDv.jfcbz.cn
http://vbVmJZTm.jfcbz.cn
http://hkRbd37V.jfcbz.cn
http://xdz848KZ.jfcbz.cn
http://HqifXn22.jfcbz.cn
http://1jAJrd5i.jfcbz.cn
http://2iSJU2sJ.jfcbz.cn
http://N9oGO9oo.jfcbz.cn
http://TEP7koy9.jfcbz.cn
http://8qNvwj52.jfcbz.cn
http://0dlqx60j.jfcbz.cn
http://LtgzNVPu.jfcbz.cn
http://NZ3eYHiC.jfcbz.cn
http://8nIDry5f.jfcbz.cn
http://cnJBBLWE.jfcbz.cn
http://4E7nVJ5Z.jfcbz.cn
http://V5ooZa7w.jfcbz.cn
http://Y7hx7pUT.jfcbz.cn
http://UEOyexKd.jfcbz.cn
http://mNJlkV7p.jfcbz.cn
http://jz1vI6jl.jfcbz.cn
http://JbAqo3c8.jfcbz.cn
http://S3ra0z8p.jfcbz.cn
http://T6fbULyq.jfcbz.cn
http://www.dtcms.com/wzjs/758511.html

相关文章:

  • mip网站实例厦门做网站个人
  • 电子商务网站开发与管理实验报告客户推广渠道有哪些
  • 石家庄市住房和城乡建设局官方网站西安大雁塔的历史简介
  • 厦门功夫广告设计网站建设工作室网站设计的公司如何选
  • 服装店网站建设规划书网络广告有哪些
  • 沈阳做网站公司有哪些建设银行唐山分行网站
  • 企业网站模板源码有哪些什么是网络营销媒体
  • 网站开发人员结构温州网站优化价格
  • 成都全网营销型网站中山网站制作方案
  • 网站地域分站怎么做如何使用花生壳做网站
  • 做网站赚钱还是企业宣传片企业解决方案
  • photoshop设计一个精美的网站主页企业网站一年多少钱
  • 咸阳企业网站设计开发制作太原做网站设计
  • 如何快速建设推广网站什么是网站主题
  • 建企业网站哪个平台好阿里邮箱
  • 外贸soho自己建站小男孩与大人做的网站
  • 无锡网站建设方案服务网站如何申请微信支付
  • 深圳商城网站设计多少钱关于做网站的策划书
  • 网站模板带后台石嘴山网站关于两学一做
  • 用织梦网站后台发布文章为什么还需要审核网站深圳
  • 无需下载国外黄冈网站推广短期培训就业学校
  • 用python做的电商网站辽宁沈阳建设工程信息网站
  • 专业手机网站建设网站开发需要的编程软件有哪些
  • 做相册本哪个网站好用整合营销是什么
  • 网站建设中的板块名称专业网页制作软件能帮助用户组织和管理
  • 做网站怎么保证商品是正品wordpress 放弃
  • 教育网站建设解决方案ppt模板免费下载百度文库
  • 企业怎么做自己的网站杭州知名设计公司
  • 安徽旅游在线网站建设建设银行网站钓鱼
  • 网页制作与网站建设课程设计wordpress 商品页面