基于51单片机的多功能洗碗机(Protues仿真)

news/2024/11/17 5:26:43/

本项目是以AT89C51最小系统为核心,外接DS18B20温度传感器、OVEN加热棒、LCD1604显示屏、ADC0832模数转换器模拟浊度传感器、L298和MOTOR当电机模块。电机模块用于模拟洗碗机的进水、洗碗、出水状态,蜂鸣器模块用于提醒用户其洗碗机结束工作。

文章目录

      • 1、仿真图
      • 2、软件设计流程图
      • 3、keil4编写代码
        • 3.1 LCD1604模块
        • 3.2 DS18B20模块
        • 3.3 ADC0832模块
        • 3.4 STATUS模块
        • 3.5 KEY模块
        • 3.6 main模块

1、仿真图

在这里插入图片描述

2、软件设计流程图

先把软件流程图画出来,有个思路也方便后面编写代码

在这里插入图片描述

3、keil4编写代码

我这里是写了一个主文件调用五个子文件,分别是:

main.c:主函数

ADC.c:ADC032模数转换器,获取电压大小,在主函数在将其转换为百分比

DS18B20.c: 获取温度传感器数据

KEY.c:按键模块

LCD1602.c: 对LCD1604显示屏进行初始化、写命令、写数据

STATUS.C:按钮功能、进水、出水、洗涤方式、定时器初始化函数以及一些公共定义

3.1 LCD1604模块

​ 我是先写lcd显示屏,它是被调用,不需要调别的数据。LCD1604与LCD1602原理差不多,只是容量比LCD1602多一倍,我需要显示的数据比较多,所以本项目这里采用的LCD1604显示模块,主要显示当前选择模式、温度数据、浊度数据、定时时间、剩余时间、进度显示。RS引脚接单片机P2.0引脚,RW引脚接单片机P2.1引脚,E引脚接单片机P2.2,D0-D7引脚接单片机P0-P7引脚。这里我写了两种显示方式,一种是可根据我们的需要写进去,一种是获取数据再显示出来。
初始化状态
在这里插入图片描述
运行状态
在这里插入图片描述

