天天看點

stc8單片機控制美的空調stc8單片機通過紅外模拟成空調遙控器

stc8單片機通過紅外模拟成空調遙控器

文章分為紅外遙控原理和單片機實作兩個部分

1 紅外遙控原理

通常紅外遙控為了提高抗幹擾性能和降低電源消耗,紅外遙控器常用載波的方式傳送二進制編碼,常用的載波頻率為38kHz,這是由發射端所使用的455kHz晶振來決定的。在發射端要對晶振進行整數分頻,分頻系數一般取12,是以455kHz÷12≈37.9kHz≈38kHz。也有一些遙控系統采用36kHz、40 kHz、56 kHz等,一般由發射端晶振的振蕩頻率來決定。是以,通常的紅外遙控器是将遙控信号(二進制脈沖碼)調制在38KHz的載波上,經緩沖放大後送至紅外發光二極管,轉化為紅外信号發射出去的。

再看看這個圖

stc8單片機控制美的空調stc8單片機通過紅外模拟成空調遙控器

這個圖的意思是說:發射端要發送38KHZ的信号,這個時間是0.56ms然後不發送這個38KHZ的載波信号,那麼發射端要是想傳送信号0或者1就是靠這個不發38Khz載波的間隔來決定的.間隔時間長的1.125ms就是表示的1,間隔0.56ms就是表示的0.

stc8單片機控制美的空調stc8單片機通過紅外模拟成空調遙控器

接收端把碰到的載波信号認為是低電平,或者也可以說是接收到載波信号之後把接收端的輸出引腳拉低了,沒有接收到載波信号就會持續為1.這樣一來就完成了傳送和接收的整個過程.

2 單片機實作

首先是先用定時器定時13us的時間

void hwsend_init() //13us 11.0592
{
    AUXR |= 0x80;		//定時器時鐘1T模式
    TMOD &= 0xF0;		//設定定時器模式
    TL0 = 0x70;		//設定定時初值
    TH0 = 0xFF;		//設定定時初值
    TF0 = 0;		//清除TF0标志
    TR0 = 1;		//定時器0開始計時
    ET0 = 1; //定時器0中斷允許
    EA = 1; //允許CPU中斷
    iraddr1=0;
    iraddr2=0;
    count = 0;
    sflag = 0;
    OP = 0;
    Infr = 1;
}
           

然後就是發送空調碼了,美的的空調碼格式是先發送4.5ms的載波,然後發4.5ms(非載波),再加上6個位元組的空調遙控碼再加上4.5ms的開始載波信号,再發送5.2ms的連接配接碼(非載波)然後把6個位元組的空調遙控嗎再次發送最後加上4.5ms的載波信号,以上是開啟空調的格式,關閉的格式也是一樣的.下面貼上代碼

void SendIRdataOpen()	//發送開啟空調碼
{
    unsigned char irdata;
    unsigned char dw,sw;
    endcount=60;   																		//發送4.5ms的起始碼	692
    sflag=1;
    hwcount=0;
    while(hwcount<endcount);
    endcount=60;  		 																//發送4.5ms的結果碼 346
    sflag=0;
    hwcount=0;
    while(hwcount<endcount);   												//發送十六位位址的前八位
    //開始發送那6個位元組的資料
    for(dw=0; dw<6; dw++)
    {
        irdata=irdataOpen[dw];
        for(sw=0; sw<8; sw++)
        {
            endcount=44; 																	//先發送0.56ms的38KHZ紅外波(即編碼中0.56ms的高電平)
            sflag=1;
            count=0;
            while(count<endcount);  											//停止發送紅外信号(即編碼中的高電平)
            if(irdata-(irdata/2)*2)  											//判斷二進制數個位為1還是0
            {
                endcount=130;  															//1為寬的高電平  低電平時間為1.69ms
            }
            else
            {
                endcount=44;   															//0為窄的高電平   低電平時間為0.56ms
            }
            sflag=0;
            count=0;
            while(count<endcount);
            irdata=irdata>>1;
        }    																						//發送十六位位址的後八位
    }
    //發送結束碼
    endcount=44; 																			//先發送0.56ms的38KHZ紅外波(即編碼中0.56ms的高電平)
    sflag=1;
    count=0;
    while(count<endcount);  													//停止發送紅外信号(即編碼中的高電平)
    //發送連接配接碼
    endcount=80;  	 																//發送5.2ms的連接配接碼
    sflag=0;
    hwcount=0;
    while(hwcount<endcount);
    //再發一遍
    endcount=60;   																		//發送4.5ms的起始碼	692
    sflag=1;
    hwcount=0;
    while(hwcount<endcount);
    endcount=60;  		 																//發送4.5ms的結果碼  346
    sflag=0;
    hwcount=0;
    while(hwcount<endcount);   												//發送十六位位址的前八位
    for(dw=0; dw<6; dw++)
    {
        irdata=irdataOpen[dw];
        for(sw=0; sw<8; sw++)
        {
            endcount=44; 																	//先發送0.56ms的38KHZ紅外波(即編碼中0.56ms的高電平)
            sflag=1;
            count=0;
            while(count<endcount);  											//停止發送紅外信号(即編碼中的高電平)
            if(irdata-(irdata/2)*2)  											//判斷二進制數個位為1還是0
            {
                endcount=130;  															//1為寬的高電平  低電平時間為1.69ms
            }
            else
            {
                endcount=44;   															//0為窄的高電平   低電平時間為0.56ms
            }
            sflag=0;
            count=0;
            while(count<endcount);
            irdata=irdata>>1;
        }    																						//發送十六位位址的後八位
    }
    //發送結束碼
    endcount=44; 																			//先發送0.56ms的38KHZ紅外波(即編碼中0.56ms的高電平)
    sflag=1;
    count=0;
    while(count<endcount);
    sflag=0;
}
           

好了,空調遙控的核心的知識就是這些,我沒有提到接收的部分,接收的部分其實就用外部中斷來統計高電平的時間就可以了.這是全部的代碼,點選這裡,進行檢視.

繼續閱讀