1.功能介紹
智能台燈可分成自動和手動兩種模式。在自動模式下,台燈能根據環境光的亮暗與人是否被台燈所檢測到(人是否在)來自動開啟台燈。當人被微機檢測到,環境光又達到某個程度的時候(可以設定與調節),台燈就會開啟。如果環境光沒有達到這個程度,台燈不會開啟。當人沒有被微機檢測到,無論多暗,台燈也不會開。 手動模式是為了不習慣使用自動模式的人或是台燈中的微機出故障等緊急情況時用的。在手動模式下,智能台燈和普通台燈是一樣使用的。
主要功能 :
(1)亮度不夠且有人靠近時台燈自動亮;
(2)靠的太近會提醒坐姿不正(蜂鳴器)
(3)附近無人時台燈自動熄滅(30秒) 時間可調
(4)根據環境亮度調節等亮度
(5)可手動調節台燈亮度
(6)設定學習時間
2.硬體設計
(1)總體硬體設計
整體硬體電路是以AT89C52單片機為控制核心,主要由熱釋電紅外傳感器,光敏電阻信号處理電路,提醒電路,燈光控制電路,故障報警電路等組成。單片機可将熱釋電紅外傳感器檢測到的人體輻射紅外信号及光強信号的模拟量轉換成數字量。

