当前位置:文档之家› 基于单片机的智能台灯设计

基于单片机的智能台灯设计

基于单片机的智能台灯设计The design of Intelligent Table Lamp Based onMicrocomputer制作人员:2015.5.14摘要随着科技的发展,单片机渗透到我们生活的各个领域,几乎很难找到哪个领域没有单片机的踪迹,台灯已是千家万户的必需生活用品,当夜晚来临时,人们摸黑去开灯,非常不方便,而当离开时,人们又经常忘记关灯而造成巨大的能源浪费。

因此我们设计制作了一种智能台灯,主要是以热释电红外传感器re200b,光敏电阻传感器和单片机组成的红外传感控制电路。

其原理是:以人体红外辐射为传感信号,当人体在台灯的范围内且环境光强较弱时,自动感应开灯,省去黑夜摸灯的麻烦;当人离开台灯传感器检测范围,自动感应关灯。

智能台灯还可以进行光亮(4档)的调节,以便达到最舒适的光亮;台灯还具有显示时间与室温的功能。

关键词:智能台灯;at89s52;热释电红外传感器re200b;时钟芯片ds12c887;温度传感器ds18b20;光敏传感器。

一.智能台灯功能介绍(1)、光亮调节:在不同的情况下需要不同的光亮来满足需求,因此我们通过给单片机四个IO口不同的电平,设置了四种光亮强度,以便达到不同的需求。

(2)、“天暗时,人来灯亮,人走灯灭”功能的实现:运用51单片机产生的方波信号驱动红外发射管发射红外线;运用三脚的红外接收头接收红外信号,当人挡住红外信号,红外信号就会反射被红外接收头接收;并且通过光敏传感器对外界的光强进行判断,在环境光线亮度达不到设定阈值时,DO端输出高电平,当外界环境光线亮度超过设定阈值时,DO端输出低电平。

由单片机检测红外接收头是否接收到红外信号,以及光敏传感器的DO端的电平高低,从而决定led 灯部分的亮度。

由此实现“天暗时,人来灯亮,人走灯灭”。

(3)、时钟部分:运用时钟芯片DS12C887产生时钟信号,由单片机读取其信号,并将数据处理之后送到液晶显示。

由于DS12C887内部有集成的电池,所以即使断电,时钟仍会走时准确,从而使该台灯更实用、更省电。

此时钟还配有按键,通过按键即可方便的调节时钟,还有闹钟功能。

(4)、温度显示:运用DS18B20芯片感应温度,由单片机读取其信号,并将数据处理后送到液晶显示,从而显示当时的温度。

二、传感器的选择及功能介绍传感器传感器是能感受规定的被测量并按照一定的规律转换成可用输出信号的器件或装置,它通常由敏感元件和转换元件组成,它的性能直接影响到整个检测电路,对检测系统起着重要的作用。

热释电红外传感器re200b红外热释电处理芯片BISS0001我们所使用的BISS0001是一款具有较高性能的传感信号处理集成电路,它配以热释电红外传感器和少量外接元器件构成被动式的热释电红外开关。

它能自动快速开启各类白炽灯、荧光灯、蜂鸣器、自动门、电风扇、烘干机和自动洗手池等装置,特别适用于企业、宾馆、商场、库房及家庭的过道、走廊等敏感区域,或用于安全区域的自动灯光、照明和报警系统。

工作原理BISS0001是由运算放大器、电压比较器、状态控制器、延迟时间定时器以及封锁时间定时器等构成的数模混合专用集成电路。

首先,根据实际需要,利用运算放大器OP1组成传感信号预处理电路,将信号放大。

然后耦合给运算放大器OP2,再进行第二级放大,同时将直流电位抬高为VM(≈0.5VDD)后,将输出信号V2送到由比较器COP1和COP2组成的双向鉴幅器,检出有效触发信号Vs。

由于VH≈0.7VDD、VL≈0.3VDD,所以,当VDD=5V 时,可有效抑制±1V的噪声干扰,提高系统的可靠性。

COP3是一个条件比较器。

当输入电压Vc<VR(≈0.2VDD)时,COP3输出为低电平封住了与门U2,禁止触发信号Vs向下级传递;而当Vc>VR时,COP3输出为高电平,进入延时周期。

当A端接“0”电平时,在Tx时间内任何V2的变化都被忽略,直至Tx时间结束,即所谓不可重复触发工作方式。

当Tx时间结束时,Vo下跳回低电平,同时启动封锁时间定时器而进入封锁周期Ti。

在Ti时间内,任何V2的变化都不能使Vo 跳变为有效状态(高电平),可有效抑制负载切换过程中产生的各种干扰。

