这里有人弄过红外吗。。。就是用单片机来搞一个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; } }
|