天天看點

基于51單片機智能台燈前叙主要功能主要設計想法二、内容介紹總結

前叙

  在電腦檔案裡面翻出之前做的一次實驗,現把它記錄下來存檔,在仿真上能夠實作,并進行了進一步焊接過實物出來,雖然當時用的是小燈泡來代替日光燈,但實物所得效果可以實作所設基本功能,卻存在工作不是很靈敏,效果差強人意,我希望能提供一些思路給大家,或許大家能通過一些思路能做出更好的效果,希望能留言告訴我,謝呐!

主要功能

  本次設計和傳統的台燈不同,它通過熱釋電紅外傳感器來感應人體紅外輻射進而控制台燈的亮滅。

  當有人出現在台燈紅外檢測的範圍内并且持續時間超過五秒時,自動感應把台燈點亮;當人暫時離開離開超過五秒時台燈自動關閉,可以達到節約能源的目的。該台燈的亮度還能根據寝室内光線的強弱來實作自動調節。

  液晶顯示屏可以顯示自己設定的學習時長并且有專門設定的按鍵調節時間。到設定的時間背景燈會做出提醒。

文章目錄

  • 前叙
  • 主要功能
  • 主要設計想法
    • 一、主要設計材料
  • 二、内容介紹
    • 1.main.c
    • 2.主要原理
  • 總結
    • 仿真圖,代碼等資料

主要設計想法

  對于在宿舍中學習看書的人,對外界環境随時間的變化不會敏感發現外界亮度的變化.這樣也容易造成亮度不夠導緻近視眼加深等,同時對于在看書學習的同學存在姿勢不對,太過于靠近書本,也容易造成近視眼加深,駝背等不良結果,而對于智能台燈,當人被微機檢測到,環境光又達到某個程度的時候(可以設定與調節),台燈就會開啟。如果環境光沒有達到這個程度,台燈不會開啟。當人沒被檢測到,無論多暗台燈都不會開啟,同時對于有些同學在宿舍人走了但台燈忘記關了,是以設定了當人長時間檢測不在旁邊就會自動關閉以節省電,而且對于自己離的書本太近了也會發出警告,此智能台燈也設定了定時學習,讓自己在規定時間内高效率學習,台燈同時也設定了自動與手動調節,根據個人需要進行調節。

一、主要設計材料

  該智能台燈的設計以單片機為中央控制單元,主要由熱釋電紅外傳感器,光強信号處理電路和LCD時間溫度顯示電路組成,軟體選用C語言程式設計。

二、内容介紹

1.main.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++;
}

           

2.主要原理

  由光敏電阻、熱釋電紅外傳感器RE200B和ADC0808晶片組成的信号檢測電路。熱釋電紅外傳感器隻能檢測到人體輻射紅外線波,是以當檢測到其他物體的時候不會觸發信号接收電路。當有人進入檢測範圍時,人的紅外輻射由于部分鏡面的作用而聚焦,同時被熱釋器件接收,當兩個熱釋電器件接收到的人體紅外輻射不同,熱釋電是不同的,無法消除,然後輸出探測到的信号。ADC0808是多種器件組成的數模混合的一種專用內建電路。在環境光線強度強時,光敏電阻的阻值小,電路檢測出低電平,傳感器停止工作無信号輸出。在光線強度弱時,光敏電阻的阻值大,電路檢測出高電平,傳感器開始工作,産生有信号輸出。光線強度檢測是一個重要部分,有兩個關鍵的元件,一個是光敏電阻,一個是可變電阻,其中光敏電陽測能力的強弱是由可變電阻來控制的。

總結

  因為上傳時間與所制作的時間相差有一些久遠,大概能知道哪些子產品對應哪些功能,發現自己之前制作的問題所在,延遲過高,可能是對于LCD刷屏時間太長,展現出自己之前制作的時候隻考慮了将他們組合到一起沒有考慮到會互相有影響,在這個實驗能充分反映,仿真圖與實際結果會存在很大的差異,我覺得有些時候可以直接進行實物操作,仿真圖可以選擇性使用,因為實物操作才是硬道理,仿真的再好最後得到的一些硬體上的差錯是仿真圖展現不了的,比如可能輸出一個高低電平變化燈泡就可能會有亮暗的一種回報,但是實物中硬體連接配接的時候有時要接三極管和電阻來控制可以實作放大和保護燈泡的作用,不是很滿意,但也作為成長的一部分。

仿真圖,代碼等資料

連結:https://pan.baidu.com/s/1BhdDkxEn0S_s7pnxu7orbQ

提取碼:like

學習從零開始,到無窮結束

繼續閱讀