27,375
社区成员
发帖
与我相关
我的任务
分享
//#include <AT89X51.h>
#include <reg51.h>
static bit OP; //红外发射管的亮灭控制位
static unsigned int count; //延时计数器
static unsigned int endcount; //终止延时计数
static unsigned char flag; //红外发送标志
sbit P3_4=P3^4;
char iraddr1; //十六位地址的第一个字节
char iraddr2; //十六位地址的第二个字节
void SendIRdata(char p_irdata);//发送子函数
void delay();
void main(void)
{
count = 0;
flag = 0; //无载波
OP = 0; //不亮
P3_4 = 0; //在后面会发现用OP赋值的
EA = 1; //允许CPU中断
TMOD = 0x11; //设定时器0和1为16位模式1
ET0 = 1; //定时器0中断允许
TH0 = 0xFF;
TL0 = 0xE6; //设定时值0为38K 也就是每隔26us中断一次
TR0 = 1; //开始计数
iraddr1=3; //自定义的一个地址
iraddr2=252; //地址反码
do
{
delay(); //延时
SendIRdata(221); //发送数据
}while(1);
}
//定时器0中断处理
void timeint(void) interrupt 1
{
TH0=0xFF;
TL0=0xE6; //设定时值为38K 也就是每隔26us中断一次
count++;
if (flag==1) //如果是待发送的有效数据flag=1,就在此产生载波(亮灭交变)
{
OP=~OP; //产生方波其实就是调制后的高电平哈
}
else
{
OP = 0; //发送低电平
}
P3_4 = OP; //往发射模块的 IO口发送出去哈
}
void SendIRdata(char p_irdata) //发送数据子函数
{
int i;
char irdata=p_irdata;
/***************************************************************/
//发送9ms的起始码
//引导码是9ms的高电平,9000us/26us = 346
endcount = 346;
flag=1; //载波模式有效
count=0;
while(count<endcount); //等待中断,在中断中发送载波,总时间为9ms
//发送4.5ms的结果码,并是载波模式无效,也就是发送4.5ms的低电平
//结果码是 4500us/26us = 173
endcount = 173;
flag=0;
count=0;
while(count<endcount);
/***************************************************************/
//发送十六位地址的前八位,iraddr存的是地址码
irdata=iraddr1;
for(i=0;i<8;i++)
{
//一个周期里规定先以高电平开始,在以低电平结束。先发送0.56ms的38KHZ“1”的红外波(即编码中0.56ms的高电平)
endcount = 21; //560us/26us = 21
flag=1;
count=0;
while(count<endcount); //等待中断
if(irdata-(irdata/2)*2) //判断二进制数个位为1还是0
{
endcount=64; //如果是 1,修改 endcount = 64, 64*26us = 1680us
}
else
{
endcount=21;//如果是0,则低电平 21*26us = 560us;
}
flag=0; //因为发送的 0,所以调制后就是一连串连续的低电平,所以 flag=0,载波模式无效
count=0;
while(count<endcount); //等待中断发送
irdata=irdata>>1;//依次取位
}
//发送十六位地址的后八位
irdata=iraddr2; //此处已经是地址的反码
for(i=0;i<8;i++)
{
endcount = 21;
flag=1;
count=0;
while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount = 64;
}
else
{
endcount = 21;
}
flag=0;
count=0;
while(count<endcount);
irdata=irdata>>1;
}/***************************************************************/
//发送八位数据
irdata=p_irdata;
for(i=0;i<8;i++)
{
endcount = 21;
flag=1;
count=0;
while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount=64;;
}
else
{
endcount = 21;
}
flag=0;
count=0;
while(count<endcount);
irdata=irdata>>1;
}
//发送八位数据的反码
irdata=~p_irdata; //要将数据位取反
for(i=0;i<8;i++)
{
endcount = 21;
flag=1;
count=0;
while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount = 64;
}
else
{
endcount = 21;
}
flag=0;
count=0;
while(count<endcount);
irdata=irdata>>1;
}
//到这边一帧的数据已经按照 38K + NEC发送出去了
}
void delay()
{
int i,j;
for(i=0;i<400;i++)
{
for(j=0;j<100;j++)
{
}
}
}