紅外線遙控器開關控制
本文旨在介紹如何利用ATMEL 89C2051單晶片微處理器撰寫一組簡單的電器遙控開關應用,由於89C2051體積小,單價便宜,非常適用於小家電的應用,再加上一些附屬的電路即可達到控制家中的LED照明燈或一些電器產品。
文中的軟體程式乃是利用LY—51S單晶片學習機所提供的範例程式,加以改寫而成,並且因為89C2051的I/O接腳數量有限,而省略了LCM液晶顯示模組的元件,如此下來也節省了不少程式空間,當然外部附屬的末端電路需視所控制的電器應用,去增加不同的電路,來驅動所控制的電器,之所以會有如此構想,實際上是近日小客車進行保養之時,更換了一個汽車電池,而舊的電池尚有利用價值,又加上手上有數個DC12V的LED燈樣品,於是就加以組合,純粹是廢物再利用的想法,如果再配合一個小的太陽能充電板,就完成了一個完全不用AC電源的家中照明設施,而且勿需支付台電的電費,何樂而不為。
使用的舊物如下:
汽車電池DC12V 一個
舊紅外線遙控器 一個
DC12V LED燈 三個
手工焊接89C2051電路板 一個
之所以將此一堆手上之舊物加組合,實在是因為這些材料與其丟掉,不如加以組合成為一個廢物利用與再生的觀念,就手上有的材料加以併湊而成,如果要進一步擴充亦可增加一些電路與材料,如AC TO DC5V模組與TRIAC等元件,即可達到控制以AC為電源的電器產品。
下面就列出所撰寫的程式:
/*-----------------------------------------------
檔案名稱:IR102.c
Code:00-FF-00-FF
------------------------------------------------*/
#include
#include"delay.c"
#include
sbit IR=P3^2; //紅外線接收埠
sbit Out0=P1^0; //分別定義PORT1的BIT0~BIT7輸出,所以可有8只控制
sbit Out1=P1^1;
sbit Out2=P1^2;
sbit Out3=P1^3;
sbit Out4=P1^4;
sbit Out5=P1^5;
sbit Out6=P1^6;
sbit Out7=P1^7;
bit Turn_flag=0;
#define PortOut P1
char code Tab[16]="0123456789ABCDEF";
/*------------------------------------------------
整體變數宣告
------------------------------------------------*/
unsigned char irtime; //紅外線接收時間變數
bit irpro_ok,irok;
unsigned char IRcord[4];
unsigned data irdata[33];
unsigned char TempData[12];
/*------------------------------------------------
函數聲明
------------------------------------------------*/
void Ir_work(void);
void Ircordpro(void);
void TIM0init(void);
void EX0init(void);
/*------------------------------------------------
主程式
------------------------------------------------*/
void main(void)
{ unsigned char i=0,k; //
unsigned short j;
EX0init(); //外部中斷初始化
TIM0init(); //計時器初始化
for(i=1;i<32;i++) span="" style="mso-tab-count: 1;" data-mce-style="mso-tab-count: 1;"> //開機時,將PORT1連續快速閃爍32次,用以確認被控制的LED燈是否有動作,注意:如有加裝AC TRIAC的控制電路時,就最好將此部份程式剔除,以免快速的開關動作有損AC電源類的電器有不良反應。
{
P1=PortOut=0x00;
DelayMs(10000); //此為閃燥的時距延遲
P1=PortOut=0xff;
DelayMs(10000);
}
EA=1;
ES=1;
EX0=1;
while(1) //主程式
{
START:
if(irok) //如果接收好了,進行紅外線處理
{
Ircordpro();
irok=0;
}
if(irpro_ok) //如果處理好後,進行工作處理,
Ir_work();
k=(TempData[7]); //將紅外線遙控器所發射的控制碼取出
while(Turn_flag==0)
{
switch(k-48)
{
case 0: PortOut=0xff;break; //控制碼為0時,將所有輸出全部OFF
case 1: Out0=~Out0;break; //控制碼為1時,關->開 或 開->關
case 2: Out1=~Out1;break;
case 3: Out2=~Out2;break;
case 4: Out3=~Out3;break;
case 5: Out4=~Out4;break;
case 6: Out5=~Out5;break;
case 7: Out6=~Out6;break;
case 8: Out7=~Out7;break;
case 9: PortOut=0x00;break; //控制碼為9時,全部打開
default:break;
}
Turn_flag=1;
}
goto START;
}
}
/*------------------------------------------------
紅外線資料碼處理
------------------------------------------------*/
void Ircordpro(void)//紅外線資料碼處理函數
{
unsigned char i, j, k;
unsigned char cord,value;
k=1;
for(i=0;i<4;i++) span="" style="mso-spacerun: yes;" data-mce-style="mso-spacerun: yes;"> //處理四個位元數
{
for(j=1;j<=8;j++) o:p="">
{
cord=irdata[k];
if(cord>7) //判斷是否大於某值時為1,此於XTAL有關,目前是以12MHZ, 當然會有些許誤差.
value|=0x80;
if(j<8) o:p="">
{
value>>=1;
}
k++;
}
IRcord[i]=value;
value=0;
}
irpro_ok=1;//處理完畢時將旗號設定為1
}
/*------------------------------------------------
顯示紅外線接收的四位碼值
------------------------------------------------*/
void Ir_work(void)
{
TempData[0] = Tab[IRcord[0]/16]; //處理首碼
TempData[1] = Tab[IRcord[0]%16];
TempData[2] = '-';
TempData[3] = Tab[IRcord[1]/16]; //處理首二碼
TempData[4] = Tab[IRcord[1]%16];
TempData[5] = '-';
TempData[6] = Tab[IRcord[2]/16]; //處理資料碼
TempData[7] = Tab[IRcord[2]%16];
TempData[8] = '-';
TempData[9] = Tab[IRcord[3]/16]; //處理資料反碼
TempData[10] = Tab[IRcord[3]%16];
// LCD_Write_String(5,1,TempData);
irpro_ok=0;//處理完成清除旗號
Turn_flag=0;
}
/*------------------------------------------------
計數器0的初始化
------------------------------------------------*/
void TIM0init(void) // 計數器0的初始化
{
TMOD=0x02;//計數器0工作模式2,TH0是重置值,TL0是初值
TH0=0x00; //重置值
TL0=0x00; //初始值
ET0=1; //打開中斷
TR0=1;
}
/*------------------------------------------------
外部中斷0的初始化
------------------------------------------------*/
void EX0init(void)
{
IT0 = 1; //指定外部中斷0下降緣觸發,INT0 (P3.2)
EX0 = 1; //予能外部中斷
EA = 1; //予能總體中斷
}
/*------------------------------------------------
外部中斷0處理
------------------------------------------------*/
void EX0_ISR (void) interrupt 0 //外部中斷0服務函數
{
static unsigned char i; //接收紅外線信號處理
static bit startflag; //是否開始處理之位元旗號
if(startflag)
{
if(irtime<63 irtime="">=33) //引導碼TC9012的,9ms+4.5ms
i=0;
irdata[i]=irtime;//儲存每個電位的持續時間數,用於判斷0或1
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
else
{
irtime=0;
startflag=1;
}
}
/*------------------------------------------------
計時器TIMER0中斷處理
------------------------------------------------*/
void tim0_isr (void) interrupt 1 using 1
{
irtime++; //用於計數兩個下降邊緣之間的時間數
}
//程式結束
在此部落格的個人像簿中有範例線路圖給各位參考,其中在輸出部份只繪了4組DC12 V的LED控制線路,如果需要控制AC電源用之電器所需的電路,在繪製後會再上傳。
有關擴充AC電源控制電路已上傳,同時也繪製了時鐘電路如此就可以進一步改寫整體程式,如定時打開或關閉指定輸出,當然在沒有LCM模組顯示訊息下,在設定操作上比較不方便而已。
使用的材料來源在此提供參考:
TRIAC BT136(ICSHOP)
DIAC MOC2032(ICSHOP)
CLOCK IC DS1302(ICSHOP)
請特別留意,目前設計的NMOS SI4800線路並沒有限流保護電路,所以請儘量使用具有限流功能的DC12V LED燈,本設計DC12V的LED燈之電力來源是汽車電池的DC12V,再利用78L05降壓提供DC5V給MCU相關電路,如果下一些功夫,可以增加定時開關程式與調變LED的週期達到亮度的變化,那就看各先去發揮了。
限會員,要發表迴響,請先登入


