在电脑文件里面翻出之前做的一次实验,现把它记录下来存档,在仿真上能够实现,并进行了进一步焊接过实物出来,虽然当时用的是小灯泡来代替日光灯,但实物所得效果可以实现所设基本功能,却存在工作不是很灵敏,效果差强人意,我希望能提供一些思路给大家,或许大家能通过一些思路能做出更好的效果,希望能留言告诉我,谢呐!
本次设计和传统的台灯不同,它通过热释电红外传感器来感应人体红外辐射进而控制台灯的亮灭。
当有人出现在台灯红外检测的范围内并且持续时间超过五秒时,自动感应把台灯点亮;当人暂时离开离开超过五秒时台灯自动关闭,可以达到节约能源的目的。该台灯的亮度还能根据寝室内光线的强弱来实现自动调节。
液晶显示屏可以显示自己设置的学习时长并且有专门设置的按键调节时间。到设定的时间后台灯会做出提醒。
对于在宿舍中学习看书的人,对外界环境随时间的变化不会敏感发现外界亮度的变化.这样也容易造成亮度不够导致近视眼加深等,同时对于在看书学习的同学存在姿势不对,太过于靠近书本,也容易造成近视眼加深,驼背等不良结果,而对于智能台灯,当人被微机检测到,环境光又达到某个程度的时候(可以设定与调节),台灯就会开启。如果环境光没有达到这个程度,台灯不会开启。当人没被检测到,无论多暗台灯都不会开启,同时对于有些同学在宿舍人走了但台灯忘记关了,所以设置了当人长时间检测不在旁边就会自动关闭以节省电,而且对于自己离的书本太近了也会发出警告,此智能台灯也设置了定时学习,让自己在规定时间内高效率学习,台灯同时也设置了自动与手动调节,根据个人需要进行调节。
该智能台灯的设计以单片机为中央控制单元,主要由热释电红外传感器,光强信号处理电路和LCD时间温度显示电路组成,软件选用C语言编程。
代码如下(示例):
#include"reg52.h"
#include"intrins.h"
#include "LCD1602.h"
typedef unsigned char u8;
typedef unsigned int u16;
sbit buzz=P2^3; //提示所定时到点了
sbit rsd=P1^1; //热释电 (仿真图上相当于一个输入,因为实物也相当于检测到有人输出一个电平来提示)
sbit key0=P1^0; //手动or自动 (手动则调整仿真图上的滑动变阻,自动则调整仿真图上的光敏电阻)
sbit key1=P1^2; //+ 对所选择的时间进行增加
sbit key2=P1^3; //- 对所选择的时间进行减少
sbit key3=P1^4; //选择时间并开始定时的按键
/*定义ADC0809接口*/
sbit OE=P2^6;
sbit START=P2^4;
sbit EOC=P2^5;
sbit LED=P2^7; //台灯(通过使用PWM输出,灯泡闪烁程度来判断亮度,但是实物上会显示亮暗,只不过仿真不能有这样的效果)
/*定义LCD1602接口*/
sbit ADDC=P2^0;
sbit ADDB=P2^1;
sbit ADDA=P2^2;
u8 ADC_flag,buzz_flag,time_flag=0;
u16 rsd_flag;
u16 rsd_flag2;
u8 a,b,c,d,e,f;
int sub=50,add1=0,add2=0,add3=0,rsd_time=5;
u8 key_flag;
u16 abc;
u8 num_n=0;
u8 scale=20;
static u16 pp;
/*
延时函数
*/
void delay(u16 i)
{
while(i--);
}
void delay1s(void) //误差 0us
{
unsigned char a,b,c;
for(c=167;c>0;c--)
for(b=171;b>0;b--)
for(a=16;a>0;a--);
_nop_();
}
void delay10ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
/*****************
定时器0初始化
*****************/
void init0()
{
TMOD&=0xf0;
TMOD = 0X02;
TL1 = 0x00;
TH1 = 0xF6;
ET0 = 1;
TR0 = 1;
}
/***********************
定时器1初始化
************************/
void init1()
{
TMOD&=0x0f;
TMOD |= 0x10;
TH1 = 0x3C;
TL1 = 0xB0;
ET1 = 1;
TR1 = 1;
PT1=1;
}
/**************************
ADC0809转换
**************************/
void ADC0809()
{
LED=0;
ADDC=0;ADDB=0;
if(key0==0)
{
ADDA=0;
}
else
ADDA=1;
START=0;
OE=0;
START=1;
_nop_();
_nop_();
START=0;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
while(EOC==0);
OE=1;
num_n=P0;
OE=0;
}
void ADC0809_PWM()
{
if(ADC_flag==1)
{
abc=num_n*1;
if(abc<=50)
scale=1;
else if((abc>50)&&(abc<=100))
scale=30;
else if((abc>100)&&(abc<=150))
scale=50;
else if((abc>150)&&(abc<=180))
scale=70;
else if((abc>180)&&(abc<210))
scale=85;
else if((abc>210)&&(abc<=230))
scale=92;
else if(abc>230)
scale=99;
else ;
}
else
scale=0;
}
void dingshi()
{
if(key3==0)
{
delay(10);
if(key3==0)
{
key_flag=key_flag+1;
if(key_flag>=5)
key_flag=0;
}
}
if(key_flag==1) //时
{
if(key1==0)
{
delay(10);
if(key1==0)
{
add1++;
if(add1>=24)
add1=0;
}
}
if(key2==0)
{
delay(10);
if(key2==0)
{
add1--;
if(add1<0)
add1=23;
}
}
LCD_Write_String(6,1," ");
delay10ms();
LCD_Write_Char(6,1,add1/10+'0');
LCD_Write_Char(7,1,add1%10+'0');
}
if(key_flag==2) //分
{
if(key1==0)
{
delay(10);
if(key1==0)
{
add2++;
if(add2>=60)
add2=0;
}
}
if(key2==0)
{
delay(10);
if(key2==0)
{
add2--;
if(add2<0)
add2=59;
}
}
LCD_Write_String(9,1," ");
delay10ms();
LCD_Write_Char(9,1,add2/10+'0');
LCD_Write_Char(10,1,add2%10+'0');
}
if(key_flag==3) //秒
{
if(key1==0)
{
delay(10);
if(key1==0)
{
add3++;
if(add3>=60)
add3=0;
}
}
if(key2==0)
{
delay(10);
if(key2==0)
{
add3--;
if(add3<0)
add3=59;
}
}
LCD_Write_String(12,1," ");
delay10ms();
LCD_Write_Char(12,1,add3/10+'0');
LCD_Write_Char(13,1,add3%10+'0');
}
if(key_flag==4)
time_flag=1;
LCD_Write_Char(6,1,add1/10+'0');
LCD_Write_Char(7,1,add1%10+'0');
LCD_Write_String(8,1,":");
LCD_Write_Char(9,1,add2/10+'0');
LCD_Write_Char(10,1,add2%10+'0');
LCD_Write_String(11,1,":");
LCD_Write_Char(12,1,add3/10+'0');
LCD_Write_Char(13,1,add3%10+'0');
}
void key()
{
if(pp>=10)
{
pp=0;
if(rsd==1)
rsd_flag++;
else
rsd_flag2++;
if((rsd_flag2>=rsd_time)&&(rsd==0))
{
rsd_flag2=0;
rsd_flag=0;
ADC_flag=0;
}
else if((rsd_flag>=rsd_time)&&(rsd==1))
{
ADC_flag=1;
rsd_flag=0;
rsd_flag2=0;
}
else ;
if(((add1+add2+add3)!=0)&&(time_flag==1)&&(buzz_flag==0))
{
add3--;
if(add3==0)
{
if((add2==0)&&(add1==0)&&(add3==0))
{
add3=0;
add2=0;
add1=0;
buzz=1;
buzz_flag=1;
time_flag=0;
}
else if(add2!=0)
{
add3=59;
add2--;
}
else if((add2==0)&&(add1!=0))
{
add3=59;
add2=59;
add1--;
}
else if((add1==0)&&(add2==0)&&(add3!=0))
{
add1=0;
add2=0;
add3=59;
}
else ;
}
}
}
}
/****************
主函数
*****************/
void main()
{
EA=1;
init1();
init0();
LCD_Init();
buzz=0;
while(1)
{
ADC0809();
ADC0809_PWM();
dingshi();
key();
LCD_Write_String(1,0,"light:");
LCD_Write_Char(7,0,abc%1000/100+'0');
LCD_Write_Char(8,0,abc%1000%100/10+'0');
LCD_Write_Char(9,0,abc%1000%100%10+'0');
LCD_Write_String(1,1,"time:");
if(buzz_flag==1)
{
while(sub)
{
buzz=1;
delay(500);
buzz=0;
delay(500);
sub--;
}
buzz_flag=0;
sub=50;
}
}
}
/*
PWM输出
*/
void time0() interrupt 1
{
static u16 n;
TH0=0x00;
TL0=0xf6; //重新赋初值
n++; //每25us n++
if((n>scale)&&(n<100)) //n<设置比例时,打开灯
{
LED=0;
}
else if(n<=scale)//n大于等于设置比例时 关闭灯
{
LED=1;
}
if(n==100) //n==40 :25us*40=1ms 1kHZ
{
n=0; //n=0
}
else ;
}
/*
定时间
*/
void time1() interrupt 3
{
TH1 = 0x3C;
TL1 = 0xB0;
pp++;
}
由光敏电阻、热释电红外传感器RE200B和ADC0808芯片组成的信号检测电路。热释电红外传感器只能检测到人体辐射红外线波,因此当检测到其他物体的时候不会触发信号接收电路。当有人进入检测范围时,人的红外辐射由于部分镜面的作用而聚焦,同时被热释器件接收,当两个热释电器件接收到的人体红外辐射不同,热释电是不同的,无法消除,然后输出探测到的信号。ADC0808是多种器件组成的数模混合的一种专用集成电路。在环境光线强度强时,光敏电阻的阻值小,电路检测出低电平,传感器停止工作无信号输出。在光线强度弱时,光敏电阻的阻值大,电路检测出高电平,传感器开始工作,产生有信号输出。光线强度检测是一个重要部分,有两个关键的元件,一个是光敏电阻,一个是可变电阻,其中光敏电阳测能力的强弱是由可变电阻来控制的。
因为上传时间与所制作的时间相差有一些久远,大概能知道哪些模块对应哪些功能,发现自己之前制作的问题所在,延迟过高,可能是对于LCD刷屏时间太长,体现出自己之前制作的时候只考虑了将他们组合到一起没有考虑到会互相有影响,在这个实验能充分反映,仿真图与实际结果会存在很大的差异,我觉得有些时候可以直接进行实物操作,仿真图可以选择性使用,因为实物操作才是硬道理,仿真的再好最后得到的一些硬件上的差错是仿真图体现不了的,比如可能输出一个高低电平变化灯泡就可能会有亮暗的一种反馈,但是实物中硬件连接的时候有时要接三极管和电阻来控制可以实现放大和保护灯泡的作用,不是很满意,但也作为成长的一部分。
链接:https://pan.baidu.com/s/1BhdDkxEn0S_s7pnxu7orbQ
提取码:like