时钟芯片DS12C887特点可作为 IBM AT 计算机的时钟和日历与MC146818B和DS1287的管脚兼容在没有外部电源的情况下可工作10年自带晶体振荡器及电池可计算到2100年前的秒、分、小时、星期、日期、月、年七种日历信息并带闰年补偿用二进制码或BCD码代表日历和闹钟信息有12和24小时两种制式,12小时制时有AM和PM提示可选用夏令时模式可以应用于MOTOROLA和INTEL两种总线数据/地址总线复用内建128字节RAM14字节时钟控制寄存器114字节通用RAM可编程方波输出总线兼容中断(/IRQ )三种可编程中断时间性中断可产生每秒一次直到每天一次中断周期性中断122 ms 到 500 ms时钟更新结束中断DS18B20温度传感器DS18B20的主要特征:全数字温度转换及输出。

先进的单总线数据通信。

最高12位分辨率,精度可达土0.5摄氏度。

12位分辨率时的最大工作周期为750毫秒。

可选择寄生工作方式。

检测温度范围为–55°C ~+125°C (–67°F ~+257°F) 内置EEPROM,限温报警功能。

64位光刻ROM,内置产品序列号,方便多机挂接。

多样封装形式,适应不同硬件系统。

三、实现:(一)、硬件部分主体部分:(两条白线为跳线,外形需要,画成了心形)LED:电流放大电路:PS:单片机IO口电流不够大,无法使灯泡足够亮。

