網路城邦
上一篇 回創作列表 下一篇   字體:
紅外線遙控器開關控制
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的週期達到亮度的變化,那就看各先去發揮了。

 

( 興趣嗜好其他 )
回應 推薦文章 列印 加入我的文摘
上一篇 回創作列表 下一篇

引用
引用網址:https://classic-blog.udn.com/article/trackback.jsp?uid=PYANG&aid=25116882