基于51单片机水塔水位控制
(仿真+程序)
功能介绍
具体功能:
1.用滑动变阻器模拟水位,ADC0809将模拟信号转换为数字信号;
2.LCD1602显示当前水位和水位阈值;
3.当水位超过设定阈值,蜂鸣器+LED声光报警,并且电机转动(模拟排水);
4.三个按键可以设定水位阈值;
演示视频:
基于51单片机水塔水位控制系统
添加图片注释,不超过 140 字(可选)
程序
//程序头函数
#include <reg52.h>
#include <intrins.h>
/***公众号:木子单片机****/
//宏定义
#define uint unsigned int
#define uchar unsigned char
#define Data_ADC0809 P1 //定义P1口为Data_ADC0809//管脚声明
sbit LED_R= P2^2; //红色指示灯
sbit LED_G= P2^0; //绿色指示灯
sbit FENG = P2^5; //蜂鸣器
sbit san=P3^4; //继电器
//ADC0809
sbit ST=P3^3;
sbit EOC=P3^6;
sbit OE=P3^2;
//按键
sbit Key1=P2^6;
sbit Key2=P2^7;
sbit Key3=P3^7;bit bdata flag; //定义位变量
uchar set; //设置变量sbit RS=P2^3;
sbit RW=P2^1;
sbit EN=P2^4;
//ADC数值
uchar ADC_value=0;//报警数值
uchar WARNING=25; //报警值变量//延时函数
void Delay1ms( int ms)
{ int i;while(ms--){for(i = 0; i< 250; i++){_nop_();_nop_();_nop_();_nop_();}}
}//检查忙函数
bit check()
{ bit busy;RS=0;RW=1;EN=1;Delay1ms(2);EN=0;return busy;
}//写指令函数
write_com(uchar zhi)
{while(check());RS=0;RW=0;EN=0;_nop_();_nop_();P0=zhi;_nop_();_nop_();_nop_();_nop_();EN=1; _nop_();_nop_();_nop_();_nop_();EN=0;
}//写数据函数
write_data(uchar shu)
{while(check());RS=1;RW=0;EN=0;_nop_();_nop_();P0=shu;_nop_();_nop_();_nop_();_nop_();EN=1;_nop_();_nop_();_nop_();_nop_();EN=0;
}//初始化LCD函数
void Init1602()
{write_com(0x38);Delay1ms(1);write_com(0x0c);Delay1ms(1); write_com(0x06);Delay1ms(1);write_com(0x01); Delay1ms(1);
}//ADC0809读取信息
uchar ADC0809()
{uchar temp=0x00;//初始化高阻太OE=0;//转化初始化ST=0;//开始转换ST=1;Delay1ms(1);ST=0;//外部中断等待AD转换结束while(EOC==0)//读取转换的AD值OE=1;temp=Data_ADC0809;OE=0;return temp;
}void Key() //按键函数
{if(Key1==0) //设置键按下{while(Key1==0); //按键松开FENG=0; //蜂鸣器响set++; //设置变量加flag=0; //关闭报警san=1; //关闭继电器TR0=0; //关闭定时器}if(set==1) //设置报警值时{write_com(0x38);//屏幕初始化write_com(0x80+0x40+13);//位置write_com(0x0f);//打开显示 无光标 光标闪烁write_com(0x06);//当读或写一个字符是指针后一一位FENG=1; //关闭蜂鸣器}else if(set>=2) //设置完成时{set=0; //变量清零write_com(0x38);//屏幕初始化 write_com(0x80);write_com(0x0c);//打开显示 无光标 无光标闪烁FENG=1; //关闭蜂鸣器flag=1; //打开报警TR0=1; //打开定时器}if(Key2==0&&set!=0) //设置报警值时加键按下{while(Key2==0); //按键松开FENG=0; //打开蜂鸣器WARNING++; //报警值加if(WARNING>=255) //最大加到255WARNING=0; //清零write_com(0x80+0x40+11); //选中液晶屏上的第二行第十一列write_data('0'+WARNING/100); //开始显示报警值。例如报警值是123,123除以100的商是1,加上‘0’是为了得到液晶中对应1的显示码write_data('0'+WARNING%100/10);//123除以100的余数是23,23再除以10得到的商是2write_data('0'+WARNING%100%10);//23除以10的余数是3write_com(0x80+0x40+13);//位置FENG=1; //关闭蜂鸣器}if(Key3==0&&set!=0) //注释同加按键{while(Key3==0);FENG=0;WARNING--;if(WARNING<=0)WARNING=255;write_com(0x80+0x40+11);write_data('0'+WARNING/100);write_data('0'+WARNING/10%10);write_data('0'+WARNING%10);write_com(0x80+0x40+13);//位置FENG=1;}
}
//显示AD数值和报警数值
void Display1602(uchar tempADC,uchar tempWaring)
{const uchar buf1[]={"Level:"};const uchar buf2[]={"Setup:"};int i=0x00;uchar temp = 0;write_com(0x80|0x05); //第一行显示while(buf1[i]!=0){write_data(buf1[i]);i++;} temp = tempADC/100 + '0';write_data(temp);temp = tempADC%100/10 + '0';write_data(temp);temp = tempADC%10 + '0';write_data(temp);write_data(' ');write_data(' ');write_com(0x80|0x45); //第二行显示i=0x00;while(buf2[i]!=0){write_data(buf2[i]);i++;}temp = tempWaring/100 + '0';write_data(temp);temp = tempWaring%100/10 + '0';write_data(temp);temp = tempWaring%10 + '0';write_data(temp);
}void init() //定时器初始化函数
{TMOD=0x01; //定时器工作方式TL0=0xb0;TH0=0x3c; //赋初值50msEA=1; //打开中断总开关ET0=1; //打开定时器0中断允许开关TR0=1; //打开定时器0定时开关
}void main() //主函数
{Init1602(); //初始化液晶函数init(); //初始化定时器while(1) //进入循环{ADC_value=ADC0809(); //读取AD数值if(set==0) //set为0,说明现在不是设置状态Display1602(ADC_value,WARNING); //显示AD数值和报警值if(ADC_value<WARNING&&set==0) //AD数值小于报警值{flag=0; //关闭报警}else if(ADC_value>WARNING&&set==0)//AD值大于报警值{flag=1; //打开报警}Key(); //调用按键函数}
}
void time1_int(void) interrupt 1 //定时器工作函数
{uchar count; //定义计时变量TL0=0xb0;TH0=0x3c; //重新赋初值50mscount++; //变量加一次就是50msif(count==10) //加到10次就是500ms{if(flag==0) //flag=0时,也就是不开启报警{LED_G=0; //绿灯点亮LED_R=1; //红灯熄灭FENG=1; //关闭蜂鸣器san=1; //关闭继电器}if(flag==1) //flag为1时,也就是打开报警{LED_G=1; //绿灯熄灭LED_R=0; //红灯点亮FENG=0; //打开蜂鸣器san=0; //打开继电器}}if(count==20) //计数20次,就是1s{ //在1s时,红绿灯都是熄灭状态,蜂鸣器也是关闭状态,装可以达到闪烁的目的count=0; //变量清零if(flag==0) //不是报警状态时{LED_G=1;LED_R=1;FENG=1;san=1; //都关闭}if(flag==1) //报警状态时{LED_G=1;LED_R=1;FENG=1;san=0; //继电器一直吸和}}
}
硬件设计
使用元器件:
单片机:AT89C52;
(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)
添加图片注释,不超过 140 字(可选)
设计资料
01仿真图
本设计使用proteus7.8和proteus8.9两个版本设计!具体如图!
添加图片注释,不超过 140 字(可选)
02程序
本设计使用软件keil4和keil5版本编程设计!具体如图!
添加图片注释,不超过 140 字(可选)
03设计资料
资料获取请关注同名公众号,全部资料包括仿真源文件 、程序(含注释)等。具体内容如下,全网最全! !
资料获取请观看前面演示视频!
点赞分享一起学习成长。