单片机全自动洗衣机程序+仿真+原理图设计调试与分析
2019-12-05 来源:51hei
一、设计任务与要求
利用51单片机模拟全自动智能洗衣机。
按键功能要求
通过“K1”键步进改变“标准]经济、单独、排水”四种方式,执行相应的程序。对应指示灯亮。
通过“K2”键步进改变“强洗、弱洗”两种方式,执行相应的程序,对应指示灯亮。
通过“K3”键控制洗衣机运行、暂停和解除报警功能。
方式功能选择要求
一般洗衣机的步骤为:洗涤,漂洗,脱水,当处于某种状态时,对应的指示灯以0.7S周期闪烁,当洗衣机在洗涤过程中,洗涤指示灯闪烁。可以通过方式选择设定具体的运行过程。
标准方式:进水—> 洗涤 —> 排水 —> 进水 —> 漂洗 —> 排水 —>进水 —> 漂洗—> 排水 —> 脱水。
经济方式:进水 —> 洗涤 —> 排水 —> 进水 —> 漂洗 —> 排水 —> 脱水。
单独方式:进水 —> 洗涤。
排水方式:排水 —> 脱水。
强洗即电动机转速快,弱洗即电动机转速慢。
整机功能要求
开机默认状态为标准方式、强洗。
在洗涤和漂洗过程中,电动机正转一次,反转一次,连续运行。
在进水和脱水过程中,相应的指示灯亮,继电器吸合。
当执行某个步骤时,只有“K3”键有效,按下暂停,再按恢复运行。
方案设计与论证
全自动洗衣机的实现方案组成框图如图一所示。它主要有电源、单片机最小系统、开关检测电路、控制按键输入电路和LED指示电路、继电器和电动机电路。
硬件电路设计
图二
电动机驱动模块电路设计
电动机驱动采用LD298电动机驱动芯片,单片机P25、P24与L298的IN1、IN2分别对应相连,ENA直接接VCC,后面所加4个二极管VD3到VD6起连续作用。电动机驱动电路原理图如图二所示。
电源模块电路设计
电动机驱动芯片的电源VCC和VS之间通过0欧的电阻R20进行隔离后,对LD298进行供电。
控制按键
如图二所示,K3键接到单片机的外部中断0,通过中断实现运行、暂停、继续运行的控制功能,当K3键第一次按下时(num2=1)正常运行,当K3键第二次按下时(num2=2)暂停运行。
进水阀和排水阀控制继电器
如图二所示,单片机的P23用来控制排水阀继电器,P22用来控制进水阀继电器,P22和P23对应输出为0时对应的阀打开,输出为1时对应的阀关闭。
软件设计
1)流程图
主程序流程图如图三所示。
程序
程序附在最后
图三
调试与分析
1、软件调试:
写程序代码时应先搭建好硬件电路,然后根据硬件电路写程序代码。在调试程序过程中,先保证程序能够运行无错误,然后在烧到实物中观察结果。
2、硬件调试:
硬件电路设计与软件设计完成后,将程序烧写到单片机中,观察运行结果是否符合要求。如果不符合设计要求,应先检查硬件是否能正常工作,如用实验板自带的正确代码检测硬件电路;然后根据设计要求到程序代码中分模块进行调试,比如该设计需用到液晶、矩阵键盘、定时器、独立键盘、中断和LED灯等,如果测试过程中液晶模块不能正常显示或者显示乱码,应将液晶模块单独分离出来进行测试,其他模块亦是如此。程序调试完成后,应在硬件电路上反复运行,以确保程序和硬件电路的稳定性。
总结
这次单片机程序设计专周,我感觉收获了很多,尤其是在提升自身的工作和自主学习能力方面。我在大二上学期就开始在实验室自学单片机,但是因为是自学,自觉性就很差,而且自学也是一件比较难的事,学习过程中一直都是学习和模仿别人的代码,看着别人写出来的程序代码,总觉得都能看懂,所以自己基本上没有自己构思写程序代码,唯一做过一次全自动洗衣机也是看着别人写的源程序代码,不停的修修改改。
这次刚拿到设计题目时,本以为不难,一开始还信心满满,然而开始做就感觉有些茫然了,尤其是题目中还有些知识是我还没学过的,比如液晶。所以我们组就必须得先把液晶学了,把需要学习的模块学完后,先是毫无头绪的写主程序,整个过程举步维艰,然后我们去学习了别人的设计方法,开始分工和分模块进行。组内分组搭建硬件电路,和写程序,先把电路搭建好,再写程序。写程序的过程中,我们是把程序分成几个小模块:液晶显示模块、键盘输入模块、抢答模块,然后每个模块写成子程序,在主程序中只需调用各个子程序即可。
在程序调试过程中,也遇到各种问题,但都逐个解决了。在整个设计过程中,我学到了许多课堂上老师无法传授的知识,也真正地做出了一件自己的产品。
单片机源程序如下:
#include #define uchar unsigned char #define uint unsigned int uchar num=0,num1=0,num2=0,num3=0,num4=0,num5=0,num6=0,flag=0,flag1=0,flag4=0,flag5=0,circle=0; sbit ledbiaozhun=P1^0; //LED指示灯 sbit ledjingji =P1^1; sbit leddandu =P1^2; sbit ledpaishui =P1^3; sbit ledqiangxi =P1^4; sbit ledruoxi =P1^5; sbit ledxidi =P1^6; sbit ledpiaoxi =P1^7; sbit ledtuoshui =P2^0; sbit sshuiwei =P3^6; //水位开关 sbit sgai =P3^7; //盖开关 sbit paishui=P2^3; //排水阀控制 sbit jinshui=P2^2; //进水阀控制 sbit U2=P2^4; sbit U3=P2^5; sbit k1=P3^0; // 步进改变'标准、经济、单独、排水'四种方式 sbit k2=P3^1; //强洗、弱洗 sbit k3=P3^2; //运行、暂停和解除报替功能 void init() { uchar a=0,b=0,c=0; TMOD=0x01; //T0工作于方式1 TH0=(65536-50000)/256; //定时时间50ms TL0=(65536-50000)%256; EA=1; //开总中断 ET0=1; //开T0中断 TR0=0; //关闭T0 EX0=1; //开外部中断0 IT0=1; //外部中断0边沿触发方式 U2=1; //电机停转 U3=1; P0=0xff; } void delayms(uint xms) //延时 { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } void key() //控制按键 { circle=1; if(k1==0) //标准、经济、单独、排水按下 { delayms(10); //延时消抖 if(k1==0) //再判 { num++; //K1按下次数加1 if(num==4) num=0; //等于4,按下次数清0 while(!k1); //等待按键释放 } } if(k2==0) //强弱选择 { delayms(10); //延时消抖 if(k2==0) //再判 { num1++; //按下次数加1 if(num1==2) num1=0; //等于2,按下次数清0 while(!k2); //等待按键释放 } } } void qiang() //强 { if(flag4==0) //电机正转 { U2=0; U3=1; } if(flag4==1) //电机反转 { U2=1; U3=0; } } void ruo() //弱 { if(flag5==0) //电机正转 { U2=0; U3=1; } if(flag5==1) //电机反转 { U2=1; U3=0; } } void qbiaozhun() //强标准 { /*******洗涤********/ num=0; num1=0; ledbiaozhun=0;//标准洗LED亮 ledqiangxi=0; //强洗LED亮 jinshui=0; //打开进水阀 ledxidi=1; //洗涤 ledpiaoxi=1; //漂洗LED亮 ledtuoshui=1; //脱水LED亮 delayms(5000);//水位监测 jinshui=1; //关闭进水阀 ledxidi=0; flag1=1; // TR0=1; //启动定时器T0 while(flag==0)//flag为洗涤次数标志位 { if(flag==0&&num2==1) { TR0=1; flag1=1; // qiang(); } if(flag==0&&num2==2) { TR0=0; //关闭定时器T0 U2=1; //电机停止 U3=1; } }; //漂洗 U2=1; U3=1; TR0=0; flag1=0; paishui=0; //排水 ledtuoshui=1; ledpiaoxi=1; ledxidi=1; delayms(5000); paishui=1; //关闭排水 delayms(100); jinshui=0; //打开进水 delayms(5000); jinshui=1; //关闭进水 ledpiaoxi=0; flag1=2; TR0=1; num3=0; num4=0; while(flag==1) { if(flag==1&&num2==1)//强漂洗 { TR0=1; flag1=2; qiang(); } if(flag==1&&num2==2)//暂停强漂洗 { TR0=0; U2=1; U3=1; } }; //漂洗 U2=1; U3=1; TR0=0; flag1=0; paishui=0; ledtuoshui=1; ledpiaoxi=0; delayms(5000); paishui=1; delayms(100); jinshui=0; delayms(5000); jinshui=1; flag1=2; TR0=1; num3=0; num4=0; while(flag==2) { if(flag==2&&num2==1) { TR0=1; flag1=2; qiang(); } if(flag==2&&num2==2) { TR0=0; U2=1; U3=1; } } ; //脱水 U2=1; U3=1; TR0=0; flag1=0; paishui=0;//打开排水 ledtuoshui=0; ledpiaoxi=1; while(sgai); paishui=1; delayms(1000); flag1=3; TR0=1; num3=0; num4=0; while(flag==3) { if(flag==3&&num2==1) { TR0=1; U2=0; U3=1; flag1=3; } if(flag==3&&num2==2) { TR0=0; U2=1; U3=1; } }; ledtuoshui=1; U2=1; U3=1; flag1=0; } void qjingji() //强经济 { /*******洗涤********/ num=0; num1=0; ledjingji=0; ledqiangxi=0; ledtuoshui=1; ledpiaoxi=1; ledxidi=1; jinshui=0; delayms(5000); jinshui=1; flag1=1; //控制定时器中的洗涤指示灯 TR0=1; while(flag==0) { if(flag==0&&num2==1) { TR0=1; flag1=1; qiang(); } if(flag==0&&num2==2) { TR0=0; U2=1; U3=1; } }; //漂洗 TR0=0; U2=1; U3=1; flag1=0; paishui=0; ledjingji=0; ledtuoshui=1; ledxidi=1; delayms(5000); paishui=1; delayms(100); jinshui=0; delayms(5000); jinshui=1; ledpiaoxi=0; flag1=2; TR0=1; num3=0; num4=0; while(flag==1) { if(flag==1&&num2==1) { TR0=1; flag1=2; qiang(); } if(flag==1&&num2==2) { TR0=0; U2=1; U3=1; } }; //脱水 TR0=0; U2=1; U3=1; flag1=0; paishui=0; //打开排水 ledjingji=0; ledtuoshui=0; ledpiaoxi=1; delayms(5000); while(sgai); paishui=1; delayms(1000); flag1=3; TR0=1; flag=2; num3=0; num4=0; while(flag==2) { if(flag==2&&num2==1) { TR0=1; U2=0; U3=1; flag1=3; } if(flag==2&&num2==2) { TR0=0; U2=1; U3=1; } }; ledtuoshui=1; U2=1; U3=1; flag1=0; } void qdandu() //强单独 { num=0; num1=0; ledqiangxi=0; ledxidi=0; leddandu=0; jinshui=0; delayms(5000); jinshui=1;//关闭进水阀 flag1=1; TR0=1; while(flag==0) { if(flag==0&&num2==1) { TR0=1; flag1=1; qiang(); } if(flag==0&&num2==2) { TR0=0; U2=1; U3=1; } }; flag1=0; U2=1; U3=1; } void rbiaozhun() //弱标准 { /*******洗涤********/ num=0; num1=0; ledbiaozhun=0; ledruoxi=0; ledtuoshui=1; ledpiaoxi=1; jinshui=0; delayms(5000); jinshui=1; ledxidi=0; flag1=1; TR0=1; while(flag==0) { if(flag==0&&num2==1) { TR0=1; flag1=1; ruo(); } if(flag==0&&num2==2) { TR0=0; U2=1; U3=1; } }; //漂洗 U2=1; U3=1; TR0=0; flag1=0; paishui=0; ledtuoshui=1; ledxidi=1; delayms(5000); paishui=1; delayms(100); jinshui=0; delayms(5000); jinshui=1; ledpiaoxi=0; flag1=2; TR0=1; num3=0; num4=0; while(flag==1) { if(flag==1&&num2==1) { TR0=1; flag1=2; ruo(); } if(flag==1&&num2==2) { TR0=0; U2=1; U3=1; } }; //漂洗 U2=1; U3=1; TR0=0; flag1=0; paishui=0; ledtuoshui=1; ledpiaoxi=0; delayms(5000); paishui=1; delayms(100); jinshui=0; delayms(5000); jinshui=1; flag1=2; TR0=1; num3=0; num4=0; while(flag==2) { if(flag==2&&num2==1) { TR0=1; flag1=2; ruo(); } if(flag==2&&num2==2) { TR0=0; U2=1; U3=1; } } //脱水 U2=1; U3=1; TR0=0; flag1=0; paishui=0; delayms(5000); ledtuoshui=0; ledpiaoxi=1; while(sgai); paishui=1; delayms(1000); flag1=3; TR0=1; num3=0; num4=0; while(flag==3) { if(flag==3&&num2==1) { TR0=1; U2=0; U3=1; flag1=3; } if(flag==3&&num2==2) { TR0=0; U2=1; U3=1; } }; ledtuoshui=1; U2=1; U3=1; flag1=0; } void rjingji() //弱经济 { /*******洗涤********/ num=0; num1=0; ledjingji=0; ledruoxi=0; ledtuoshui=1; ledpiaoxi=1; ledxidi=1; jinshui=0; delayms(5000); jinshui=1; //打开进水阀,进水 flag1=1; TR0=1; while(flag==0) { if(flag==0&&num2==1) //弱经济洗 { TR0=1; flag1=1; ruo(); } if(flag==0&&num2==2) //弱经济洗暂停 { TR0=0; U2=1; U3=1; } }; //漂洗 TR0=0; U2=1; U3=1; flag1=0; paishui=0; //排水阀打开 ledjingji=0; ledtuoshui=1; ledxidi=1; delayms(5000); paishui=1; //排水阀关闭 delayms(100); jinshui=0; //进水阀打开 delayms(5000); jinshui=1; //进水阀关闭 ledpiaoxi=0; flag1=2; TR0=1; num3=0; num4=0; while(flag==1) { if(flag==1&&num2==1)//漂洗 { TR0=1; flag1=2; ruo(); } if(flag==1&&num2==2)//漂洗暂停 { TR0=0; U2=1; U3=1; } }; //脱水 TR0=0; U2=1; U3=1; flag1=0; ledjingji=0; ledtuoshui=0; ledpiaoxi=1; paishui=0; //排水阀打开 delayms(5000); while(sgai); paishui=1; delayms(3000); flag1=3; TR0=1; num3=0; num4=0; while(flag==2) { if(flag==2&&num2==1) { TR0=1; U2=0; U3=1; flag1=3; } if(flag==2&&num2==2) { TR0=0; U2=1; U3=1; } }; ledtuoshui=1; U2=1; U3=1; flag1=0; } void rdandu() //弱单独 { num=0; num1=0; ledruoxi=0; ledxidi=0; leddandu=0; jinshui=0; //打开进水阀,进水 delayms(5000); jinshui=1; flag1=1; TR0=1; //启动定时器T0 while(flag==0) { if(flag==0&&num2==1) //弱单独洗 { TR0=1; flag1=1; ruo(); } if(flag==0&&num2==2)//弱单独洗暂停 { TR0=0; U2=1; U3=1; } }; flag1=0; U2=1; U3=1; } void dpaishui() //排水/脱水 { num=0; num1=0; ledpaishui=0; ledtuoshui=0; jinshui=1; paishui=0; delayms(3000); while(sgai); delayms(3000); flag1=3; TR0=1; num3=0; num4=0; while(flag==0) { if(flag==0&&num2==1) //脱水 { TR0=1; flag1=3; U2=0; U3=1; } if(flag==0&&num2==2)//暂停脱水 { TR0=0; U2=1; U3=1; } }; U2=1; U3=1; flag1=0; ledtuoshui=1; paishui=1; ////排水阀关闭 } void main() { init(); while(1) { key(); //键扫描 if((num1==0&&num==0)&&circle==1) //标准 强洗 { ledruoxi=1; //关闭弱洗LED ledpaishui=1; //关闭排水LED ledbiaozhun=0;//强标准LED亮 ledqiangxi=0; //强洗LED亮 if(num2==1) { qbiaozhun(); //强标准洗 } if(num2>1) //K3键按下次数为2,暂停洗涤 { ; } circle=0; } if(num1==0&&num==1) //经济 强洗 { ledruoxi=1; ledbiaozhun=1; ledqiangxi=0; ledjingji=0; if(num2==1) { qjingji(); //强经济洗 ledjingji=1; } circle=0; } if(num1==0&&num==2) //单独 强洗 { ledruoxi=1; ledjingji=1; ledqiangxi=0; leddandu=0; if(num2==1) { qdandu(); //强单独洗 leddandu=1; } circle=0; } if(num1==0&&num==3) { ledruoxi=1; //排水 强洗 leddandu=1; ledqiangxi=0; ledpaishui=0; if(num2==1) { dpaishui(); //单排水 ledpaishui=1; } circle=0; } if(num1==1&&num==0) //弱 标准 { ledqiangxi=1; ledpaishui=1; ledruoxi=0; ledbiaozhun=0; if(num2==1) { rbiaozhun(); //弱标准洗 ledruoxi=1; } circle=0; } if(num1==1&&num==1) //弱经济 { ledqiangxi=1; ledbiaozhun=1; ledruoxi=0; ledjingji=0; if(num2==1) { rjingji(); //弱经济洗 ledruoxi=1; ledjingji=1; } circle=0; } if(num1==1&&num==2) { ledqiangxi=1; ledjingji=1; ledruoxi=0; leddandu=0; if(num2==1) { rdandu(); //弱单独洗 ledruoxi=1; leddandu=1; } circle=0; } if(num1==1&&num==3) { ledqiangxi=1; leddandu=1; ledruoxi=0; ledpaishui=0; if(num2==1) //K3键 { dpaishui(); //单排水 ledpaishui=1; } circle=0; } num2=0; } } void T0_time() interrupt 1 //定时 { TH0=(65536-50000)/256; //重赋初值 TL0=(65536-50000)%256; num3++; //定时计数加1 if(num3==20) //1秒时间到 { num3=0; //计数清0 if(flag1==1) ledxidi=~ledxidi; //洗涤指示取反 if(flag1==2) ledpiaoxi=~ledpiaoxi; //漂洗指示取反 if(flag1==3) ledtuoshui=~ledtuoshui; //脱水指示取反 num4++; num5++; num6++; if(num4==15) //洗涤定时,15秒到 { num4=0; //清0 flag++; //标志洗涤次数 } if(num5==5) //强洗周期,5秒到 { num5=0; flag4++; //强洗标志加1 if(flag4==2) flag4=0; } if(num6==3) //弱洗周期 ,3秒到 { num6=0; flag5++; //弱洗标志加1 if(flag5==2) flag5=0; } } } void int0() interrupt 0 //外部中断0 ,K3键 { num2++; //K3按下计数加1 ,num2为1运行,num2为2暂停 ……………………