单片机红外编码程序

#include

sbit P3_4 = P2^1;

static bit OP; //红外发射管的亮灭

static unsigned int count; //延时计数器

static unsigned int endcount; //终止延时计数

static unsigned char flag; //红外发送标志

char iraddr1; //十六位地址的第一个字节

char iraddr2; //十六位地址的第二个字节

void SendIRdata(char p_irdata);

void delay();

void main(void)

{

count = 0;

flag = 0;

OP = 0;

P3_4 = 0;

EA = 1; //允许CPU中断

TMOD = 0x11; //设定时器0和1为16位模式1

ET0 = 1; //定时器0中断允许

TH0 = 0xFF;

TL0 = 0xE8; //设定时值0为38K 也就是每隔26us中断一次

TR0 = 1;//开始计数

iraddr1=3;

iraddr2=252;

do{

unsigned char i;

delay();

SendIRdata(12);

}while(1);

}

//定时器0中断处理

void timeint(void) interrupt 1

{

TH0=0xFF;

TL0=0xE8; //设定时值为38K 也就是每隔26us中断一次

count++;

if (flag==1)

{

OP=~OP;

}

else

{

OP = 0;

}

P3_4 = OP;

}

void SendIRdata(char p_irdata)

{

int i;

char irdata=p_irdata;

//发送9ms的起始码

endcount=223;

flag=1;

count=0;

do{}while(count
//发送4.5ms的结果码

endcount=117;

flag=0;

count=0;

do{}while(count
//发送十六位地址的前八位

irdata=iraddr1;

for(i=0;i<8;i++)

{

//先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)

endcount=10;

flag=1;

count=0;

do{}while(count
//停止发送红外信号(即编码中的高电平)

if(irdata-(irdata/2)*2) //判断二进制数个位为1还是0

{

endcount=41; //1为宽的高电平

}

else

{

endcount=15; //0为窄的高电平

}

flag=0;

count=0;

do{}while(count
irdata=irdata>>1;

}

//发送十六位地址的后八位

irdata=iraddr2;

for(i=0;i<8;i++)

{

endcount=10;

flag=1;

count=0;

do{}while(count
if(irdata-(irdata/2)*2)

{

endcount=41;

}

else

{

endcount=15;

}

flag=0;

count=0;

do{}while(count
irdata=irdata>>1;

}

//发送八位数据

irdata=p_irdata;

for(i=0;i<8;i++)

{

endcount=10;

flag=1;

count=0;

do{}while(count
if(irdata-(irdata/2)*2)

{

endcount=41;

}

else

{

endcount=15;

}

flag=0;

count=0;

do{}while(count
irdata=irdata>>1;

}

//发送八位数据的反码

irdata=~p_irdata;

for(i=0;i<8;i++)

{

endcount=

10;

flag=1;

count=0;

do{}while(count
if(irdata-(irdata/2)*2)

{

endcount=41;

}

else

{

endcount=15;

}

flag=0;

count=0;

do{}while(count
irdata=irdata>>1;

}

endcount=10;

flag=1;

count=0;

do{}while(count
flag=0;

}

void delay()

{

int i,j;

for(i = 0; i < 400; i++){

for(j = 0; j < 200; j++){

}

}

}



*********************************************************************************


单片机模拟红外遥控器发射的C语言程序2010-11-12 09:26//********************************************单片机红外发射*******************************************
#include "reg52.h"
sbit ir=P1^0;//红外发射管控制脚,使用24M晶振
sbit ka=P2^0;
sbit kb=P2^1;
unsigned int count, set_count; //中断计数,设定中断次数
bit irflag,keyflag; //红外发送标志位,按键标志位
unsigned char irsys[]={0x00,0xff};//16位用户码
unsigned char irdata,ircode; //发送的红外数据
//---------------------------------------------------------------------------
void delay(unsigned int a)//延时约1ms,晶振24M ,此处延时不需很精确
{
unsigned char i;
while(--a!=0)
for(i=300;i>0;i--); //若是12M晶振i=125
}
//---------------------------------------------------------------------------
void keyscan() // 按键扫描
{
if(ka==0){keyflag=1;irdata=0x0a;} //a键按下,则发射数据0x0a
if(kb==0){keyflag=1;irdata=0x0b;} //b键按下,则发射数据0x0b
}
//---------------------------------------------------------------------------
void ir_sendbyte() //红外发送一个字节数据
{
unsigned char i;
for(i=0;i<8;i++) //发送8位数据
{
set_count=43;//35; //发送编码中的0.56ms高电平 (//后为12M晶振下的数值)
irflag=1; //启动红外发射二极管发射
count=0; //中断计数先清0
TR0=1; //开启定时器0
while(countTR0=0; //关闭定时器0
if(ircode&0x01) set_count=130;//130; //判断红外编码最低位,若为1则1.69ms的低电平 (//后为12M晶振下的数值)
else set_count=43;//35; //为0则0.565ms的低电平 (//后为12M晶振下的数值)
irflag=0; //低电平则不发射
count=0; //中断计数清0
TR0=1; //开启定时器0
while(countTR0=0; //关闭定时器0
ircode=ircode>>1; //将数据右移,即从低位到高位发送
}
}
//---------------------------------------------------------------------------
void ir_send() //发送红外数据
{
set_count=692;//672; //发送编码中的引导码(9ms高电平+4.5ms低电平) (//后为12M晶振下的数值)
irflag=1; //启动红外发射二极管发射
count=0; //中断计数清0
TR0=1;
while(countTR0=0;
set_co

unt=346;//336; //发送编码中的4.5ms低电平(//后为12M晶振下的数值)
irflag=0; //低电平则不发射
count=0;
TR0=1;
while(countTR0=0;
ircode=irsys[0]; //发送16位用户码的前1-8位
ir_sendbyte();
ircode=irsys[1]; //发送16位用户码的前9-16位
ir_sendbyte();
ircode=irdata; //发送8位数据码
ir_sendbyte();
ircode=~irdata; //发送8位数据反码
ir_sendbyte();
set_count=43;//35; //发送编码中的0.56ms高电平 (//后为12M晶振下的数值)
irflag=1;
count=0;
TR0=1;
while(countTR0=0;
ir=1;
delay(23); //延时23ms(编码中的23ms低电平)
set_count=692;//670; //发送编码中的引导码(9ms高电平+4.5ms低电平) (//后为12M晶振下的数值)
irflag=1;
count=0;
TR0=1;
while(countTR0=0;
set_count=346;//336; //发送编码中的4.5ms低电平(//后为12M晶振下的数值)
irflag=0;
count=0;
TR0=1;
while(countTR0=0;
set_count=43;//35; //发送编码中的0.56ms高电平 (//后为12M晶振下的数值)
irflag=1;
count=0;
TR0=1;
while(countTR0=0;
ir=1; //发射完了关闭红外发射二极管
}
//---------------------------------------------------------------------------
void timer0_init() //定时器初始化
{
EA=1;
TMOD=0x02; //定时0 8位自动重装模式
ET0=1;
TH0=0xe6;//0xf3; //定时13us,38K红外矩形波,晶振24M (//后为12M晶振下的数值)
TL0=0xe6;
}
//---------------------------------------------------------------------------
void main()
{
timer0_init(); //定时0初始化
count=0; //中断计数先清0
irflag=0; //红外发射标志先置0
while(1)
{
keyscan(); //键值扫描
if(keyflag) //若有按键按下
{
delay(10);
ir_send(); //发送红外编码
delay(500);
keyflag=0; //按键标志清零
delay(100);
}
}
}
//---------------------------------------------------------------------------
void timer0() interrupt 1 //定时器0中断
{
count++;
if(irflag==1) ir=~ir; //有发射标志,则发射38khz的矩形波
else ir=1; //否则不发射,即相当于发射编码中的低电平
}
/*说明:本人经多次调试发现若在24M晶振下使用,发射很正常,而在12M晶振下发射的数据则稳定性要差很多,正在完善中*/
/*程序编写:落叶
2010.11.12*/


相关文档
最新文档