最近设计了一个项目基于单片机的洗衣机系统,与大家分享一下:
一、基本介绍
项目名:洗衣机
项目编号:mcuclub-jj-018
单片机类型:STC89C52
具体功能:
1、通过模式按键可以选择不同模式(标准、浸洗、强洗、快洗),通过4个LED灯指示,模式不同,时间不同
2、通过水量按键可选择不同的水位(18L、32L、46L、62L),通过4个LED灯指示
3、通过4个LED灯显示当前所处过程(浸泡、洗涤、漂洗、脱水)
4、通过一个启动/暂停按键控制洗衣机的启动/暂停
5、洗衣结束后,蜂鸣器报警3次提醒洗衣结束
6、通过2位数码管显示时间
7、通过一个继电器模拟进水、另一个继电器模拟出水、直流电机模拟洗涤
扩展功能:通过蓝牙模块将所有状态发送到手机端,手机端可以控制洗衣机启停
二、51实物图
单片机型号:STC89C52
板子为绿色PCB板,两层板,厚度1.2,上下覆铜接地。元器件基本上为插针式,个别降压芯片会使用贴片式。
供电接口:TYPE-C
三、51仿真图
仿真软件版本:proteus8.9
电路连线方式:网络标号连线方式
注意:部分实物元器件仿真中没有,仿真中会用其他工作原理相似的元件代替,这样可能导致实物程序和仿真程序不一样
四、32实物图
单片机型号:STM32F103C8T6
板子为绿色PCB板,两层板,厚度1.2,上下覆铜接地。元器件基本上为插针式,个别降压芯片会使用贴片式。
供电接口:TYPE-C
五、原理图
软件版本:AD2013
电路连线方式:网络标号连线方式
注意:原理图只是画出了模块的引脚图,而并不是模块的内部结构原理图
六、PCB图
由原理图导出,封装很大一部分都是作者自己绘制,不提供封装库,只提供连接好的源文件。中间有一个项目编号,隐藏在单片机底座下,插入单片机后不会看到。
两层板,上下覆铜接地。
七、系统框图
此次设计的自动洗衣机,按照输入方式可以分为输入、输出和中控三部分。中控部分是使用了单片机,其以获取输入的部分数据为主要目的,再通过内部进行处理,把持输出部分。输入部分是由两部分构建,第一部分为按键模块,经过这一模块能够控制启停、切换模式、设置水位;第二部分为供电模块,整个控制系统的供电都是有该模块提供的。输出部分则是由四部分构建,第一部分为数码管的显示模块,可以显现出时间;第二部分为直流电机控制继电器正传和反转控制模块;第三部分为继电器,功能是加水和排水;第四部分报警模块,洗涤完成之后通过声光发出报警提醒;除此之外还有蓝牙模块,即作为输入,也作为输出,用户可以通过该模块接收当前的指令,也可以通过手机发送指令控制,洗衣机的启停。
八、软件设计流程
系统的主流程图如图所示。在主程序中:首先对各个模块进行初始化,随后进入while主循环,在主循环中,首先进入第一个函数按键函数,该函数主要分为两部分,第一部分为调用按键扫描函数获取按键键值,第二部分通过键值进行相应的处理操作,包括切换界面、设置洗衣模式和水位、启停等;紧接着进入第二个函数监测函数,该函数主要将当前的模式和水位数据通过蓝牙模块将监测的数据传输到手机端,用户也可以通过手机端发送指令,设备根据用户发送的指令执行对应的处理;紧接着进入第三个函数显示函数,该函数显示当前剩余的时间;最后进入第四个函数处理函数,洗衣机开始,步骤0:浸泡,先加水,再浸泡,步骤1:洗涤,电机正反转动,步骤2:漂洗,先放水,再加水,再漂洗,再放水,再加水,再漂洗,再放水,步骤3:脱水,电机正转,脱水完成后,蜂鸣器响3次结束。
九、部分程序展示
软件版本:keil5
逻辑程序和驱动程序分开,分布于main.c和其他.c文件
void Manage_function(void)
{
if(flag_begin == 1) //洗衣机开始
{
switch(flag_step)
{
case 0: //步骤0:浸泡,先加水,再浸泡
LED_STEP1 = 0;
LED_STEP2 = 1;
LED_STEP3 = 1;
LED_STEP4 = 1;
if(time_all > (time_mode + time_soak + time_level*5 + time_rinse + time_dehydration))
{
RELAY_JS = 0;
RELAY_FS = 1;
}
else if(time_all > (time_mode + time_level*5 + time_rinse + time_dehydration))
{
RELAY_JS = 1;
RELAY_FS = 1;
}
else
flag_step = 1;
break;
case 1: //步骤1:洗涤,电机正反转动
LED_STEP1 = 1;
LED_STEP2 = 0;
LED_STEP3 = 1;
LED_STEP4 = 1;
if(time_all > (time_level*5 + time_rinse + time_dehydration))
{
if(flag_10s == 1)
{
flag_exchange = ~flag_exchange;
flag_10s = 0;
}
if(flag_exchange == 0)
{
MOTOR_A = 1;
MOTOR_B = 0;
}
else
{
MOTOR_A = 0;
MOTOR_B = 1;
}
}
else
{
MOTOR_A = 0;
MOTOR_B = 0;
flag_step = 2;
}
break;
case 2: //步骤2:漂洗,先放水,再加水,再漂洗,再放水,再加水,再漂洗,再放水
LED_STEP1 = 1;
LED_STEP2 = 1;
LED_STEP3 = 0;
LED_STEP4 = 1;
if(time_all > (time_level*4 + time_rinse + time_dehydration)) //放水
{
RELAY_JS = 1;
RELAY_FS = 0;
}
else if(time_all > (time_level*3 + time_rinse + time_dehydration)) //加水
{
RELAY_JS = 0;
RELAY_FS = 1;
}
else if(time_all > (time_level*3 + time_rinse/2 + time_dehydration)) //漂洗
{
RELAY_JS = 1;
RELAY_FS = 1;
if(flag_10s == 1)
{
flag_exchange = ~flag_exchange;
flag_10s = 0;
}
if(flag_exchange == 0)
{
MOTOR_A = 1;
MOTOR_B = 0;
}
else
{
MOTOR_A = 0;
MOTOR_B = 1;
}
}
else if(time_all > (time_level*2 + time_rinse/2 + time_dehydration))//放水
{
MOTOR_A = 0;
MOTOR_B = 0;
RELAY_JS = 1;
RELAY_FS = 0;
}
else if(time_all > (time_level*1 + time_rinse/2 + time_dehydration))//加水
{
RELAY_JS = 0;
RELAY_FS = 1;
}
else if(time_all > (time_level*1 + time_dehydration)) //漂洗
{
RELAY_JS = 1;
RELAY_FS = 1;
if(flag_10s == 1)
{
flag_exchange = ~flag_exchange;
flag_10s = 0;
}
if(flag_exchange == 0)
{
MOTOR_A = 1;
MOTOR_B = 0;
}
else
{
MOTOR_A = 0;
MOTOR_B = 1;
}
}
else if(time_all > time_dehydration) //放水
{
MOTOR_A = 0;
MOTOR_B = 0;
RELAY_JS = 1;
RELAY_FS = 0;
}
else
{
RELAY_JS = 1;
RELAY_FS = 1;
flag_step = 3;
}
break;
case 3: //步骤3:脱水,电机正转,脱水完成后,蜂鸣器响3次结束
LED_STEP1 = 1;
LED_STEP2 = 1;
LED_STEP3 = 1;
LED_STEP4 = 0;
if(time_all != 0)
{
RELAY_JS = 1;
RELAY_FS = 0;
MOTOR_A = 1;
MOTOR_B = 0;
}
else
{
MOTOR_A = 0;
MOTOR_B = 0;
BEEP = 0;
Delay_function(500);
BEEP = 1;
Delay_function(500);
BEEP = 0;
Delay_function(500);
BEEP = 1;
Delay_function(500);
BEEP = 0;
Delay_function(500);
BEEP = 1;
Delay_function(500);
RELAY_JS = 1;
RELAY_FS = 1;
flag_step = 0;
flag_begin = 0;
flag_timer_begin = 0;
flag_1m = 0;
}
break;
default:
break;
}
}
}