?? 紅外發射程序.c
字號:
/*
一般紅外電視遙控器的輸出都是用編碼后串行數據對38~40kHz的方波進行脈沖幅度調制而產生的,實際發射電路中調制頻率可以是任意頻率信號
只是在38~40kHz接收頭最靈敏,接收的距離遠,而其他頻率接收距離很近。
當發射器按鍵按下后,即有遙控碼發出,所按的鍵不同遙控編碼也不同。這種遙控碼具有以下特征:
采用脈寬調制的串行碼,以脈寬為0.565ms、間隔0.56ms、周期為1.125ms的組合表示二進制的“0”;以脈寬為0.565ms、間隔1.685ms、周期為2.25ms的組合表示二進制的“1”。
上述“0”和“1”組成的32位二進制碼經38kHz的載頻進行二次調制,然后再通過紅外發射二極管產生紅外線向空間發射。
一般電視遙控器為NEC標準,遙控編碼是,先發9ms的脈沖,間隔4.5ms后,發送用戶8位地址碼,發送8位地址反碼,發送8位控制碼,再發8位控制反碼,最后再發0.565ms
的脈沖信號用來結束幀。
*/
#include <reg51.h>
static bit OP,sec; //紅外發射管的亮滅
static unsigned int count,cnt; //延時計數器
static unsigned int endcount; //終止延時計數
static unsigned char flag; //紅外發送標志
bit key_mark;
char i,n;
char iraddr; //十六位地址的第一個字節
sbit out=P1^5;
sbit tishi=P1^4;
sbit add=P3^0;
sbit sub=P3^2;
char t0;
void SendIRdata(char p_irdata);
void delay();
void key();
void delay()
{
long i;
i=100;
while(i>0)
i--;
}
void key()
{
if(!add)
{
n++;
SendIRdata(n);
}
else if(!sub)
{
t0++;
TH1=TL1=t0;
}
}
void main(void)
{
count = 0;
flag = 0;
OP = 0;
out =1;
EA = 1; //允許CPU中斷
TMOD = 0x21; //設定時器0方式1和1為位模式2
ET1 = 1; //定時器1中斷允許
TH1 = 0xf3;
TL1 = 0xf3; //設定時值0為38K 也就是每隔13us中斷一次
TR1=0;
iraddr=56;
SendIRdata(n);
while(1)
{
if((!add || !sub) && !key_mark)
{
delay();
if(!add || !sub)
{
key_mark=1;
tishi=0;
key();
}
}
else if(add && sub)
key_mark=0,tishi=1;
}
}
//定時器0中斷處理
void timeint1(void) interrupt 3 //方式2
{
out=!out;
}
void send(char n)
{
for(i=0;i<8;i++)
{
//先發送0.56ms的38KHZ紅外波(即編碼中0.56ms的1電平)
out=1;
TR1=1;
TH0=0XFD;
TL0=0XD0; //565uS
TR0=1;
while(!TF0);
TF0=0;
out=1;
TR1=0;
//停止發送紅外信號(即編碼中的1電平)
if(n&1) //判斷二進制數個位為1還是0
{
TH0=0XF9;
TL0=0X6B; //1685 us 1為寬的低電平
}
else
{
TH0=0XFD;
TL0=0XD0; //565uS 0為窄的低電平
}
n>>=1;
while(!TF0);
TF0=0;
TR0=0;
TR1=0;
out=1;
}
}
void SendIRdata(char p_irdata)
{
//發送9ms的起始碼高
out=1;
TR1=1; //發送高脈沖
TH0=0XDC;
TL0=0XD8; //9000uS 定時
TR0=1;
while(!TF0);
TF0=0;
//發送4.5ms的結果碼低
TR1=0;//不發送脈沖
out=1;
TH0=0XEE;
TL0=0X6C; //4500uS 定時
while(!TF0);
TF0=0;
TR0=0;
TR1=0;
send(iraddr); //8位地址碼
send(~iraddr); //8位地址反碼
send(p_irdata); //8位控制碼
send(~p_irdata); //8位控制反碼
//發結束碼,此結束碼必須有,否則無法解碼,切忌,可以產生完整的34個下降沿,對應33位數據,即一個起始碼+32個數據位
out=1;
TR1=1;
TH0=0XFD;
TL0=0XD0; //565uS
TR0=1;
while(!TF0);
TF0=0;
TR1=0;
TR0=0;
out=1; //out=1 必須放到發送完結束嗎之后,因為38K信號產生要進time1的定時中斷,如果out放在TR1=0之前,由于此時可能會產生中斷信號,所有out
//的狀態可能取反,最終導致8550過熱而燒毀。
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -