本项目是以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();}}}

写的不够好,但是我会继续努力的!!!

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

  1. 基于51单片机的多功能智能型电动车防盗报警器proteus仿真原理图PCB

    功能介绍: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶实时显示当前锁的状态 2.可通过按键开启/关闭继电器 3.当上锁后,检测到有人同时有震动时,5s后进入监测, 监测0~5s, ...

  2. 基于51单片机的产品数量自动计量系统protues仿真

    硬件设计 (末尾附文件) 代码设计 ///************************************************************************* ///** ...

  3. STM32单片机智能全自动多功能洗碗机加热放水烘干紫外消毒

    实践制作DIY- GC0090-全自动多功能洗碗机 一.功能说明: 基于STM32单片机设计-全自动多功能洗碗机 功能介绍: 硬件组成: STM32F103C系列最小系统板 +LCD1602显示器+水 ...

  4. 51单片机智能全自动多功能洗碗机加热放水烘干紫外消毒

    实践制作DIY- GC0089-智能全自动多功能洗碗机一.功能说明: 基于51单片机设计-智能全自动多功能洗碗机 功能介绍: 硬件组成: STC89C52最小系统板 +LCD1602显示器+水位传感器 ...

  5. 【043】基于51单片机的篮球比赛积分计时系统Proteus仿真

    一.压缩包资料内容 (1).基于51单片机的篮球比赛积分计时系统proteus仿真设计一份: (2).基于51单片机的篮球比赛积分计时系统proteus仿真设计keli源代码一份: (3).基于51单 ...

  6. 基于51单片机轮胎胎压监测系统-压力传感器(仿真+程序+报告)

    本设计: 基于51单片机轮胎胎压监测系统-压力传感器(仿真+程序+报告) Proteus仿真版本:proteus7.8 程序编译器:keil 4 编程语言:C语言 编号C0018 ----本设计分享下 ...

  7. 【038】基于51单片机的土壤湿度自动浇花系统Proteus仿真设计

    一.压缩包资料内容 (1).基于51单片机的土壤湿度自动浇花系统proteus仿真设计一份: (2).基于51单片机的土壤湿度自动浇花系统proteus仿真设计keli源代码一份: (3).基于51单 ...

  8. 基于51单片机HX711的电子秤称重计价proteus仿真程序设计

    设计要求 1.利用压力传感器检测重量信号,经放大和A/D转换,送单片机进行处理,并在液晶屏上显示出被称重量值: 2.最小显示单位为1克: 3.量程超过报警值蜂鸣器报警 资料下载地址:基于51单片机HX ...

  9. 基于51单片机的多功能智能语音循迹避障小车

    目录 一.功能介绍及硬件准备 二.电机控制及调速 三.小车循迹方案 四.跟随功能实现 五.测速功能实现 六.OLED显示车速 七.摇头避障功能实现 八.SU-03T语音模块介绍 九.语音切换小车模式+ ...

最新文章

  1. flashcom中远程共享对象SharedObject的用法
  2. 【必点】程序员自助SDCC热门主题+图书豪华套餐
  3. [php错误]PHP中Notice: unserialize(): Error at offset of bytes in on line 的解决方法
  4. ppt矩形里面的图片怎么放大缩小_ppt 怎么才能做到图片的放大缩小???? 下面有图...
  5. 【Boost】boost库中的小工具enable_shared_from_this
  6. 有关计算机程序的论文,有关计算机程序的论文范文.doc
  7. eclipse配置glassfish、将一个WEB项目部署到glassfigh
  8. lru算法c语言实现单链表,操作系统之LRU算法 C语言链表实现
  9. 模拟处理机作业调度---短作业优先调度算法
  10. 网络设置里计算机为什么有两个字,一计算机网络操作题.doc
  11. ERP系统应用的流程与步骤
  12. 小米手机深陷“返修门” 售后成软肋
  13. ios12最后一个正式版_iOS12正式版
  14. 【Redis】大数据量(百亿级)Key存储需求及解决方案
  15. LTE提高了频谱利用率吗?
  16. 图像处理——图像平滑
  17. 爱说分手 吹了9个男朋友
  18. Detection in Crowded Scenes: One Proposal, Multiple Predictions(拥挤场景下的检测:一个提议,多个预测)
  19. python循环打印A-Z
  20. python3之calendar日历模块

热门文章

  1. 计算机专业集齐七龙珠,集齐七颗龙珠 为你召唤一台飞行堡垒8
  2. OMAP4460的DDR2升级说明
  3. CISC RISC架构
  4. Django MTV
  5. 微博互粉php,PHP+redis实现微博的推模型案例分析
  6. andriod 01
  7. c#开发的漂亮高仿QQ打包安装程序界面
  8. 探索工坊设计与实施实录
  9. 学习与脑力锻炼的关系
  10. 毕业设计倒计时Day 173:开题答辩记录