stc8單片機通過紅外模拟成空調遙控器
文章分為紅外遙控原理和單片機實作兩個部分
1 紅外遙控原理
通常紅外遙控為了提高抗幹擾性能和降低電源消耗,紅外遙控器常用載波的方式傳送二進制編碼,常用的載波頻率為38kHz,這是由發射端所使用的455kHz晶振來決定的。在發射端要對晶振進行整數分頻,分頻系數一般取12,是以455kHz÷12≈37.9kHz≈38kHz。也有一些遙控系統采用36kHz、40 kHz、56 kHz等,一般由發射端晶振的振蕩頻率來決定。是以,通常的紅外遙控器是将遙控信号(二進制脈沖碼)調制在38KHz的載波上,經緩沖放大後送至紅外發光二極管,轉化為紅外信号發射出去的。
再看看這個圖
這個圖的意思是說:發射端要發送38KHZ的信号,這個時間是0.56ms然後不發送這個38KHZ的載波信号,那麼發射端要是想傳送信号0或者1就是靠這個不發38Khz載波的間隔來決定的.間隔時間長的1.125ms就是表示的1,間隔0.56ms就是表示的0.
接收端把碰到的載波信号認為是低電平,或者也可以說是接收到載波信号之後把接收端的輸出引腳拉低了,沒有接收到載波信号就會持續為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;
}
好了,空調遙控的核心的知識就是這些,我沒有提到接收的部分,接收的部分其實就用外部中斷來統計高電平的時間就可以了.這是全部的代碼,點選這裡,進行檢視.