基于51单片机的自动清洗系统(自动洗衣机)

目录

一、主要功能

二、硬件资源

三、程序编程

四、实现现象


一、主要功能

基于AT89C52单片机,采用DS18B20温度传感器检测温度,通过LCD1602显示屏显示,并且按键

可以加减温度的上限;

点击清洗按键后,倒计时1分钟,电机正转20s,反转20s,直到倒计时结束停止,蜂鸣器报警。

点击脱水按键后,倒计时1分钟,电机正转20s,反转20s,直到倒计时结束停止,蜂鸣器报警。

然后加三个按键,分别代表进水,出水,排水,三个LED状态灯表示。

采用滑动变阻器连接ADC0832数模转换器检测水位。

二、硬件资源

基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。

三、程序编程

cpp 复制代码
#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~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

相关推荐
智商偏低34 分钟前
单片机之helloworld
单片机·嵌入式硬件
水龙吟啸1 小时前
计算机组成原理与体系结构-实验四 微程序控制器 (Proteus 8.15)
硬件架构·proteus·硬件工程
青牛科技-Allen2 小时前
GC3910S:一款高性能双通道直流电机驱动芯片
stm32·单片机·嵌入式硬件·机器人·医疗器械·水泵、
隐藏起来3 小时前
在 proteus8或者proteus 9 中查看 micropython 的 print 输出
proteus
白鱼不小白4 小时前
stm32 USART串口协议与外设(程序)——江协教程踩坑经验分享
stm32·单片机·嵌入式硬件
S,D4 小时前
MCU引脚的漏电流、灌电流、拉电流区别是什么
驱动开发·stm32·单片机·嵌入式硬件·mcu·物联网·硬件工程
芯岭技术7 小时前
PY32F002A单片机 低成本控制器解决方案,提供多种封装
单片机·嵌入式硬件
youmdt8 小时前
Arduino IDE ESP8266连接0.96寸SSD1306 IIC单色屏显示北京时间
单片机·嵌入式硬件
嘿·嘘8 小时前
第七章 STM32内部FLASH读写
stm32·单片机·嵌入式硬件
几个几个n10 小时前
STM32-第二节-GPIO输入(按键,传感器)
单片机·嵌入式硬件