按键部分:(二)、软件部分#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit ds=P2^4; //温度传感器信号线sbit beep=P2^3;//蜂鸣器sbit re=P2^2; //热释电sbit gm=P2^7;//光敏sbit s0=P1^3;//智能sbit s1=P3^0;//功能键sbit s2=P3^1;//增加键sbit s3=P3^4;//减小键sbit s4=P3^5;//闹钟查看键sbit s5=P3^6;//调光sbit s6=P3^2;//显示温度sbit rs=P1^0; //sbit lcden=P1^2; // 液晶sbit wr=P1^1; //sbit led1=P2^0;sbit led2=P2^1; //ledsbit led3=P2^5;sbit led4=P2^6;sbit rd=P3^7;sbit dscs=P1^7;sbit dsas=P1^6;sbit dsrw=P1^5; //时钟芯片sbit dsds=P1^4;sbit dsirq=P3^3;uint temp;float f_temp;uchar s5num=0,s0num=0,s6num=0;uchar flag1=0,flag_ri;//定义两个位变量uchar count,s1num,flag=0,t0_num;//其它变量定义uchar miao,shi,fen,year,month,day,week,amiao,afen,ashi; uchar code table[]=" 20 - - ";//液晶固定显示内容uchar code table1[]=" : : ";uchar code table2[]="WELCOME!";void write_ds(uchar,uchar);//函数申明void set_alarm(uchar,uchar,uchar);void read_alarm(); uchar read_ds(uchar);void set_time();/************************************************//*led*/void led(uchar x){switch(x){case 0: led1=1;led2=0;led3=1;led4=0;break;case 1: led1=0;led2=0;led3=1;led4=0; break;case 3: led1=0;led2=0;led3=0;led4=1; break;case 2: led1=1;led2=1;led3=0;led4=0; break;case 4: led1=0;led2=1;led3=0;led4=1; break;}}/***************************************************/void delay(uint z)//延时函数{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void di() //蜂鸣器报警声音{beep=0;delay(100);beep=1;}void write_(uchar ){//写液晶命令函数rs=0;lcden=0;P0=;delay(3);lcden=1;delay(3);lcden=0;}void write_date(uchar date){//写液晶数据函数rs=1;lcden=0;P0=date;delay(3);lcden=1;delay(3);lcden=0;}void init(){//初始化函数uchar i;EA=1;//打开总中断EX0=1;//开外部中断1IT0=1;//设置负跳变沿触发中断EX1=1;//开外部中断1IT1=1;//设置负跳变沿触发中断flag1=0;//变量初始化t0_num=0;s1num=0;week=1;lcden=0;rd=0;/*以下几行在首次设置DS12C887时使用,以后不必再写入write_ds(0x0A,0x20);//打开振荡器write_ds(0x0B,0x26);//设置24小时模式,数据二进制格式//开启闹铃中断set_time();//设置上电默认时间-----------------------------------------------------*/write_(0x38);//1602液晶初始化write_(0x0c);write_(0x06);write_(0x01);write_(0x80);for(i=0;i<15;i++)//写入液晶固定部分显示{write_date(table[i]);delay(1);}write_(0x80+0x40);for(i=0;i<16;i++){write_date(table1[i]);delay(1);}}void write_sfm(uchar add,char date){//1602液晶刷新时分秒函数4为时,7为分,10为秒char shi,ge;shi=date/10;ge=date%10;write_(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);}void write_nyr(uchar add,char date){//1602液晶刷新年月日函数3为年,6为分,9为秒char shi,ge;shi=date/10;ge=date%10;write_(0x80+add);write_date(0x30+shi);write_date(0x30+ge);}void write_week(char we){//写液晶星期显示函数write_(0x80+12);switch(we){case 1: write_date('M');delay(5);write_date('O');delay(5);write_date('N');break;case 2: write_date('T');delay(5);write_date('U');delay(5);write_date('E');break;case 3: write_date('W');delay(5);write_date('E');delay(5);write_date('D');break;case 4: write_date('T');delay(5);write_date('H');delay(5);write_date('U');break;case 5: write_date('F');delay(5);write_date('R');delay(5);write_date('I');break;case 6: write_date('S');delay(5);write_date('A');delay(5);write_date('T');break;case 7: write_date('S');delay(5);write_date('U');delay(5);write_date('N');break;}}void keyscan(){if(flag_ri==1){//这里用来取消闹钟报警,任一键取消报警if((s1==0)||(s2==0)||(s3==0)||(s4==0)){delay(5);if((s1==0)||(s2==0)||(s3==0)||(s4==0)){while(!(s1&&s2&&s3&&s4));di();flag_ri=0;//清除报警标志}}}if(s1==0)//检测S1{delay(10);if(s1==0){s1num++;//记录按下次数if(flag1==1)if(s1num==4)s1num=1;flag=1;while(!s1);di();switch(s1num){//光标闪烁点定位case 1: write_(0x80+0x40+10);write_(0x0f);break;case 2: write_(0x80+0x40+7);break;case 3: write_(0x80+0x40+4);break;case 4: write_(0x80+12);break;case 5: write_(0x80+9);break;case 6: write_(0x80+6);break;case 7: write_(0x80+3);break;case 8: s1num=0;write_(0x0c);flag=0;write_ds(0,miao);write_ds(2,fen);write_ds(4,shi);write_ds(6,week);write_ds(7,day);write_ds(8,month);write_ds(9,year);break;}}}if(s1num!=0)//只有当S1按下后,才检测S2和S3 {if(s2==0){delay(10);if(s2==0){while(!s2);di();switch(s1num){//根据功能键次数调节相应数值case 1: miao++;if(miao==60)miao=0;write_sfm(10,miao);write_(0x80+0x40+10);break;case 2: fen++;if(fen==60)fen=0;write_sfm(7,fen);write_(0x80+0x40+7);break;case 3: shi++;if(shi==24)shi=0;write_sfm(4,shi);write_(0x80+0x40+4);break;case 4: week++;if(week==8)week=1;write_week(week);write_(0x80+12);break;case 5: day++;if(day==32)day=1;write_nyr(9,day);write_(0x80+9);break;case 6: month++;if(month==13)month=1;write_nyr(6,month);write_(0x80+6);break;case 7: year++;if(year==100)year=0;write_nyr(3,year);write_(0x80+3);break;}}}if(s3==0){delay(10);if(s3==0){while(!s3);di();switch(s1num){//根据功能键次数调节相应数值case 1: miao--;if(miao==-1)miao=59;write_sfm(10,miao);write_(0x80+0x40+10);break;case 2: fen--;if(fen==-1)fen=59;write_sfm(7,fen);write_(0x80+0x40+7);break;case 3: shi--;if(shi==-1)shi=23;write_sfm(4,shi);write_(0x80+0x40+4);break;case 4: week--;if(week==0)week=7;write_week(week);write_(0x80+12);break;case 5: day--;if(day==0)day=31;write_nyr(9,day);write_(0x80+9);break;case 6: month--;if(month==0)month=12;write_nyr(6,month);write_(0x80+6);break;case 7: year--;if(year==-1)year=99;write_nyr(3,year);write_(0x80+3);break;}}}}if(s4==0)//检测S4{delay(10);if(s4==0){flag1=~flag1;while(!s4);di();if(flag1==0){//退出闹钟设置时保存数值flag=0;write_(0x80+0x40);write_date(' ');write_date(' ');write_(0x0c);write_ds(1,miao);write_ds(3,fen);write_ds(5,shi);}else{//进入闹钟设置read_alarm();//读取原始数据miao=amiao;//重新赋值用以按键调节fen=afen;shi=ashi;write_(0x80+0x40);write_date('R');//显示标志write_date('i');write_(0x80+0x40+3);write_sfm(4,ashi);//送液晶显示闹钟时间write_sfm(7,afen);write_sfm(10,amiao);}}}if(s0==0){delay(10);if(s0==0){di();s0num++;if(s0num==2)s0num=0;}}if(s5==0){delay(10);if(s5==0){di();s5num++;if(s5num==5)s5num=0;led(s5num);delay(10);}delay(10);while(!s5);}}void write_ds(uchar add,uchar date){//写12C887函数dscs=0;dsas=1;dsds=1;dsrw=1;P0=add;//先写地址dsas=0;dsrw=0;P0=date;//再写数据dsrw=1;dsas=1;dscs=1;}uchar read_ds(uchar add){//读12C887函数uchar ds_date;dsas=1;dsds=1;dsrw=1;dscs=0;P0=add;//先写地址dsas=0;dsds=0;P0=0xff;ds_date=P0;//再读数据dsds=1;dsas=1;dscs=1;return ds_date;}/*---首次操作12C887时给予寄存器初始化--- void set_time(){//首次上电初始化时间函数write_ds(0,0);write_ds(1,0);write_ds(2,28);write_ds(4,4);write_ds(5,0);write_ds(6,7);write_ds(7,10);write_ds(8,5);write_ds(9,15);}----------------------------------------*/void read_alarm(){//读取12C887闹钟值amiao=read_ds(1);afen=read_ds(3);ashi=read_ds(5);}/***********ds18b20**********/void dsreset(void) //18B20复位,初始化函数{uint i;ds=0;i=103;while(i>0)i--;ds=1;i=4;while(i>0)i--;}bit tempreadbit(void) //读1位函数{uint i;bit dat;ds=0;i++; //i++ 起延时作用ds=1;i++;i++;dat=ds;i=8;while(i>0)i--;return (dat);}uchar tempread(void) //读1个字节{uchar i,j,dat;dat=0;for(i=1;i<=8;i++){j=tempreadbit();dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里}return(dat);}void tempwritebyte(uchar dat) //向18B20写一个字节数据{uint i;uchar j;bit testb;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb) //写1{ds=0;i++;i++;ds=1;i=8;while(i>0)i--;}else{ds=0; //写0i=8;while(i>0)i--;ds=1;i++;i++;}}}void tempchange(void) //DS18B20 开始获取温度并转换{dsreset();delay(1);tempwritebyte(0xcc); // 写跳过读ROM指令tempwritebyte(0x44); // 写温度转换指令}uint get_temp() //读取寄存器中存储的温度数据uchar a,b;dsreset();delay(1);tempwritebyte(0xcc);tempwritebyte(0xbe);a=tempread(); //读低8位b=tempread(); //读高8位temp=b;temp<<=8; //两个字节组合为1个字temp=temp|a;f_temp=temp*0.0625; //温度在寄存器中为12位分辨率位0.0625°temp=f_temp*10+0.5; //乘以10表示小数点后面只取1位,加0.5是四舍五入f_temp=f_temp+0.05;return temp; //temp是整型}////////////////////显示程序//////////////////////////void dis_temp(uint t){uchar a,b;write_(0x80+0x40);a=t/100;write_date(a+0x30);delay(5);a=t%100/10;write_date(a+0x30);delay(5);write_date(0x2e);delay(5);a=t%100%10;write_date(a+0x30);delay(5);write_date(0xdf);delay(5);write_date(0x43);delay(5);}/************************************************/ /*智能*/void re200b(){if(s0num==1){if(re==1 && gm==1){if(s5num==0){s5num=1;}}if(re==0||gm==0){s5num=0;}led(s5num);}if(s0num==0){led(s5num);}}void main()//主函数{uchar i;wr=0;init();led(0);write_(0x01);for (i=0;i<8;i++){write_date(table2[i]);delay(20);}delay(4000);init();while(1){keyscan();//按键扫描re200b();if(flag_ri==1)//当闹钟中断时进入这里{di();delay(100);di();delay(500);}if(flag==0&&flag1==0)//正常工作时进入这里{keyscan();//按键扫描year=read_ds(9);//读取12C887数据month=read_ds(8);day=read_ds(7);week=read_ds(6);shi=read_ds(4);fen=read_ds(2);miao=read_ds(0);write_sfm(10,miao);//送液晶显示write_sfm(7,fen);write_sfm(4,shi);write_week(week);write_nyr(3,year);write_nyr(6,month);write_nyr(9,day);}}}void exter() interrupt 2//外部中断1服务程序{ uchar c; //进入中断表示闹钟时间到,flag_ri=1; //设置标志位,用以大程序中报警提示c=read_ds(0x0c);//读取12C887的C寄存器表示响应了中断}void wendu() interrupt 0//外部中断0服务程序{uchar i;di();for(i=0;i<4;i++){write_(0x01);tempchange();dis_temp(get_temp());delay(700);}write_(0x01);for(i=0;i<15;i++)//写入液晶固定部分显示{write_date(table[i]);delay(1);}write_(0x80+0x40);for(i=0;i<16;i++){write_date(table1[i]);delay(1);}}四、应用背景:此款智能台灯可以应用于家居生活,其功能齐全,有普通模式和智能模式之分,并且有闹钟功能,能显示温度。

相关主题