📄 红外发射程序.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 + -