紅外遙控器發送數據時,是將二進制數據調制成一系列的脈沖信號紅外發射管發射出去,紅外載波為頻率38KHz的方波,紅外接收端在收到38KHz的載波信號時,會輸出低電平,否則輸出高電平,從而可以將“時斷時續”的紅外光信號解調成一定周期的連續方波信號,再經過1838一體化紅外接收頭解調便可以恢復出原數據信號。如圖1所示
圖1
紅外接收頭解調過程如圖2所示
圖2
解調后的“0”和“1”波形及單片機編碼圖3、圖4所示
圖3
圖4
圖5
了解了紅外接收頭解調及遙控編碼下面就可以對照圖5編寫編碼程序了,圖5是遙控按鍵1的一段實際編碼,由9ms低電平4.5ms高電平的啟始碼,26位系統碼,及8位數據碼、8位數據反碼、23ms高電平及結束碼組成。
電路圖
實物圖
********以下是遙控完整程序********
/********
**項目: 自制紅外電視遙控器(EE01學習板演示程序)
**作者:一線工人
**網站:電子工程師之家 www.eehome.cn
**轉貼請保持代碼的完整性
********/
#include 《reg52.h》
#define uint unsigned int
#define uchar unsigned char
bit irout;//紅外管狀態
sbit ir=P1^7;//紅外發射管控制腳
uint count, set_count;//中斷計數,設定中斷次數
bit flag,keyflag;//紅外發送標志,按鍵標志位
uchar irsys[4]={0x1a,0xa1,0xdc,0x03};//26位系統碼,最后一個字節只用2位
uchar ircode,irdata;
/**********************************************
延時1ms
***********************************************/
void delay(uint z)//延時1ms,晶振22.1184M
{
uint x,y;
for(x=z;x》0;x--)
for(y=225;y》0;y--);
}
/**********************************************
按鍵掃描
**********************************************/
void keyscan(void)
{
uchar keytemp;
P3=0xff;
keytemp=P3&0x0f;
if(keytemp!=0x0f)
{
delay(20);
keytemp=P3&0x0f;
if(keytemp!=0x0f)
keyflag=1;//有按鍵標志
switch(keytemp)
{
case 0x0e:irdata=27;break;//按鍵1對應該遙控器P+的鍵值
case 0x0d:irdata=26;break;//按鍵2對應該遙控器P-的鍵值
case 0x0b:irdata=31;break;//按鍵3對應該遙控器VOL+的鍵值
case 0x07:irdata=30;break;//按鍵4對應該遙控器VOL-的鍵值
}
}
}
/*******************************************
發送8位紅外數據
*******************************************/
void sendcode_8(void)
{
uchar i;
for(i=0;i《8;i++)
{
set_count=28;//發送0.56ms 38k紅外波(編碼中的0.56ms低電平)
flag=1;
count=0;
TR0=1;
while(count《set_count);
TR0=0;
if(ircode&0x01)//判斷紅外編碼最低位,1寬的高電平,0窄的高電平
{
set_count=120;
}
else
{
set_count=38;
}
flag=0;
count=0;
TR0=1;
while(count《set_count);
TR0=0;
ircode=ircode》》1;
}
}
/*******************************************
發送2位紅外數據
*******************************************/
void sendcode_2(void)//前26位系統碼最后兩位
{
uchar i;
for(i=0;i《2;i++)
{
set_count=28;
flag=1;
count=0;
TR0=1;
while(count《set_count);
TR0=0;
if(ircode&0x01)
{
set_count=120;
}
else
{
set_count=38;
}
flag=0;
count=0;
TR0=1;
while(count《set_count);
TR0=0;
ircode=ircode》》1;
}
}
/*******************************************
發送紅外數據
*******************************************/
void sendcode(void)
{
set_count=575;//發送9ms 38K紅外光
flag=1;
count=0;
TR0=1;
while(count《set_count);
TR0=0;
set_count=320;//間隔4.5ms
flag=0;
count=0;
TR0=1;
while(count《set_count);
TR0=0;
ircode=irsys[0];//發送26位系統碼的前1-8位
sendcode_8();
ircode=irsys[1];//發送26位系統碼的前9-16位
sendcode_8();
ircode=irsys[2];//發送26位系統碼的前17-24位
sendcode_8();
ircode=irsys[3];//發送26位系統碼的前24-26位
sendcode_2();
ircode=irdata;//發送8位數據碼
sendcode_8();
ircode=~irdata; //發送8位數據反碼
sendcode_8();
set_count=28;//發送0.56ms 38k紅外波(編碼中的0.56ms低電平)
flag=1;
count=0;
TR0=1;
while(count《set_count);
TR0=0;
ir=1;
delay(23);//延時23ms(編碼中的23ms高電平)
set_count=575;//發送9ms 38k紅外波
flag=1;
count=0;
TR0=1;
while(count《set_count);
TR0=0;
set_count=330;//間隔4.5ms
flag=0;
count=0;
TR0=1;
while(count《set_count);
TR0=0;
set_count=30;//發送0.56ms 38k紅外波(編碼中的0.56ms低電平)
flag=1;
count=0;
TR0=1;
while(count《set_count);
TR0=0;
ir=1;
}
/*******************************************
定時器初始化
*******************************************/
void init_timer()
{
EA=1;
TMOD=0X02;//8位自動重載模式
ET0=1;
TH0=0XE8;//定時13us,38K紅外波,晶振22.1184
TL0=0XE8;
}
/*******************************************
主函數
*******************************************/
void main(void)
{
init_timer();
count=0;
flag=0;
irout=1;
while(1)
{
keyscan();
if(keyflag)//若有新按鍵
{
delay(10);
sendcode();//發送紅外編碼
delay(500);
keyflag=0;//按鍵標志清零
}
}
}
/*******************************************
定時器中斷
*******************************************/
void timer0(void) interrupt 1
{
count++;
if(flag==1)
{
irout=~irout;
}
else
{
irout=1;
}
ir=irout;
}
***************************************************************************************************
評論
查看更多