这里有人弄过红外吗。。。就是用单片机来搞一个38k的波,来发射,,,现在我用keil调时间总是调不准
13us定时中断一次让红外发射管发射38khz的光
要是要发射9ms的话就要中断9000/13=692次
现在用keil运行,算得25ms
用c来写是有时间误差的,所以我就用keil调出290次,keil里运行算得9.038ms
但是用实物测试同样也失败,我用的是12m晶振
大神现身啊
发射部分程序(改自网上程序):
#include <reg51.h>//包含特殊功能寄存器库
sbit OP=P1^2; //红外发射管的亮灭
unsigned int count; //延时计数器
unsigned int endcount; //终止延时计数
unsigned char flag; //红外发送标志
char iraddr1; //十六位地址的第一个字节
char iraddr2; //十六位地址的第二个字节
void delay()
{
int i,j;
for(i=0;i<400;i++)
{
for(j=0;j<100;j++)
{
}
}
}
void SendIRdata(char p_irdata)
{
int i;
char irdata=p_irdata;
//发送9ms的起始码
endcount=290;//290; //290次,9.038ms
flag=1;
count=0;
do{}while(count<endcount);
//发送4.5ms的结果码
endcount=155;//155;
flag=0;
count=0;
do{}while(count<endcount);
//发送十六位地址的前八位
irdata=iraddr1;
for(i=0;i<8;i++)
{
//先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)
endcount=13;
flag=1;
count=0;
do{}while(count<endcount);
//停止发送红外信号(即编码中的高电平)
if(irdata-(irdata/2)*2) //判断二进制数个位为1还是0
{
endcount=49; //1为宽的高电平
}
else
{
endcount=13; //0为窄的高电平
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//发送十六位地址的后八位
irdata=iraddr2;
for(i=0;i<8;i++)
{
endcount=13;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount=49;
}
else
{
endcount=13;
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//发送八位数据
irdata=p_irdata;
for(i=0;i<8;i++)
{
endcount=13;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount=49;
}
else
{
endcount=13;
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//发送八位数据的反码
irdata=~p_irdata;
for(i=0;i<8;i++)
{
endcount=13;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount=49;
}
else
{
endcount=13;
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
endcount=13;
flag=1;
count=0;
do{}while(count<endcount);
flag=0;
}
void main()
{
count = 0;
flag = 0;
OP = 1;
iraddr1=5;
iraddr2=9;
TMOD = 0x02;//TMOD是定时器方式控制寄存器,这里选用定时器0,工作在模式2
TL0 = 0xF3;//定时器初值
TH0 = 0xF3;//定时器初值
EA = 1;//开总中断
ET0 = 1;//开CPU中断和T0中断
TR0 = 1;//启动定时器
while(1)
{ delay();
SendIRdata(22);
}
}
void time0_int(void) interrupt 1//定时器0中断服务程序,除函数名自己取名外,其他部分要按照这样的格式写。
{
TL0 = 0xF3;//定时器初值
TH0 = 0xF3;//定时器初值
count++;
if (flag==1)
{
OP=~OP;
}
else
{
OP = 1;
}
}