这次作品的设计初衷是源自个人的生活经验,希望和我有着一样麻烦的技术宅会喜欢这个设计。当代快节奏的工作生活中,忙忙碌碌总使得我们疲惫不堪,一杯热咖啡,一杯温水也许是现代都市人最便捷的放松方式。对于长期坐在电脑前的技术宅来说,一杯热饮除了可以补充我们必须的水分,也可以使我们适当的小憩。
笔者作为职业码农,却常常遇到这样的困扰:早上冲好的咖啡,放着放着就凉了,同事胃不好,需要喝温水,可一忙就忘记了,常常是整杯水都放凉了才想起。想必每个人都有这样的经历,这次的设计,就是给大家解决这一问题,除了可以节约水资源,还能及时提醒人们饮用热饮,喜欢喝热饮的朋友,以后不必再因为冷却的热饮而苦皱眉头了!
工作原理:
值得补充的是,这次的杯垫是用废弃的光盘制作的(无意中给华硕做广告了),中间的硬币就是导热材料,下面涂了硅脂,和DS18B20粘在一起。DS18B20就是这次设计的核心,通过感应温度、并记录温度达到提醒人们喝热饮的功能。在使用非隔热杯子的前提下(材料不限,只要不是隔热的),杯子内液体的温度势必会影响杯子表层温度,虽然我们不确定杯子表层温度的具体数值,但可以肯定的是,杯子的温度是和里面液体的温度是正比的。根据这个原理,当使用者觉得某个时刻的热饮温度刚刚好适合自己饮用时,就把杯子放到杯垫上,稍等五六秒钟,给DS18B20一点时间来升温,然后按下“记忆”键,此时杯子外部的温度就被记录到了单片机的eeprom里了,即便是断电后,此数据仍会存在。
当下次冲好了一杯咖啡,就可以把杯子放到杯垫上面了,温度传感器会将采集到的温度T值与eeprom里的数值A做比较,当A-1 < T < A+1 时,杯垫侧面的八个二极管就会闪烁,以此来提示主人喝咖啡!
温度的差值也可以根据设计者自行改变,比如在比较寒冷的地区,T与A的差值可以通过改变程序来实现,我在南方,实际测试的时候发现T与A的值在正负1之间就足够了。
记忆键在向单片机记录温度数据的时候,也会擦除之前的数据,这样一个按钮就可以完成杯垫的操作。
作为单片机系统来说,其实就是DS18B20和eeprom的应用,国产的stc单片机大多数都自带了一定大小的eeprom,这就给设计者带来了极大的方便。为了让电路更加简洁,这次选用的是STC11F04E的1T单片机,具备4K的程序存储空间和1K的eeprom空间,20管脚的封装设计大大减小了PCB面积。下面就是原理图:
程序设计:
这里要做出说明的是,大多数DS18B20程序代码都是12T单片机下设计的,而1T单片机指令速度要比12T单片机快很多,这就导致了DS18B20程序不能直接拿来调用。笔者根据stc的官方资料,通过计算指令外加逻辑分析仪测试的方式,得出的结论是,11系列的1T单片机要比12T单片机指令快6.5倍左右,根据这个数据来修改原始DS18B20程序的延时程序和eeprom程序,这样就能保证系统的稳定性。
STC的官方资料很明确的给出了eeprom的原始程序,笔者根据自己的理解,对官方程序作了一些改动,为了使程序更加简洁,应用了C语言的宏定义,自己也是做了对应的库文件,方便实用。现在的程序代码略长,我整理后会补发。原理图我是用proteus画的,并不是实物中的STC11F04E单片机,但端口是通用的,只需要根据原理图对应STC11F04E单片机连线即可。程序公开情况请关注工作室腾讯微博:Chinked-out(@136678431)。
制作过程:
一、准备工作
图1
1、像图1中这样,给DS18B20接好导线,并做好绝缘。
图2
2、利用易拉罐,剪出两个直径在3.5CM左右的圆形
图3
3、准备图3中这种较厚的双面胶,五金店里都有卖,很便宜
4、根据原理图焊接好的电路板,由于电路很简单,这里我就不做过多解释了。
二、组装
图4
1、像图4这样,用双面胶粘好温度传感器和一个金属原片
图5
2、如图5,把刚刚步骤中的圆片粘在光盘上,注意是温度传感器在光盘中间的圆孔位置。
图6
3、把光盘反过来,由于另一面已经固定好了,就可以直接涂硅脂了,可以多涂点,保证下一步的顺利
图7
4、然后把四周涂有502胶水的金属圆片像图中那样粘在光盘中间(因为大多数杯子的底部都是凹进去的,所以为了增加接触面,可以用有一定厚度的金属,比如一元硬币,视频中的实物就是硬币)
图8 图9
待胶水干后,就可以在光盘的地面操作了,将电池盒(7号)和电路板粘在光盘上,用前文说的这种双面胶效果很好的,不仅粘的结实,还可以调整高度,保证光盘翻过来放置时是水平的。
源代码:
- #include "stc11fxx.h"
- #include "INTRINS.H"
- #include "basic.h"
- #include "STC11Fxx_IAP.H"
- #define Address 0x0200
- sbit DQ=P3^7;
- sbit key1 = P3^5;
- sbit key2 = P3^4;
- sbit key3 = P3^3;
- Word temp,t1,t2;
- Byte m,n,w,p;
- void delay(Word i);
- void Init_DS18B20();
- Byte ReadOneChar();
- Byte WriteOneChar(Byte dat);
- void tmpchange();
- void tmp();
- void display();
- void UartInit();
- void Delay500ms();
- void Delay150ms();
- void Delay50ms();
- void IAP_Wait ();
- Byte IAP_Read (Word addr);
- void IAP_Program (Word addr,Byte dat);
- void IAP_Erase (Word addr);
- void key();
- void Delay180ms();
- void main()
- {
- Delay180ms();
- // P1=0x00;
- w=IAP_Read(Address);
- do
- {
- tmpchange();
- tmp();
- display();
- P1=temp;
- key();
- }
- while(1);
- }
- /* 延时子程序 */
- void delay(Word i) //delay
- {
- while(i--);
- }
- /* 初始化ds18b2子函数* */
- void Init_DS18B20()
- {
- DQ = 0; //单片机将DQ拉低
- delay(390); //精确延时 大于 480us
- DQ = 1; //拉高总线
- delay(130);
- }
- /* 读字节子函数 */
- Byte ReadOneChar()
- {
- Byte i = 0;
- Byte dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 给脉冲信号
- dat>>=1; // 数据右移一位
- DQ = 1; // 给脉冲信号
- if(DQ) // DQ为1
- dat|=0x80; // 读出数据
- delay(45); // 延时
- }
- return(dat);
- }
- /* 写字节子函数 */
- Byte WriteOneChar(Byte dat)
- {
- Word i = 0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01; //写入一位数据
- delay(45);
- DQ = 1;
- dat>>=1; //右移一位数据
- }
- return(dat);
- }
- /* 发送温度转换命令 */
- void tmpchange() // DS18B20 begin change
- {
- Init_DS18B20(); // 初始化DS18B20
- WriteOneChar(0xcc); // 跳过序列号命令
- WriteOneChar(0x44); // 发送温度转换命令
- }
- /* 读出温度函数 */
- void tmp() //get the temperature
- {
- Init_DS18B20(); // 初始化ds18b2子函数
- WriteOneChar(0xcc); // 跳过ROM命令
- WriteOneChar(0xbe); // 发送读取数据命令
- m=ReadOneChar(); // 连续读两个字节数据
- n=ReadOneChar();
- temp=n;
- temp<<=8;
- temp=temp|m; // 两字节合成一个整型变量。
- temp=temp>>4;
- }
- void Delay180ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- i = 8;
- j = 145;
- k = 99;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- void IAP_Wait ()
- {
- IAP_CONTR = 0;
- IAP_CMD = 0;
- IAP_TRIG = 0;
- IAP_ADDRH = 0;
- IAP_ADDRL = 0;
- }
- Byte IAP_Read (Word addr)
- {
- Byte dat;
- Set_IAP_CMD(Read);
- Set_IAP_addr;
- Set_IAP_On;
- dat=IAP_DATA;
-
- IAP_Wait();
- return dat;
- }
- void IAP_Program (Word addr,Byte dat)
- {
- Set_IAP_CMD(Program);
- Set_IAP_addr;
- IAP_DATA=dat;
- Set_IAP_On;
- IAP_Wait();
- }
- void IAP_Erase (Word addr)
- {
- Set_IAP_CMD(Erase);
- Set_IAP_addr;
- Set_IAP_On;
- IAP_Wait();
- }
- void key()
- {
- if(key1==0)
- {
- Delay180ms();
- if(key1==0)
- {
- IAP_Erase(Address);
- IAP_Program(Address,temp);
- p=IAP_Read(Address);
- }
- }
- loop:if(key2==0)
- {
- p=IAP_Read(Address);
- P1=p;
- goto loop;
- }
- }
- void display()
- {
- //loop2:
- w=IAP_Read(Address);
- tmpchange(); //温度转换
- tmp();
- t1=temp;
- Delay150ms();
- tmpchange(); //温度转换
- tmp();
- if(temp<t1)
- {
- if((w-1)<temp&&temp<(w+1))
- {
- loop2:
- P1=0xaa;
- Delay150ms();
- P1=0x55;
- Delay150ms();
- goto loop2;
- }
- }
- }
-
- void Delay150ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- i = 7;
- j = 78;
- k = 167;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- void Delay50ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- i = 3;
- j = 26;
- k = 223;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
复制代码
原理图与完整源代码下载:
记忆杯垫(含源代码).zip
(70.19 KB, 下载次数: 172)
|