目录
一、主要功能
基于AT89C52单片机,采用DS18B20温度传感器检测温度,通过LCD1602显示屏显示,并且按键
可以加减温度的上限;
点击清洗按键后,倒计时1分钟,电机正转20s,反转20s,直到倒计时结束停止,蜂鸣器报警。
点击脱水按键后,倒计时1分钟,电机正转20s,反转20s,直到倒计时结束停止,蜂鸣器报警。
然后加三个按键,分别代表进水,出水,排水,三个LED状态灯表示。
采用滑动变阻器连接ADC0832数模转换器检测水位。
二、硬件资源
基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。
编辑
三、程序编程
#include "reg51.h"#include<intrins.h>#include<stdio.h>#include "lcd1602.h"#include "Delay.h"#define uchar unsigned char#define uint unsigned intsbit k1=P1^2;
sbit k2=P1^3;
sbit k3=P1^4;
sbit k4=P1^5;
sbit k5=P1^6;
sbit k6=P1^7;
sbit k7=P3^0;
sbit beep=P2^7;//蜂鸣器sbit led1=P3^7;//ledsbit led2=P3^6;
sbit led3=P3^5;
sbit out1=P3^3;//电机sbit out2=P3^4;
sbit out3=P1^0;
sbit out4=P1^1;
sbit CS= P2^4; //ADC0832sbit CLK= P2^5;
sbit DIO= P2^6;
sbit DS=P3^2; //DS18B20温度传感器uchar time=0,mode=0,sec=0;//系统变量uchar fen=0,miao=0,set=1;//时间uchar miao1=0;//倒计时uchar disp1\[\]="00:00";
uchar disp2\[\]="00s";
uchar wd\[\]="00";
uchar wdyz\[\]="00";
uchar shuiwei\[\]="000";static uint u,U,R;//水位变量static int wdmax=50;unsigned char count;typedef unsigned char u8;typedef unsigned int u16;static uint temp;static float ftemp = 0.0f;//温度转变static int wdnumber;
uint temp;static int mode1=0;void tmpchange();uint tmp();void beep_warning();void dsreset(void) //发出命令{
uint i;
DS=0;
i=103; //将总线拉低480us~960us
while(i>0)i--;
DS=1; //然后拉高总线,若DS18B20做出反应会将在15us~60us后将总线拉低
i=4; //15us~60us等待
while(i>0)i--; //while(DS);}bit tmpreadbit(void) //读取数据{
uint i;
bit dat;
DS=0;i++; //i++ for delay
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--; return (dat);
}uchar tmpread(void) //读取数据{
uchar i,j,dat;
dat=0; for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
} return(dat);
}void tmpwritebyte(uchar dat) //传输数据给DS18B20{
uint i;
uchar j;
bit testb; for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1; if(testb) //write 1
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
} else
{
DS=0; //write 0
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}void tmpchange(void) //DS18B20开始工作{ dsreset(); Delay(1); tmpwritebyte(0xcc);
tmpwritebyte(0x44);
}
uint tmp() //获得温度{ float tt;
uchar a,b; dsreset(); Delay(1); tmpwritebyte(0xcc); tmpwritebyte(0xbe);
a=tmpread();//低八位
b=tmpread();//高八位
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a;
tt=temp*0.0625; //算出来的是测到的温度,数值可到小数点后两位
temp=tt*10+0.5; //为了显示温度后的小数点后一位并作出四舍五入,因为取值运算不能取小数点后的数
return temp;
}uchar get\_AD\_Res() //ADC0832启动读取函数{
uchar i, data1=0, data2=0;
CS=0;
CLK=0;DIO=1;\_nop\_();
CLK=1;\_nop\_();
CLK=0;DIO=1;\_nop\_();
CLK=1;\_nop\_();
CLK=0;DIO=0;\_nop\_();
CLK=1;\_nop\_();
CLK=0;DIO=1;\_nop\_();
for(i=0; i<8; i++)
{
CLK=1;\_nop\_();
CLK=0;\_nop\_();
data1=(data1<<1)|(uchar)DIO;
}
for(i=0; i<8; i++)
{
data2=data2|(uchar)DIO<<i;
CLK=1;\_nop\_();
CLK=0;\_nop\_();
}
CS=1;
return(data1 == data2)?data1:0;
}void swpd() //水位判断{ if(R>100)
{
out3 = 1;
out4 = 0;
} else
{
out3 = 1;
out4 = 1;
}
}void main()//主函数{ init_1602();//初始化LCD
write\_string(2,0,"ms:"); write\_string(2,11,"sw");
TMOD|=0X01;
TH0=0X3C;
TL0=0XB0;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
beep = 1; while(1)
{
u=get\_AD\_Res();
U=(250*u)/128; //水位
R=200*U/250; //水位转变
swpd();//水位判断
if(mode==0) // 停止模式
{ if(!k1)
{
wdmax++; while(!k1);
}
if(!k2)
{
wdmax--; while(!k2);
}
if(!k3)
{ init_1602();
mode1=0; write_string(2,1,"qx"); if(mode==0)
{
mode=1;
fen=set;
miao=0;
miao1=20;
} while(!k3);
}
if(!k4)
{ init_1602();
mode1=0; write_string(2,1,"ts"); if(mode==0)
{
mode=1;
fen=set;
miao=0;
miao1=20;
} while(!k4);
}
if(!k5)
{
mode1=1; while(!k5);
}
if(!k6)
{
mode1=2; while(!k6);
} if(!k7)
{
mode1=3; while(!k7);
}
} switch(mode)//模式控制
{ case 0:
out1=1;out2=1;
led1=1;led2=1;led3=1; break; case 1:
out1=1;out2=0; break; case 2:
out1=1;out2=1; break; case 3:
out1=0;out2=1; break; case 4:
out1=1;out2=1;
}
switch(mode1)
{ case 0:
out3 = 0;
out4 = 0;
led1 = 1;
led2 = 1;
led3 = 1; break; case 1:
out3 = 1;
out4 = 0;
led1 = 0;
led2 = 1;
led3 = 1; break; case 2:
out3 = 1;
out4 = 0;
led1 = 1;
led2 = 0;
led3 = 1; break; case 3:
out3 = 1;
out4 = 0;
led1 = 1;
led2 = 1;
led3 = 0; break;
}
}
}//定时器中断void Timer0() interrupt 1{ if(time<10)//0.5s
time++; else
{ tmpchange(); //让18b20开始转换温度
temp = tmp(); //读取温度
ftemp = temp/10.0f; //转换温度
wdnumber = ftemp;
time=0; //显示
if(mode==0)
{ write\_string(1,0,"wd:"); write\_string(1,7,"yz:");
wd\[0\]=wdnumber/10+0x30;
wd\[1\]=wdnumber%10+0x30;
wdyz\[0\]=wdmax/10+0x30;
wdyz\[1\]=wdmax%10+0x30;
if(wdnumber > wdmax)
{
beep = 0;
} else
{
beep = 1;
}
write\_string(1,3,wd); write\_string(1,10,wdyz);
disp1\[0\]=set/10+0x30;
disp1\[1\]=set%10+0x30;
disp1\[3\]='0';
disp1\[4\]='0'; write_string(2,5,disp1);
shuiwei\[0\]=R/100+0x30;
shuiwei\[1\]=(R%100)/10+0x30;
shuiwei\[2\]=R%10+0x30; write_string(2,13,shuiwei);
} else//运行倒计时
{ write_string(1,0,"run:");
disp1\[0\]=fen/10+0x30;
disp1\[1\]=fen%10+0x30;
disp1\[3\]=miao/10+0x30;
disp1\[4\]=miao%10+0x30; write_string(2,5,disp1);
disp2\[0\]=miao1/10+0x30;
disp2\[1\]=miao1%10+0x30; write_string(1,6,disp2);
shuiwei\[0\]=R/100+0x30;
shuiwei\[1\]=(R%100)/10+0x30;
shuiwei\[2\]=R%10+0x30; write_string(2,13,shuiwei);
}
} if(mode>0)
{ if(sec<19)//1s
sec++; else
{
sec=0; if(miao>0)//秒计时
miao--; else
{ if(fen>0)
{
miao=59;//分计时
fen--;
} else
{
beep=0; //结束
mode=0;
beep=1;
}
} if(mode==1)//正转
{ if(miao1>0)
miao1--; else
{
miao1=20;
mode=3;
}
} else if(mode==2)//暂停
{ if(miao1>0)
miao1--; else
{
miao1=25;
mode=3;
}
} else if(mode==3)//反转
{ if(miao1>0)
miao1--; else
{
miao1=20;
mode=1;
}
} else if(mode==4)//暂停
{ if(miao1>0)
miao1--; else
{
miao1=20;
mode=1;
}
}
else
{
miao1=0; init_1602();
beep = 0; Delay(500);
beep = 1;
}
}
}
TH0=0X3C;
TL0=0XB0;
}
四、实现现象
具体动态效果看B站演示视频:
基于51单片机的自动清洗系统(自动洗衣机)
全部资料(源程序、仿真文件、安装包、演示视频):
链接:https://pan.baidu.com/s/1ddJ3RP7JqBRiUF7uI6a2tw?pwd=ahdy
提取码:ahdy