适合初学者的简易水位控制系统仿真原理图如下
单片机源程序如下:
- #include "reg52.h"
- //宏定义
- #define uint unsigned int
- #define uchar unsigned char
- //LCD管脚声明
- sbit LCDRS = P1^1;
- sbit LCDEN= P1^2;
- //初始化时显示的内容
- uchar code Init1[]="Tp:00.0 C Ti:000";
- uchar code Init2[]="Up:00 Down:00 ";
- //液晶的基本操作程序
- //LCD延时
- void LCDdelay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=10;y>0;y--);
- }
- //写命令
- void write_com(uchar com)
- {
- LCDRS=0;
- P0=com;
- LCDdelay(5);
- LCDEN=1;
- LCDdelay(5);
- LCDEN=0;
- }
- //写数据
- void write_data(uchar date)
- {
- LCDRS=1;
- P0=date;
- LCDdelay(5);
- LCDEN=1;
- LCDdelay(5);
- LCDEN=0;
- }
- //显示时间温度数据程序
- void Display_1602(uint aa,uchar dss,uchar sxx,uchar xxx)
- {
- //温度显示
- write_com(0x80+3);
- write_data('0'+aa/100);
- write_data('0'+aa/10%10);
- write_data('.');
- write_data('0'+aa%10);
- write_data(0xdf);
- //定时显示
- write_com(0x80+13);
- write_data('0'+dss/100);
- write_data('0'+dss/10%10);
- write_data('0'+dss%10);
- //上限显示
- write_com(0x80+0x40+3);
- write_data('0'+sxx/10%10);
- write_data('0'+sxx%10);
- //下限显示
- write_com(0x80+0x40+13);
- write_data('0'+xxx/10%10);
- write_data('0'+xxx%10);
- }
- //字符显示程序
- void Display_wd()
- {
- //温度显示
- write_com(0x80);
- write_data('S');
- write_data('e');
- write_data('t');
- write_data(' ');
- write_data('s');
- write_data('t');
- write_data('a');
- write_data('t');
- write_data('e');
- }
- //1602初始化程序
- //1602初始化
- void Init1602()
- {
- uchar i=0;
- // write_com(0x01);//清屏
- write_com(0x38);//屏幕初始化
- write_com(0x0c);//打开显示 无光标 无光标闪烁
- write_com(0x06);//当读或写一个字符是指针后一一位
- write_com(0x80);//设置位置
- for(i=0;i<16;i++)
- {
- write_data(Init1[i]);
- }
- write_com(0x80+0x40);//设置位置
- for(i=0;i<16;i++)
- {
- write_data(Init2[i]);
- }
- }
- //程序头函数
- #include
- //显示函数
- #include
- //宏定义
- #define uint unsigned int
- #define uchar unsigned char
- //LCD管脚声明
- sbit jdq= P1^0; //加热继电器
- sbit shui=P1^3;//加水继电器
- sbit Feng = P2^6; //蜂鸣器
- //按键
- sbit Key1=P1^4; //设置
- sbit Key2=P1^5; //加
- sbit Key3=P1^6; //减
- sbit Key4=P1^7; //确定
- sbit shang=P3^7;//上限
- sbit xia=P3^6;//下限
- sbit DQ=P2^2; //定义DS18B20总线I/O
- signed char w,bj,bjx,bjd; //温度值全局变量
- uchar c; //温度值全局变量
- bit bdata flag=0,flag_BJ,flag_off=1,que;
- //时间计算
- #define Imax 14000 //此处为晶振为11.0592时的取值,
- #define Imin 8000 //如用其它频率的晶振时,
- #define Inum1 145 //要改变相应的取值。
- #define Inum2 700
- #define Inum3 3000
- //解码变量
- unsigned char Im[4]={0x00,0x00,0x00,0x00};
- //全局变量
- uchar f;
- unsigned char m,Tc;
- unsigned char IrOK;
- //设置变量
- uchar xx=29;
- //下限
- uchar sx=35;
- //上限
- int ds=0;
- uchar Mode=0;
- void delay(uint z)
- {
- uint i,j;
- for(i=0;i
- for(j=0;j<121;j++);
- }
- //温度工作程序
- /*****延时子程序*****/
- void Delay_DS18B20(int num)
- {
- while(num--) ;
- }
- /*****初始化DS18B20*****/
- void Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1; //DQ复位
- Delay_DS18B20(8); //稍做延时
- DQ = 0; //单片机将DQ拉低
- Delay_DS18B20(8); //精确延时,大于480us
- DQ = 1; //拉高总线
- Delay_DS18B20(14);
- x = DQ; //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
- Delay_DS18B20(20);
- }
- /*****读一个字节*****/
- unsigned char ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 给脉冲信号
- dat>>=1;
- DQ = 1; // 给脉冲信号
- if(DQ)
- dat|=0x80;
- Delay_DS18B20(4);
- }
- return(dat);
- }
- /*****写一个字节*****/
- void WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 1;
- DQ = dat&0x10;
- Delay_DS18B20(5);
- DQ = 0;
- dat>>=1;
- }
- }
- /*****读取温度*****/
- unsigned int ReadTemperature(void)
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned int t=0;
- float tt=0;
- Init_DS18B20();
- WriteOneChar(0xC1); //跳过读序号列号的操作
- WriteOneChar(0x44); //启动温度转换
- Init_DS18B20();
- WriteOneChar(0xC1); //跳过读序号列号的操作
- WriteOneChar(0xBE); //读取温度寄存器
- a=ReadOneChar(); //读低8位
- b=ReadOneChar(); //读高8位
- t=b;
- t<<=8;
- t=t|a;
- tt=t*0.00625;
- t= tt*10+0.5; //放大10倍输出并四舍五入
- return(t);
- }
- /*****读取温度*****/
- void check_wendu(void)
- {
- c=ReadTemperature()-5; //获取温度值并减去DS18B20的温漂误差
- w=c/10; //计算得到整数位
- if(w<0){w=0;} //设置温度显示上限
- if(w>99){w=99;} //设置温度显示上限
- }
- //按键工作程序
- void Key()
- {
- //模式选择
- if(Key1==0)
- {
- while(Key1==0);
- Feng=0;
- Mode++;
- Display_wd();
- if(Mode==4)
- {
- Mode=1;
- Feng=1;
- }
- write_com(0x38);//屏幕初始化
- write_com(0x0d);//打开显示 无光标 光标闪烁
- write_com(0x06);//当读或写一个字符是指针后一一位
- switch(Mode)
- {
- case 1:
- {
- write_com(0x80+15);//位置
- Feng=1;
- break;
- }
- case 2:
- {
- write_com(0x80+0x40+4);//位置
- Feng=1;
- break;
- }
- case 3:
- {
- write_com(0x80+0x40+14);//位置
- Feng=1;
- break;
- }
- }
- }
- if(Key2==0&&Mode!=0)
- {
- while(Key2==0);
- Feng=0;
- switch(Mode)
- {
- case 1:
- {
- if(ds<999)
- {
- ds++;
- write_com(0x80+13);
- write_data('0'+ds/100);
- write_data('0'+ds/10%10);
- write_data('0'+ds%10);
- write_com(0x80+15);//位置
- }
- Feng=1;
- break;
- }
- case 2:
- {
- if(sx<99-1)
- {
- sx++;
- write_com(0x80+0x40+3);
- write_data('0'+sx/10%10);
- write_data('0'+sx%10);
- write_com(0x80+0x40+4);//位置
- }
- Feng=1;
- break;
- }
- case 3:
- {
- if(xx
- {
- xx++;
- write_com(0x80+0x40+13);
- write_data('0'+xx/10%10);
- write_data('0'+xx%10);
- write_com(0x80+0x40+14);//位置
- }
- Feng=1;
- break;
- }
- }
- }
- if(Key3==0&&Mode!=0)
- {
- while(Key3==0);
- Feng=0;
- switch(Mode)
- {
- case 1:
- {
- if(ds>0)
- {
- ds--;
- write_com(0x80+13);
- write_data('0'+ds/100);
- write_data('0'+ds/10%10);
- write_data('0'+ds%10);
- write_com(0x80+15);//位置
- }
- Feng=1;
- break;
- }
- case 2:
- {
- if(sx>xx+1)
- {
- sx--;
- write_com(0x80+0x40+3);
- write_data('0'+sx/10%10);
- write_data('0'+sx%10);
- write_com(0x80+0x40+4);//位置
- }
- Feng=1;
- break;
- }
- case 3:
- {
- if(xx>0)
- {
- xx--;
- write_com(0x80+0x40+13);
- write_data('0'+xx/10%10);
- write_data('0'+xx%10);
- write_com(0x80+0x40+14);//位置
- }
- Feng=1;
- break;
- }
- }
- }
- if(Key4==0)
- {
- while(Key4==0);
- Feng=0;
- Mode=0;
- // write_com(0x38);//屏幕初始化
- // write_com(0x0c);//打开显示 无光标 无光标闪烁
- Init1602();
- if(ds>0)
- {
- flag=1;
- jdq=1;
- TR1=1;
- }
- Feng=1;
- }
- }
- /* if(IrOK==1)
- {
- if(Im[2]==0x0d) //遥控设置键
- {
- Feng=0;
- Mode++;
- Display_wd();
- if(Mode==4)
- {
- Mode=1;
- Feng=1;
- }
- write_com(0x38);//屏幕初始化
- write_com(0x0d);//打开显示 无光标 光标闪烁
- write_com(0x06);//当读或写一个字符是指针后一一位
- switch(Mode)
- {
- case 1:
- {
- write_com(0x80+15);//位置
- Feng=1;
- break;
- }
- case 2:
- {
- write_com(0x80+0x40+5);//位置
- Feng=1;
- break;
- }
- case 3:
- {
- write_com(0x80+0x40+14);//位置
- Feng=1;
- break;
- }
- }
- }
- //+键
- else if(Im[2]==0x40)
- {
- if(Mode!=0)
- {
- Feng=0;
- switch(Mode)
- {
- case 1:
- {
- if(ds<999)
- {
- ds++;
- write_com(0x80+13);
- write_data('0'+ds/100);
- write_data('0'+ds/10%10);
- write_data('0'+ds%10);
- write_com(0x80+15);//位置
- }
- Feng=1;
- break;
- }
- case 2:
- {
- if(sx<99-1)
- {
- sx++;
- write_com(0x80+0x40+4);
- write_data('0'+sx/10%10);
- write_data('0'+sx%10);
- write_com(0x80+0x40+5);//位置
- }
- Feng=1;
- break;
- }
- case 3:
- {
- if(xx
- {
- xx++;
- write_com(0x80+0x40+13);
- write_data('0'+xx/10%10);
- write_data('0'+xx%10);
- write_com(0x80+0x40+14);//位置
- }
- Feng=1;
- break;
- }
- }
- }
- }
- //-键
- else if(Im[2]==0x19)
- {
- if(Mode!=0)
- {
- Feng=0;
- switch(Mode)
- {
- case 1:
- {
- if(ds>0)
- {
- ds--;
- write_com(0x80+13);
- write_data('0'+ds/100);
- write_data('0'+ds/10%10);
- write_data('0'+ds%10);
- write_com(0x80+15);//位置
- }
- Feng=1;
- break;
- }
- case 2:
- {
- if(sx>xx+1)
- {
- sx--;
- write_com(0x80+0x40+4);
- write_data('0'+sx/10%10);
- write_data('0'+sx%10);
- write_com(0x80+0x40+5);//位置
- }
- Feng=1;
- break;
- }
- case 3:
- {
- if(xx>0)
- {
- xx--;
- write_com(0x80+0x40+13);
- write_data('0'+xx/10%10);
- write_data('0'+xx%10);
- write_com(0x80+0x40+14);//位置
- }
- Feng=1;
- break;
- }
- }
- }
- }
- //确定键
- else if(Im[2]==0x15)
- {
- Feng=0;
- Mode=0;
- Init1602();
- if(ds>0)
- {
- flag=1;
- jdq=1;
- TR1=1;
- }
- Feng=1;
- }
- IrOK=0;
- }
- }
- */
- //报警部分程序
- void Alam()
- {
- if(flag_BJ==1&&flag_off==1)
- {
- Feng=0;
- delay(1000);
- Feng=1;
- flag_off=0;
- // flag_BJ=0;
- }
- }
- //主程序
- void main()
- {
- Init1602();
- EA=1;//打开中断总开关
- IT1=1;//下降沿有效
- EX1=1;//外部中断1开
- ET1=1;//打开允许开关
- TMOD=0x01;//设置工作方式
- TL1=0x3c;
- TH1=0xb0;//赋初值
- TH0=0;//T0赋初值
- TL0=0;
- TR0=0;//t0开始计时
- check_wendu();
- delay(1000);
- bjd=99;
- bjx=0;
- while(1)
- {
- check_wendu();
- if(Mode==0)
- {
- Display_1602(c,ds,sx,xx);
- if((xia==1)&&(shang==1)) //低于下限
- {
- que=1;
- shui=0;
- jdq=1;
- }
- else
- {
- que=0;
- }
- if((shang==0)&&(xia==0)) //高于上限
- {
- shui=1;
- if(flag_BJ==0)
- flag_BJ=1;
- }
- if((shang==0)&&(xia==1)) //错误
- {
- shui=1;
- jdq=1;
- Feng=0;
- que=1;
- }
- if(flag==0)
- {
- if((w
bjx)) - {
- if(w>=sx)
- {
- jdq=1;
- if(flag_BJ==0)
- flag_BJ=1;
- }
- else if((w
- {
- jdq=0;
- if(flag_BJ==0)
- flag_BJ=1;
- }
- else
- {
- flag_BJ=0;
- flag_o