//趁年假有点时间,我(lhxtzlhxtz)用单片机成功制成了一个"煲粥小助手"(时间很准确).
//现拿出来跟大家分享,一来给新哥们作个参考,二来希望高手能给点意见噢,总之:传递正能量,共同提高。
//感湿头的灵敏度的大小靠调节100K可变电阻获得(觉得不错)。恢复度我现在觉得还不错,用了大约一个星期,还没换
//过棉线,到了梅雨天会如何呢,现在还不知道.
/*
(1)开场白:
听说五豆粥有比较好的保健作用,但用普通的电饭煲来煲五豆粥太费工夫,于是产生了用单片机与调速器
结合,自制一个"煲粥小助手"的冲动。
(2)功能需求:
午饭后泡料,晚上临睡前(21点---23点)设置好就能自动煲粥,明早(7点---8点)就能吃上可口的五豆粥。
例如:晚上临睡前(22点)设置好3小时后自动煲粥,则凌晨1时自动煲粥,煲好后自动保温,明早(7点)吃刚刚好。
如果专门给老人吃,你就不要预约了,22点直接按启动按钮,明早7点五豆粥又软又烂,正好适合老人吃。吃前可以
根据各人的口味,加点白糖或细盐。
(具体细节请看代码的解析)
(3)硬件原理:
见付图
(4)源码适合的单片机:STC89C52RC,晶振为11.0592MHz。
(5)完整的源代码(代码编译后为967字节)如下:
*/
#include //代入头文件//
#include // 用空操作 _nop_ 时要加这句// _nop_(); //
#define uchar unsigned char //宏定义变量类型 0----255// 当状态变量
#define uint unsigned int //宏定义变量类型 0----65535// 短时间计数用
#define ulong unsigned long //宏定义变量类型 0----4294967295// 长时间计数用
uchar a,b; // 0----255 当状态变量
uchar a1,k; //预约时间显示状态变量
uint t10,t11,b10,b11; // 0----65535 X1 输入点双向滤波 (启动)
uint t20,t21,b20,b21; //0----65535 X2 输入点双向滤波 (感湿)
uint t30,t31,b30,b31; //0----65535 X2 输入点双向滤波 (预约)
ulong t1,t2,t3,tz,tbx; // 0----4294967295 长时间计数用
ulong tk, ts; // 预约时间
//3点输入
***it X1=P1^0; //启动//
***it X2=P1^1; //感湿头//
***it X3=P1^2; //预约时间调节//
//8点输出
***it Y1=P2^0; //加热驱动继电器
***it Y2=P2^1; //完成指示灯
***it Y3=P2^2; //故障指示灯
***it Y4=P2^3; //保温驱动继电器
***it Y5=P2^4; //预约1小时后自启动指示灯
***it Y6=P2^5; //预约2小时后自启动指示灯
***it Y7=P2^6; //预约3小时后自启动指示灯
***it Y8=P2^7; //预约4小时后自启动指示灯
void main( )//主程序(语句少得有点可怜噢)
{
TMOD=0x01; // 设置定时器0为工作方式1
TH0=(65536-921)/256; //高8位装数=商
TL0=(65536-921)%256; //低8位装数=余数
//上两句实际装数合计是921,用11.0592MHZ晶体时是1MS一次中断//
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1;//启动定时器0
while(1) //永不回头,定时器0的中断未到,就不断执行这个空的大循环
{
}
}
void exter0() interrupt 1 //定时器0的中断程序(绝大部分语句在这执行,一是因为有足够多的运行时间,二是避免见鬼)
{
TH0=(65536-921)/256; //重装数,11.0592MHz 装数921(1ms),如果不重装,默认数是65535,不是想要的921//
TL0=(65536-921)%256;
//开关量双向滤波开始(这种招式未见论坛上出现过,所以解析详细点。如有不当,希望高手提点)
//X1输入点双向滤波 (启动)t10,t11,b10,b11;
if(X1==0) {t10++; t11=0;} //按下记数并消除松手暗积累
if(t10==10){b10=1;b11=0; } //10MS滤波后浮出按下控制柄 b10=1 代替 X1==0,并置松手控制柄 b11为0
if(b10==1) t10=0; //清按下记数0
if(X1==1) {t11++;t10=0;} //松手记数并消除按下暗积累
if(t11==10){b11=1;b10=0; } //10MS滤波后浮出松手控制柄 b11=1 代替 X1==1,并置按下控制柄 b10为0
if(b11==1) t11=0; //清松手记数0
//X2输入点双向滤波 (感湿) t20,t21,b20,b21;
if(X2==0) {t20++; t21=0;} //按下记数并消除松手暗积累
if(t20==10){b20=1;b21=0; } //10MS滤波后浮出按下控制柄 b20=1 代替 X2==0
if(b20==1) t20=0;
if(X2==1) {t21++;t20=0;} //松手记数并消除按下暗积累
if(t21==10){b21=1;b20=0; } //10MS滤波后浮出松手控制柄 b21=1 代替 X2==1
if(b21==1) t21=0;
//X3输入点双向滤波 (预约时间) t30,t31,b30,b31;
if(X3==0) {t30++; t31=0;} //按下记数并消除松手暗积累
if(t30==10){b30=1;b31=0; } //10MS滤波后浮出按下控制柄 b30=1 代替 X3==0
if(b30==1) t30=0;
if(X3==1) {t31++;t30=0;} //松手记数并消除按下暗积累
if(t31==10){b31=1;b30=0; } //10MS滤波后浮出松手控制柄 b31=1 代替 X3==1
if(b31==1) t31=0;
//开关量双向滤波结束
//以下再也不会出现X1,X2,X3,也是告诉程序,我们怕见鬼不露相,你就跟我们的信使b10,b11,------b31打交道吧。
if(a1==0) {if(b30==1)a1=1;} //预约时间按钮按下次数记录
if(a1==1) {if(b31==1)a1=2;}
if(a1==2) {a1=3;k=k+1;}
if(a1==3) {a1=0;}
if(k>=5) {k=1;} //k在1--4循环
//预约时间显示
if(k==1) {Y5=0;Y6=1;Y7=1;Y8=1;ts=3600000;} // 预约1小时后开始工作,Y5灯亮
if(k==2) {Y5=1;Y6=0;Y7=1;Y8=1;ts=7200000;} // 预约2小时后开始工作,Y6灯亮
if(k==3) {Y5=1;Y6=1;Y7=0;Y8=1;ts=10800000;} //预约3小时后开始工作,Y7灯亮
if(k==4) {Y5=1;Y6=1;Y7=1;Y8=0;ts=14400000;} //预约4小时后开始工作,Y8灯亮
if(k>=1){ //预约时间按钮曾按下,计时开始
tk++;
if(tk==ts) {Y4=0;Y1=0;b=1;} //预约时间到,就接通保温和加热,开始加热并让保险tbx计时开始
}
if(b==1){tbx++; } //开按过了,开始加热并让保险tbx计时开始
if(tbx>=3600000) // ( 1小时 = 3600秒=数字 3600000)
{
if(a==0) {tbx=0;a=5;Y4=0;Y1=1;Y3=0; } //加热1小时还未沸腾,全断电, Y3指示亮,表示有故障
}
if(a>=1){tz++; } //水开后,总时间tz计时开始
if(tz>=3600000){a=5; Y1=1; Y2=0; } //水开后1小时停止加热( 1小时 = 3600秒=数字 3600000 )完成指示灯亮
if(b==0){if(b10==1){Y4=0;Y1=0; b=1; } } // 当按一下按钮 X1 后b10=1,加热开始Y4=0,Y1=0,并自锁b=1
if(a==0){if(b20==1){ a=1; } } // 当感湿探测头测得水开了,X2为0,b20==1,a=1让总时间tz计时开始
if(a==1){t1++; } // 水开后,延时断电t1计时开始
if(t1>=120000 ){t1=0;a=2; Y1=1; } // 到时 ( 2分钟 = 120秒=数字120000 )断电
if(a==2){t2++; } // 延时通电t2计时开始
if(t2>=300000){t2=0;a=3; Y1=0; } // 到时 ( 5分钟 = 300秒=数字300000 )通电
if(a==3){t3++; } //
if(t3>=30000){t3=0;a=4; Y1=1; }// 到时 ( 30秒 = 30秒=数字30000 )断电
if(a==4){a=2; } // 水开后1小时内,不断轮回,就是每加热30秒就保温5分钟
}
|