字體:小 中 大 | |
|
|
2015/06/29 03:46:23瀏覽868|回應0|推薦0 | |
紅外線遙控器開關控制 本文旨在介紹如何利用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的週期達到亮度的變化,那就看各先去發揮了。 |
|
( 興趣嗜好|其他 ) |