#include "LCD1602.h"#include <intrins.h>
#define uchar unsigned char
#define  DataPort  P0sbit RS=P2^0;
sbit RW=P2^1;
sbit E=P2^2;void delay(unsigned int n)//延时函数
{unsigned int i=0,j=0;for(i=0;i<n;i++){for(j=0;j<120;j++);}
}
// lcd 写入命令函数
void lcd_writer_com(uchar com)
{RS=0;  //  RS:数据/命令选择端 RW=0;  //  R/W :读/写选择端  E=0;   //使能端:下降沿有效 P0=com;delay(5);E=1;E=0; }
//写数据函数,
void lcd_write_data(uchar Data)
{RS=1;  //  RS:数据/命令选择端RW=0;  //  R/W :读/写选择端 E=0;   //  使能端:下降沿有效 P0=Data;delay(5);E=1;E=0;
}
//xy位置
void GotoXY(unsigned char x, unsigned char y)
{if(x==0)lcd_writer_com(0x80+y);   //0x80是第一行的起始地址if(x==1)lcd_writer_com(0xc0+y); 	//0xc0是第二行的起始地址if(x==2)lcd_writer_com(0x90+y);	//0x90是第三行的起始地址if(x==3)lcd_writer_com(0xd0+y);	//0xd0是第四行的起始地址
}
void Print(unsigned char *str)	 //在LCD上显示数据,内部调用
{while(*str!='\0'){lcd_write_data(*str);str++;}
}
void LCD_Print(unsigned char x, unsigned char y, unsigned char *str) //指定的位置打印指定数据
{GotoXY(x,y);Print(str);
}
void LCD_Print_num(unsigned char x, unsigned char y,long int temp_num) //指定的位置显示数值
{uchar temp_tab[7]=0;long int num=0;uchar i=0;num=temp_num;GotoXY(x,y);if(num<0){num=0-num;lcd_write_data('-');}temp_tab[0]=num/1000000%10+0x30;temp_tab[1]=num/100000%10+0x30;temp_tab[2]=num/10000%10+0x30;temp_tab[3]=num/1000%10+0x30;temp_tab[4]=num/100%10+0x30;  temp_tab[5]=num/10%10+0x30;temp_tab[6]=num%10+0x30;for(i=0;i<7;i++){if(temp_tab[i]!=0x30)break;}if(i==7){lcd_write_data(0x30);}else{while(i<7){lcd_write_data(temp_tab[i]);i++;}}
}
//lcd初始化
void lcd_init(void)
{
// RS =0 RW =0 写命令
// RS=1  RW=0  写数据
// RS =0  RW=1  读状态lcd_writer_com(0x38);        //0011 1000lcd_writer_com(0x38);lcd_writer_com(0x08);	//0000 1000lcd_writer_com(0x0c);	//0000 0001	   0x0C:设置开显示,不显示光标lcd_writer_com(0x06);	//0000 0110	   0x06:写一个字符后地址指针加1lcd_writer_com(0x01);	 //0000 1111   显示清0,数据指针清0LCD_Print(0,0,"MODE:");	  	//显示屏显示当前模式LCD_Print(1,0,"TIME:");		//显示屏显示剩余时间LCD_Print(2,0,"DSHI:");		//显示屏显示定时LCD_Print(2,8,"ZD:");		//显示屏显示浊度	LCD_Print(1,8,"WD:");		//显示屏显示温度	LCD_Print(3,0,"ZhunBei");	//显示屏显示准备LCD_Print(2,14,"%" );
}

3.2 DS18B20模块

​ 本项目这里采用的是DS18B20温度传感器模块,其VCC引脚接5V,GND引脚接地,DQ引脚接51单片机P3.3引脚,通过温度检测当前的水温来判断是否启动加热棒模块。

//测量温度
#include "DS18B20.h"
#include "lcd1602.h"
int readtemp =0;  // 定义读出温度储存寄存器
unsigned char str[] ={"0123456789"}; //温度显示调用数组
sbit RS=P2^0;
sbit RW=P2^1;
sbit E=P2^2;
sbit DQ =P3^3;    //DS18B20 温度传感器信号端口
void delay_18B20(unsigned int i)//延时函数
{for(;i>0;i--);
}
void Init_DS18B20(void)	   // DS18B20 温度传感器初始化子程序
{unsigned char x=0;DQ=1;	  //DQ拉高delay_18B20(8);DQ=0;	     //DQ拉低delay_18B20(80); //延时大于480usDQ=1;	     //拉高总线delay_18B20(14);x =DQ;	     //x =0 初始化成功,反之不成功delay_18B20(20);}
unsigned char ReadOneChar(void)  //DS18B20温度传感器  读时序 子程序
{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_18B20(4);}return(dat);
}
void WriteOneChar(unsigned char dat)   //DS18B20温度传感器  写时序 子程序
{unsigned char i =0;for(i=8;i>0;i--){DQ =0;DQ =dat & 0x01;if(DQ){delay_18B20(1);DQ =1;}else{delay_18B20(5);DQ =1;}dat>>=1;}
}
unsigned char ReadTemperature(void)	  //DS18B20 温度传感器读出子程序
{unsigned  char a =0,b=0;unsigned  int temp =0;Init_DS18B20();    // 初始化温度WriteOneChar(0xcc);  //跳过读序列号操作WriteOneChar(0x44); //启动温度转换delay_18B20(100);Init_DS18B20();WriteOneChar(0xCC);  //跳过读序列号操作WriteOneChar(0xBE);  //读取温度寄存器delay_18B20(100);a =ReadOneChar();   //读取温度低位b =ReadOneChar();	  //读取温度高位temp=((b*256+a)>>4); // 当前采集温度除16得到实际温度return(temp);		 //显示屏显示温度
}void  display()  //显示函数
{unsigned int temp1=0,temp2=0,i=0;temp1=(readtemp%100)/10;temp2=readtemp%10;lcd_writer_com(0xc0+12);  //0x80+0x40:LCD第2行的起始地址lcd_write_data(str[temp1]);	lcd_write_data(str[temp2]);lcd_write_data(0xDF);   lcd_write_data('C');
}

3.3 ADC0832模块

​ 本项目这里采用的是ADC0832模数转换模块,通过电压大小来模拟浑浊程度,从而在选择智能洗的时候根据浑浊程度来进行相对应的洗涤时间。其VCC引脚接5V,GND引脚接地,CLK引脚接51单片机P1.1引脚,DI引脚接51单片机P1.2引脚,DO引脚接51单片机P1.3引脚,CS引脚接51单片机P1.4引脚,CH0引脚接滑动变阻器,

//浑浊度
#include "ADC.h"sbit ADC_CS =P1^4;     //片选端
sbit ADC_CLK= P1^1;
sbit ADC_DATI= P1^2;
sbit ADC_DATO =P1^3;
//adc转换
uchar adc0832(uchar temp_CH)
{uchar temp_data =0x00;	  //ad值uchar i,temp_ad_val1,temp_ad_val2;temp_ad_val2 =0x00;		 temp_ad_val1 =0x00;ADC_CLK =0;//初始化ADC_DATI =1;_nop_();ADC_CS =0;_nop_();ADC_CLK =1;_nop_();    if (temp_CH ==0x00){ADC_CLK =0;ADC_DATI =1;   //通道0的第一位_nop_();ADC_CLK =1;_nop_();ADC_CLK=0;ADC_DATI =0;    //通道0的第二位_nop_();ADC_CLK =1;_nop_();}else{ADC_CLK =0;ADC_DATI =1;   //通道0的第一位_nop_();ADC_CLK =1;_nop_();ADC_CLK=0;ADC_DATI =1;    //通道0的第二位_nop_();ADC_CLK =1;_nop_();}ADC_CLK =0;ADC_DATI =1;for(i =0;i<8;i++)	  //读取前八位{_nop_();temp_ad_val2 <<=1;ADC_CLK =1;_nop_();ADC_CLK=0;if(ADC_DATO)temp_ad_val2 |=0x01;elsetemp_ad_val2 |=0x00;}for(i =0;i<8;i++)		   //后读取8位的值{temp_ad_val1 >>= 1;if (ADC_DATO)temp_ad_val1 |= 0x80;elsetemp_ad_val1 |= 0x00;_nop_();ADC_CLK = 1;_nop_();ADC_CLK = 0;}if (temp_ad_val2 == temp_ad_val1)      //比较前8位与后8位的值,如果不相同舍去。若一直出现显示为零,请将该行去掉temp_data = temp_ad_val1;_nop_();ADC_CS = 1;        //释放ADC0832ADC_DATO = 1;ADC_CLK = 1;return temp_data;
}

3.4 STATUS模块

定时器初始化

void timer0_init(void)
{TMOD =0X10;			 //定时器TH1=(65536 -50000)/256;TL1 =(65536-50000)%256;TR1=1;EA=1;ET1=1;TR0=0;    //启动定时器为1
}

智能洗模块

uchar zhineng =0;     // 智能洗的判断标志位 0 为不启动,1为启动
uchar zhuodu_ok =0;    //智能洗时,根据浊度,确定洗涤时间
uchar zhineng_num =5;  //智能洗时,循环检测5次,确保浊度稳定,之后根据浊度决定洗涤时间
void zhinengxi()
{	LCD_Print(0,5,"zhinengxi");jinshui();while(zhineng)   //智能洗时{while(zhineng_num-- && !zhuodu_ok){if(p_zhoudu <25)  //浊度小于25%,定时10s{t_ding =10;	}else if (p_zhoudu<60)  //浊度小于60%,定时20s{t_ding =20;}else			   //浊度大于等于60,定时30s{t_ding =30;}if (zhineng_num ==0){TR0 =1;	    //开启定时器,开始倒计时}	}zhuodu_ok =1;motor();                    //电机转动adc0832(0);                      //ADC处理函数LCD_Print_num(1,5,t_ding);   //显示定时时间if (t_ding ==0){chushui();}}
}

电机模块

本项目这里采用的L298和MOTOR模块,其引脚IN1接单片机P1.5引脚,引脚IN2接单片机P1.6引脚,MOTOR步电机设置是5V。用于模拟进水状态、出水状态、洗涤状态。当处于进水状态、工作状态时,电机正转。出水状态时,电机反转。

void motor()	   //电机函数
{LCD_Print(3,0,"xiwanzhong");if(t_ding !=0){m1=1;m2=0;}if(t_ding ==0){m1=0;m2=0;}
}

进水模块

出水模块电机与之相反即可。

void  jinshui()	//进水时m1 =1,m2=0;出水时 m1=0,m2=1 ,进水出水电机运行相反
{LCD_Print(3,0,"jinshui");if (zhineng){m1 =1;m2=0;delay(10000); //进水10s}else if (jieneng){m1 =1;m2=0;delay(8000);	//进水8s}else if (chaokuai){m1 =1;m2=0;delay(5000);	   //进水5s}else {m1 =1;m2=0;delay(3000);}m1=0;m2=0;c_num=0;delay(2000);        //进水结束,电机停止2s
}

3.5 KEY模块

这里我用switch语句来进行分别。按下按钮进行相对应的功能

void key_choose(void)
{	int button;button =key_scan();switch(button){case 1:zhinengxi();zhineng =1;break;case 2:jienengxi();jieneng=1;break;case 3:chaokuaixi();chaokuai =1;break;case 4:dingshixi();dingshi =1;break;case 5:jia();break;case 6:jian();break;case 7:lcd_init();c_num=0;break;}
}

3.6 main模块

​ 在主函数这里,我给按钮模块加了一个if判断语句,当按下一个按键时,只能等那个按键实现完功能,才能继续按其他按钮。如果要强制中断其运行,可点击复位按钮,本人能力有限。

#include "ADC.h"
#include "LCD1602.h"
#include "DS18B20.h"
#include "STATUS.h"
#include "KEY.h"
int num =0;
void zhongduan() interrupt 3		//中断程序,每经过一次中断为50ms,20次就是一秒
{TH1=(65536 -50000)/256;TL1 =(65536-50000)%256;num++;if(num>=20){t_ding--;num=0;if(t_ding<=0){TR0 =0;}}
}
void main()
{lcd_init();      //屏幕初始化timer0_init();   //定时器初始化m1 =0;		//电机引脚m1,m2电平相同且为低,保证此时电机不转,因为两个引脚电压相同		m2 =0;OVEN=1;		//加热棒是低电平触发,因此给高电平,此时不加热buzzer =1;		//蜂鸣器是高电平触发,因此给低电平,此时不响while(1){v_zhoudu =adc0832(0); // 测浊度p_zhoudu =v_zhoudu *100/255;  //计算浊度百分比 因为是5v电压,放大20倍,方便转换LCD_Print_num(2,12,p_zhoudu);   //显示浊度readtemp=ReadTemperature();   //获取温度display();				//显示温度if(c_num==0)	    	//!c_num 用于来记录按键按下的次数。未按时为0,这个while循环成立,反之不成立{key_choose();		//模式按键函数 ,用以决定是何种洗涤模式}if(readtemp<30)     //温度低于30时,启动加热{OVEN=0;	}else{OVEN=1;}while(zhineng)   //智能洗时{zhinengxi();}while(jieneng)	 //节能洗时{jienengxi();}while(chaokuai)	    //超快洗{chaokuaixi();}while(dingshi)	   //定时洗{dingshixi();}}}

写的不够好,但是我会继续努力的!!!
在这里插入图片描述


http://www.ppmy.cn/news/164281.html

相关文章

Arduino洗碗机

一、Arduino Arduino是一个开放源码电子原型平台&#xff0c;拥有灵活、易用的硬件和软件。Arduino专为设计师&#xff0c;工艺美术人员&#xff0c;业余爱好者&#xff0c;以及对开发互动装置或互动式开发环境感兴趣的人而设的。 Arduino可以接收来自各种传感器的输入信号从…

洗碗机浑度检测

洗碗机浑浊度检测传感器 一.浑浊度含义 浑浊度是水体物理性状指标之一。它表征水中悬浮物质等阻碍光线透过的程度。一般来说,水中的不溶解物质越多,浑浊度也越高。浑浊度是由于水中存在颗粒物质如黏土、污泥、胶体颗粒、浮游生物及其他微生物而形成,用以表示水的清澈或浑浊…

基于单片机的洗碗机控制器

设计简介&#xff1a; 本设计是基于单片机的洗碗机控制器&#xff0c;主要实现以下功能&#xff1a; LCD1602显示温度、温度最大值以及状态按键设置温度最大值洗碗过程&#xff1a;进水-->加热-->排水-->冲洗-->烘干-->结束在洗碗过程中可以通过按键暂停、开始…

基于plc的自动洗碗机的设计(西门子)

目 录 摘 要 I Abstract II 1绪论 1 1.1全自动洗碗机的发展 1 1.2全自动洗碗机概述 2 1.2.1 全自动洗碗机的分类 2 1.2.2 全自动洗碗机的基本结构 3 1.2.3 全自动洗碗机的工作原理 4 1.3研究主要内容 4 2 全自动洗碗机机械设计 6 2.1 整体方案设计 6 2.2 各重要部件设计 6 2.2.…

智能语音信息处理团队14篇论文被语音技术顶会Interspeech 2023接收

近日&#xff0c;Interspeech 2023会议发出了审稿结果通知&#xff0c;语音及语言信息处理国家工程研究中心智能语音信息处理团队共14篇论文被会议接收&#xff0c;论文方向涵盖语音识别、语音合成、话者识别、语音增强、情感识别、声音事件检测等&#xff0c;各接收论文简介见…

表格软件有哪些?热门表格软件推荐

作为报表开发人员&#xff0c;我们经常需要使用各种表格软件来处理数据并生成清晰、易读的报表。在市面上&#xff0c;有许多不同类型的表格软件可供选择。下面我将列举7款热门的表格软件&#xff0c;并详细介绍其中一款优秀的软件—VeryReport。 编辑搜图 请点击输入图片描述…

主题包网址(Theme)

idea主题网址&#xff1a; http://www.riaway.com/ http://color-themes.com/?viewindex http://color-themes.com/?viewindex

壁纸 - 精选海量高清图片与桌面背景

特色功能介绍&#xff1a; 1、海量的高清精美壁纸 2、每日更新&#xff0c;让您紧跟潮流壁纸的步伐 3、提供数十个类别和数百个主题专辑以供筛选 4、左右划屏快速切换预览&#xff0c;享受全屏无死角视觉盛宴 5、独家提供壁纸缩放浏览功能&#xff0c;让您全面掌控壁纸的每一处…