(1)LED驅動電路
LED驅動電路采用3路串聯、每路4顆的LED燈,使用三極管S8050來控制LED燈的亮滅。在軟體上采用PWM控制方式,以此達到控制LED燈的亮度。
(2)光敏感應電路
對于台燈亮度的感應采用了光敏電阻,利用光敏電阻的阻值随着亮度的改變而改變,電阻值的改變會改變光敏電阻上的電壓值。這時,通過AD轉換器采集電壓,轉換成相應的光強資料傳輸給單片機。
(3)人體感應電路
人體感應電路采用了HC-SR501基于紅外線技術的數字傳感器。當傳感器感應到人體時,傳感器IO引腳輸出高電平;當無人體時,傳感器輸出低電平。
(4)紅外接近傳感器
紅外接近傳感器采用了E18- D80NK數字型傳感器,檢測到目标是低電平輸出,正常狀态是高電平輸出;此傳感器的功能為檢測使用者是否坐于台燈前。
3.軟體設計
(1)數位管驅動程式
#define DUAN P0 //數位管段位
sbit W0=P2^7; //數位管位端
sbit W1=P2^6;
sbit W2=P2^5;
sbit W3=P2^4;
/**********************************************************************
* 名稱 : display();
* 功能 : 數位管顯示
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void display()
{
if(flag_set==0) //正常模式下
{
DUAN=tab[min/10]; //送入段碼,秒數高位
W0=0; //打開位位址
delay(1); //小延時
W0=1; //關閉位位址
DUAN=tab_dian[min%10]; //送入段碼,秒數低位
W1=0;
delay(1);
W1=1;
DUAN=tab[sec/10]; //送入段碼,分鐘數高位
W2=0;
delay(1);
W2=1;
DUAN=tab[sec%10]; //送入段碼,分鐘數高位
W3=0;
delay(1);
W3=1;
}
else if(flag_set==1) //設定模式下閃爍相應位
{
if(ss==1) //閃爍标志 ss=1 正常顯示
{
DUAN=~tab[min/10];
W0=0;
delay(1);
W0=1;
DUAN=~tab_dian[min%10];
W1=0;
delay(1);
W1=1;
}
else //閃爍标志 ss=0 熄滅相應位 達到閃爍效果 ss在定時器裡500ms取反一次
{
DUAN=~tab[10]; //
W0=0;
delay(1);
W0=1;
DUAN=~tab_dian[10];
W1=0;
delay(1);
W1=1;
}
DUAN=~tab[sec/10];
W2=0;
delay(1);
W2=1;
DUAN=~tab[sec%10];
W3=0;
delay(1);
W3=1;
}
else
{
DUAN=~tab[min/10];
W0=0;
delay(1);
W0=1;
DUAN=~tab_dian[min%10];
W1=0;
delay(1);
W1=1;
if(ss==1)
{
DUAN=~tab[sec/10];
W2=0;
delay(1);
W2=1;
DUAN=~tab[sec%10];
W3=0;
delay(1);
W3=1;
}
else
{
DUAN=~tab[10];
W2=0;
delay(1);
W2=1;
DUAN=~tab[10];
W3=0;
delay(1);
W3=1;
}
}
}
(2)按鍵驅動程式
sbit change= P2^3; //自動模式切換按鍵
sbit set = P2^2; //設定按鍵
sbit add = P2^1; //加按鍵
sbit sub = P2^0; //減按鍵
/**********************************************************************
* 名稱 : KEY();
* 功能 : 按鍵控制
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void KEY()
{
uint lum_mean,lum_all;
uchar b,c;
if(change==0) //自動切換按鍵按下
{
delay(10); //去抖
if(change==0) //再次判斷按鍵按下
{
buzz=0; //蜂鳴器鳴響
flag_auto=!flag_auto; //自動模式标志位取反
if(flag_auto==1) //當切換到手動模式時 首先将LED發光比例PWM設定在50%
scale=20;
}
while(!change) display();buzz=1; //等待按鍵釋放 松開按鍵後關閉蜂鳴器、重新整理顯示
}
if(jiejin==0&&flag_jiejin==1) //接近傳感器檢測到障礙時 開啟報警
{
buzz=0;
flag_jiejin=0;
}
if(jiejin!=flag_jiejin) //接近傳感器檢測不到障礙時 關閉報警
{
buzz=1;
flag_jiejin=1;
}
if(set==0) //設定鍵按下時
{
delay(10);
if(set==0)
{
buzz=0;
flag_set++; //設定變量++
if(flag_set==3) //加到3時回複回正常模式
flag_set=0;
flag_bs=0; //按下設定 關閉報警
}
while(!set) display(); buzz=1;//等待按鍵釋放 松開按鍵後關閉蜂鳴器、重新整理顯示
}
if(flag_set==1) //加鍵按鍵隻有在設定狀态(flag_set!=0)時按下才有效 調分
{
if(add==0) //加按鍵按下時
{
delay(10); //消抖
if(add==0)
{
buzz=0; //蜂鳴器響
min++; //分++
if(min>=60)
min=0;
}
while(!add) display(); buzz=1; //等待按鍵釋放 松開按鍵後關閉蜂鳴器、重新整理顯示
}
if(sub==0) //減按鍵按下時
{
delay(10); //消抖
if(sub==0)
{
buzz=0; //蜂鳴器響
min--; //分--
if(min>0)
min=59;
}
while(!sub) display(); buzz=1; //等待按鍵釋放 松開按鍵後關閉蜂鳴器、重新整理顯示
}
}
if(flag_set==2) //調秒
{
if(add==0) //加鍵按下
{
delay(10); //消抖
if(add==0)
{
buzz=0; //蜂鳴器響
sec++; //秒++
if(sec>=60)
sec=0;
}
while(!add) display(); buzz=1; //等待按鍵釋放 松開按鍵後關閉蜂鳴器、重新整理顯示
}
if(sub==0) //減鍵按下
{
delay(10);
if(sub==0) //消抖
{
buzz=0; //蜂鳴器響
sec--; //秒--
if(sec<0)
sec=59;
}
while(!sub) display(); buzz=1; //等待按鍵釋放 松開按鍵後關閉蜂鳴器、重新整理顯示
}
while(!sub);
}
if(flag_auto==0) //自動模式
{
if(flag_rsd==1) //且有人在範圍内時 環境發光強度控制燈光變化
{
for(b=0;b<49;b++) //将空數組tt[]内數值整體左移一位
{
tt[b]=tt[b+1]; //将後一數值放到前一位置
}
tt[49]=ADC0809(); //将讀出的ad0809數值放入tt[49]
for(c=0;c<50;c++) //将tt[]内數值相加
{
lum_all=lum_all+tt[c];
}
lum_mean=lum_all/50; //将總數/50取出平均值
// lum_all=0; //将總數清零
if(lum_mean<=30) scale=1; //判斷取出平均值大小 小于30 發光強度0%
else if(lum_mean>=150) scale=41; //大于150 發光強度100%
else scale=((lum_mean-30)/3)+1; //其他值時将其計算得到發光強度 (計算目的是為了得到一個1-41之間的數值 控制燈光變化)
}
else
scale=1; //沒有人在範圍内時 将燈光亮度調至0%
}
else //手動模式下
{
if(flag_set==0) //正常模式下
{
if(add==0) //加鍵按下
{
delay(10);
if(add==0)
{
// buzz=0; //蜂鳴器響
scale++; //燈光比例++
if(scale>=41)
scale=41;
display();
}
// while(!add) display(); buzz=1;
}
if(sub==0) //減鍵按下時
{
delay(10);
if(sub==0)
{
// buzz=0; //蜂鳴器響
scale--; //燈光比例--
if(scale>1)
scale=1;
display();
}
// while(!sub) display(); buzz=1;
}
}
}
}
(3)ADC控制程式
#define Data_ADC0809 P1
//ADC0809 控制引腳定義
sbit ST=P3^1;
sbit EOC=P3^2;
sbit OE=P3^3;
extern uchar ADC0809(); //函數聲明
/**********************************************************************
* 名稱 : ADC0809();
* 功能 : ADC0809把模拟量轉化為八位數字量
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
uchar ADC0809()
{
uchar temp_=0x00;
OE=0; //初始化高阻态 轉化初始化 低電平,禁止輸出允許
ST=0;
ST=1; //上升沿 清零
ST=0; //下降沿 開始轉換
while(EOC==0); //外部中斷 等待AD轉換結束 EOC為1時AD轉換結束跳出
OE=1; //高電平,輸出允許
temp_=Data_ADC0809; //讀取轉換的AD值
OE=0; //低電平,禁止輸出允許
return temp_; //傳回ADC讀取值
}
(4)LED亮度控制程式
//管腳聲明
sbit LED = P3^4; //PWM輸出
sbit change= P2^3; //自動模式切換按鍵
sbit rsd = P3^6; //熱釋電
sbit jiejin=P3^5; //接近開關
sbit buzz=P3^7; //蜂鳴器報警電路
/**********************************************************************
* 名稱 : init();
* 功能 : 初始化定時器
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void init()
{
TMOD=0x11; //工作方式1
TH1=0x3c;
TL1=0xb0; //T1賦初值50ms
TH0=0xff;
TL0=0xe7; //T0賦初值25us
ET0=1;
ET1=1; //打開中斷允許開關
EA=1; //中斷總開關
TR0=1; //開定時器0 開關
TR1=0; //關定時器0 開關
}
/**********************************************************************
* 名稱 : void time0() interrupt 1
* 功能 : 定時器T0 中斷服務函數:PWM脈沖發生函數
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void time0() interrupt 1
{
uchar n;
TH0=0xff;
TL0=0xe7; //重新賦初值
n++; //每25us n++
if(n>scale) //n<設定比例時,打開燈
{
LED=1;
}
else if(n<=scale)//n大于等于設定比例時 關閉燈
{
LED=0;
}
if(n==40) //n==40 :25us*40=1ms 1kHZ
{
n=0; //n=0
}
else ;
}
/**********************************************************************
* 名稱 : void time1() interrupt 3
* 功能 : 定時器T1 中斷服務函數:計時和閃爍控制 紅外熱釋
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void time1() interrupt 3
{
uchar m;
TH1=0x3c;
TL1=0xb0; //重新賦初值
m++; //50ms m++
if((m==10||m==20)&&flag_set!=0) //每過500ms 并且 在設定狀态時
{
ss=!ss; //閃爍變量取反
}
if(m==20) //到達1s時
{
m=0; //m=0
if(rsd==0) //熱釋電無信号時
rsd_sec++; //熱釋電計時秒++
if(rsd_sec<=30&&rsd==1) //熱釋電計時秒小于等于30 并且 熱釋電有信号時
{
rsd_sec=0; //将熱釋電秒清零
flag_rsd=1; //标志位置1 控制AD0809采集數值 調節燈光亮度
}
else if(rsd_sec>30&&rsd==0) //熱釋電計時秒大于30 并且 熱釋電無信号時
{
flag_rsd=0; //标志位置0 停止ad0809轉換 關閉燈光
rsd_sec=0; //熱釋電計時秒清零
}
if(flag_set==0&&flag_bs==0&&((min+sec)!=0)) //正常模式下&&未報警&&定時時間不為零時
{
sec--;
if(sec<0) //定時秒-- 小于0時
{
sec=59; //複位到59秒
min--; //分--
}
if(min<=0&&sec==0) //分和秒都減到零時
{
min=0;
flag_bs=1;
buzz=0; //蜂鳴器報警提示時間到
}
}
// else buzz=1;
}
}
(5)主函數
/**********************************************************************
* 名稱 : main();
* 功能 : 主函數
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void main()
{
init(); //調用初始化函數
flag_auto=1; //初始化手動模式
rsd=0; //熱釋電引腳置低(有信号時時高電平)
delay(500); //延時500ms後開機
while(1) //大循環
{
KEY(); //調用按鍵函數
display(); //調用顯示函數
}
}
源碼+AD電路圖 下載下傳:關注公衆号,首頁回複“智能台燈”擷取資料