目录
一、主要功能
二、硬件资源
三、程序编程
四、实现现象
一、主要功能
基于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 int
sbit 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;//led
sbit 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; //ADC0832
sbit 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~960uswhile(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 delayDS=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 0i=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 variabletemp=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();//初始化LCDwrite_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.5stime++;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)//1ssec++;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