急求红外发射与解码的c程序

急求红外发射与解码的c程序,第1张

(1)发送程序

#include <reg52h>

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

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

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

static unsigned int temp; //按键

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

static unsigned char num;

sbit ir_in=P3^4;

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

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

unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 2009-8-11 <br>4 <br>红外数据传输 <br>0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //共阳数码管 0~~f

void SendIRdata(char p_irdata);

void delay(unsigned int);

void keyscan();

/主函数/

void main(void)

{

num=0;

P2=0x3f;

count = 0;

flag = 0;

OP = 0;

ir_in= 0;

EA = 1; //允许CPU中断

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

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

TH0 = 0xFF;

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

TR0 = 1;//开始计数

iraddr1=3;//00000011

iraddr2=252;//11111100

do{keyscan(); <br>}while(1);

}

/定时器0中断处理 /

void timeint(void) interrupt 1

{

TH0=0xFF;

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

count++;

if (flag==1)

{

OP=~OP;

}

else

{

OP = 0;

}

ir_in= OP;

}

void SendIRdata(char p_irdata)

{ 2009-8-11

5

红外数据传输

int i;

char irdata=p_irdata;

//发送9ms的起始码

endcount=223;

flag=1;

count=0;

do{}while(count<endcount);

/发送45ms的结果码/

endcount=117;

flag=0;

count=0;

do{}while(count<endcount);

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

irdata=iraddr1;

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

{

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

endcount=10;

flag=1;

count=0;

do{}while(count<endcount);

/停止发送红外信号(即编码中的高电平)/

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

{

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

}

else

{

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

}

flag=0;

count=0;

do{}while(count<endcount);

irdata=irdata>>1;

}

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

irdata=iraddr2;

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

{

endcount=10;

flag=1;

count=0;

do{}while(count<endcount);

if(irdata-(irdata/2)2)

{

endcount=41;

}

else

{ 2009-8-11

6

红外数据传输

endcount=15;

}

flag=0;

count=0;

do{}while(count<endcount);

irdata=irdata>>1;

}

/发送八位数据/

irdata=p_irdata;

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

{

endcount=10;

flag=1;

count=0;

do{}while(count<endcount);

if(irdata-(irdata/2)2)

{

endcount=41;

}

else

{

endcount=15;

}

flag=0;

count=0;

do{}while(count<endcount);

irdata=irdata>>1;

}

/发送八位数据的反码/

irdata=~p_irdata;

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

{

endcount=10;

flag=1;

count=0;

do{}while(count<endcount);

if(irdata-(irdata/2)2)

{

endcount=41;

}

else

{

endcount=15;

}

flag=0;

count=0;

do{}while(count<endcount);

irdata=irdata>>1;

}

2009-8-11

7

红外数据传输

endcount=10;

flag=1;

count=0;

do{}while(count<endcount);

flag=0;

}

void delay(unsigned int z)

{

unsigned char x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

/4×4键盘扫描按下按键发射数据/

void keyscan()

{

P1=0xfe;

temp=P1;

temp=temp&0xf0;

while(temp!=0xf0)

{

temp=P1;

switch(temp)

{

case 0xee:num=1;

break;

case 0xde:num=2;

break;

case 0xbe:num=3;

break;

case 0x7e:num=4;

break;

}

while(temp!=0xf0)

{

temp=P1;

temp=temp&0xf0;

}

P2=table[num-1];

SendIRdata(table[num-1]);

}

P1=0xfd;

temp=P1;

temp=temp&0xf0;

while(temp!=0xf0)

{

temp=P1;

switch(temp)

{

case 0xed:num=5;

break;

case 0xdd:num=6;

break;

case 0xbd:num=7;

break;

case 0x7d:num=8; 2009-8-11

8

红外数据传输

break;

}

while(temp!=0xf0)

{

temp=P1;

temp=temp&0xf0;

}

P2=table[num-1];

SendIRdata(table[num-1]);

}

P1=0xfb;

temp=P1;

temp=temp&0xf0;

while(temp!=0xf0)

{

temp=P1;

switch(temp)

{

case 0xeb:num=9;

break;

case 0xdb:num=10;

break;

case 0xbb:num=11;

break;

case 0x7b:num=12;

break;

}

while(temp!=0xf0)

{

temp=P1;

temp=temp&0xf0;

}

P2=table[num-1];

SendIRdata(table[num-1]);

}

P1=0xf7;

temp=P1;

temp=temp&0xf0;

while(temp!=0xf0)

{

temp=P1;

switch(temp)

{

case 0xe7:num=13;

break;

case 0xd7:num=14;

break;

case 0xb7:num=15;

break;

case 0x77:num=16;

break;

}

while(temp!=0xf0)

{

temp=P1;

temp=temp&0xf0;

} 2009-8-11

9

红外数据传输

P2=table[num-1];

SendIRdata(table[num-1]);

}

}

(2)接收程序

#include"reg52h"

#define uchar unsigned char

#define uint unsigned int

uchar dis_num,num,num1,num2,num3;

sbit led=P1^0;

unsigned char code table[]={

0xc0,0xf9,0xa4,0xb0,

0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,

0xc6,0xa1,0x86,0x8e}; //共阳数码管 0~~f

sbit prem =P3^2; //定义遥控头的接收脚

uchar ram[4]={0,0,0,0};//存放接受到的4个数据 地址码16位+按键码8位+按键码取反的8位

void delaytime(uint time) //延迟90uS

{

uchar a,b;

for(a=time;a>0;a--)

{

for(b=40;b>0;b--);

}

}

void rem()interrupt 0 //中断函数

{

uchar ramc=0; //定义接收了4个字节的变量

uchar count=0; //定义现在接收第几位变量

uint i=0; //此处变量用来在下面配合连续监测9MS 内是否有高电平

prem=1;

for(i=0;i<1100;i++) //以下FOR语句执行时间为8MS左右

{

if(prem) //进入遥控接收程序首先进入引导码的前半部判断,即:是否有9MS左右的低电平

return; //引导码错误则退出

}

while(prem!=1); //等待引导码的后半部 45 MS 高电平开始的到来。

delaytime(50); //延时大于45MS时间,跨过引导码的后半部分,来到真正遥控数据32位中

//第一位数据的056MS开始脉冲

for(ramc=0;ramc<4;ramc++)//循环4次接收4个字节

{ for(count=0;count<8;count++) //循环8次接收8位(一个字节)

{

while(prem!=1); //开始判断现在接收到的数据是0或者1 ,首先在这行本句话时,

//保已经进入数据的056MS 低电平阶段

//等待本次接受数据的高电平的到来。

delaytime(9);//高电平到来后,数据0 高电平最多延续056MS,而数据1,高电平可 2009-8-11

10

红外数据传输

//延续166MS大于08MS 后我们可以再判断遥控接收脚的电平,

if(prem) //如果这时高电平仍然在继续那么接收到的数据是1的编码

{

ram[ramc]=(ram[ramc]<<1)+1;//将目前接收到的数据位1放到对应的字节中

delaytime(11); //如果本次接受到的数据是1,那么要继续延迟1MS,这样才能跨入

//下个位编码的低电平中(即是开始的056MS中)

}

else //否则目前接收到的是数据0的编码

ram[ramc]=ram[ramc]<<1; //将目前接收到的数据位0放到对应的字节中

} //本次接收结束,进行下次位接收,此接收动作进行32次,正好完成4个字节的接收

}

if(ram[2]!=(~(ram[3]&0x7f))) //本次接收码的判断

{

for(i=0;i<4;i++) //没有此对应关系则表明接收失败,清除接受到的数据

ram[i]=0;

return ;

}

dis_num=ram[2]; //将接收到的按键数据赋给显示变量

}

main()

{

IT0=1; //设定INT0为边沿触发

EX0=1; //打开外部中断0

EA=1; //全局中断开关打开

while(1)

{

switch(dis_num)

{

case 0x81: num=0; break;

case 0xcf: num=1; break;

case 0x92: num=2; break;

case 0x86: num=3; break;

case 0xcc: num=4; break;

case 0xa4: num=5; break;

case 0xa0: num=6; break;

case 0x8f: num=7; break;

case 0x80: num=8; break;

case 0x84: num=9; break;

case 0x88: num=10;break;

case 0xe0: num=11;break;

case 0xb1: num=12;break;

case 0xc2: num=13;break;

case 0xb0: num=14;break;

case 0xb8: num=15;break;

}

P2=table[num];

P1=0x01;

delaytime(5);

}

}

首先,检查红外遥控器是否被正确连接到Arduino上,并确保正确的电源供应。其次,检查红外遥控器的编码是否正确。如果没有正确的编码,可以使用特定的红外遥控器编码库,或者使用红外遥控器编码器程序来实现正确的编码。最后,确保你的代码正确地发送和接收红外信号。

这是采用STC12C5A60S2单片机的红外解码程序及其说明。

;采用脉宽调制的串行码,以脉宽为0565ms、间隔056ms、周期为1125ms的组合表示二进制的"0";

;以脉宽为0565ms、间隔1685ms、周期为225ms的组合表示二进制的"1

;上述"0"和"1"组成的32位二进制码经38kHz的载频进行二次调制以提高发射效率,

;达到降低电源功耗的目的。然后再通过红外发射二极管产生红外线向空间发射

;遥控编码是连续的32位二进制码组,其中前16位为用户识别码,能区别不同的电器设备,

;防止不同机种遥控码互相干扰。该芯片的用户识别码固定为十六进制01H

;后16位为8位 *** 作码(功能码)及其反码。

;当一个键按下超过36ms,振荡器使芯片激活,将发射一组108ms的编码脉冲,这108ms发射代码由一个起始码(9ms),

;一个结果码(45ms),低8位地址码(9ms~18ms),高8位地址码(9ms~18ms),8位数据码(9ms~18ms)

;和这8位数据的反码(9ms~18ms)组成。如果键按下超过108ms仍未松开,

;接下来发射的代码(连发代码)将仅由起始码(9ms)和结束码(25ms)组成。

;

;解码的关键是如何识别"0"和"1",接收端而言,"0"是056ms的高+056ms的低。"1"是168ms的高+056ms的低。

;所以可以根据高电平的宽度区别"0"和"1"。当高电平出现时开始延时,056ms以后,若读到的电平为低,

;说明该位为"0",反之则为"1",为了可靠起见,延时必须比056ms长些,但又不能超过112ms,否则如果该位为"0",

;读到的已是下一位的高电平,因此取(112ms+056ms)/2=084ms最为可靠,一般取084ms左右均可。

;为了共用引导部分延时程序,这里用09ms延时。

;-------------红外解码程序---------------------------

EXINT0:

PUSH ACC

PUSH PSW

PUSH 1

PUSH 2

PUSH 6

CLR EA ;暂时关闭中断请求

MOV R6,#10

EXINT10:

LCALL DELAY09MS ;调用900us延时子程序

JB IRIN,INTOUT1 ;判断P32是否有高电平,如果有就退出解码程序

DJNZ R6,EXINT10 ;循环10次,检测在900微妙中是否存在高电平。以上完成对遥控信号的9000微秒的初始低电平信号的识别。

JNB IRIN,$ ;等待高电平避开9毫秒低电平引导脉冲

LCALL DELAY45MS ;延时45毫秒

;-------------接受32位代码--------------------------

MOV R1,#IRUSERL

MOV R2,#04H

EXINT101:

MOV R6,#08H ;每组数据位8位

EXINT102:

JNB IRIN,$ ;等待地址码第一组数据的高电平信号

LCALL DELAY09MS ;高电平开始后延时判断信号此时的高/低状态

MOV C,IRIN ;将P32引脚此时的电平状态0或1存入C中

JNC INT1OUT ;如果为0跳出

LCALL DELAY1MS

INT1OUT:

MOV A,@R1

RRC A ;将C中的数据0/1移入A中最低位

MOV @R1,A ;将A中的数据暂存在R1

DJNZ R6,EXINT102 ;接受完8位代码

INC R1

DJNZ R2,EXINT101 ;接受完4组32位代码

;--------------数据码比较-------------------------------

MOV A,IRDATAL

; LCALL SENDRXDAT

MOV A,IRDATAL

CPL A

CJNE A,IRDATAH,INTOUT1 ;判断数码正误,不等退出

MOV IR_DAT,IRDATAL ;相等则保存正确数据

MOV A,IR_DAT

; LCALL SENDRXDAT

SETB IRBIT

INTOUT1:

LCALL DELAY45MS

SETB EA ;允许中断

POP 6

POP 2

POP 1

POP PSW

POP ACC

RETI

;;110592900=9953

DELAY09MS: ;6

PUSH 4 ;4

PUSH 3 ;4

MOV R4,#20 ;2

DLY900:

MOV R3,#122 ;2

DJNZ R3,$ ;4

DJNZ R4,DLY900 ;4

MOV R4,#11 ;2

DJNZ R4,$ ;4

POP 3 ;3

POP 4 ;3

RET ;4

;TOTAL=9952

;;110592560=6193

DELAY056: ;6

PUSH 4 ;4

PUSH 3 ;4

MOV R4,#12 ;2

DLY5600:

MOV R3,#122 ;2

DJNZ R3,$ ;4

DJNZ R4,DLY5600 ;4

MOV R4,#71 ;2

DJNZ R4,$ ;4

POP 3 ;3

POP 4 ;3

RET ;4

;TOTAL=6194

;;1105924500=49766

DELAY45MS: ;6

PUSH 4 ;4

PUSH 3 ;4

MOV R4,#52 ;2

DLY45:

MOV R3,#236 ;2

DJNZ R3,$ ;4

DJNZ R4,DLY45 ;4

MOV R4,#85 ;2

DJNZ R4,$ ;4

POP 3 ;3

POP 4 ;3

RET ;4

;;TOTAL=49768

;;1105921000=11059

DELAY1MS: ;6

PUSH 4 ;4

PUSH 3 ;4

MOV R4,#20 ;2

DLY1MS:

MOV R3,#136 ;2

DJNZ R3,$ ;4

DJNZ R4,DLY1MS ;4

MOV R4,#8 ;2

DJNZ R4,$ ;4

POP 3 ;3

POP 4 ;3

RET ;4

;TOTAL=11060

;;

DELAY100US: ;6

PUSH 4 ;4

MOV R4,#140 ;2

DJNZ R4,$ ;4

MOV R4,#131 ;2

DJNZ R4,$ ;4

POP 4 ;3

RET ;4

;TOTAL=1105

;;

,空调器的遥控码比较长,达100多位,分析其规律比较难,但是先要会记录其主要代码,用定时器记录其高低电平的时间依次存入RAM中,待一帧数据结束后,再存入EEPROM中,可以发往上位机进行分析

也可以不加识别地再次调用,这样会占用较大的EEPROM空间

因此不能记录其所有的按键状态 同样是开机按键,制冷和制热状态下的遥控码是不同的

//////////////////////////////////////

//晶振频率为6MHz 一个机器周期2us //

//实现按键地址码、指令码的数码管显示//

//2010-06-01 //

//////////////////////////////////////

#include<reg52h>

#define uchar unsigned char

#define uint unsigned int

sbit dula=P2^6;

sbit wela=P2^7;

bit overflag,dataover;//开始接收数据,数据处理完毕

uchar timedata;//定时器0溢出次数

uchar chubus[33];//33Byte数据 timedata组成的数组

uchar jieguos[4];//地址码,地址反码,数据码,数据反码;

void initial()//初始化

{

IT0=1;EX0=1;//负边沿触发

TMOD=0x01;ET0=1;TR0=1;//模式1,十六位定时器

TH0=0xff;TL0=0x06;//05ms溢出

EA=1; //开总中断

}

void time0() interrupt 1//定时器0中断

{TH0=0xff;TL0=0x06;

timedata++;

}

void ex0() interrupt 0//外部中断0,接收数据

{

static bit startflag;//开始接收

static uchar i;

if(startflag)

{

if(timedata<32&&timedata>=16) i=0;

chubus[i]=timedata;

timedata=0;

i++;

if(i==33){overflag=1;i=0;}

}

else

{

startflag=1;

timedata=0;

}

}

void chulidata()

{

uchar chubu;//初步数据

uchar jieguo;//结果数据

uchar x,y,z=1;

for(x=0;x<4;x++)//处理四组数据

{

for(y=1;y<=8;y++)//处理一组数据8Byte

{

chubu=chubus[z];

jieguo=jieguo>>1;

if(chubu>3) jieguo=jieguo|0x80;//大于15mS为1

z++;

}

jieguos[x]=jieguo;

jieguo=0;

}

dataover=1;

}

void delay(uint z)

{

uint x ,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void display()

{

uchar gao,gao1;

uchar di,di1;

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71};

gao1=table[jieguos[0]/16];

di1=table[jieguos[0]%16];

gao=table[jieguos[2]/16];

di=table[jieguos[2]%16];

dula=1;

P0=gao1;

dula=0;

P0=0xff;

wela=1;

P0=0x7e;

wela=0;

delay(2);

dula=1;

P0=di1;

dula=0;

P0=0xff;

wela=1;

P0=0xfd;

wela=0;

delay(2);//地址码

dula=1;

P0=gao;

dula=0;

P0=0xff;

wela=1;

P0=0x77;

wela=0;

delay(2);

dula=1;

P0=di;

dula=0;

P0=0xff;

wela=1;

P0=0x6f;

wela=0;

delay(2);//指令码

}

void main()

{

initial();//初始化

while(1)

{

if(overflag)//数据接收完毕

{

chulidata();//处理数据,完成标志dataover

overflag=0;

}

if(dataover)

{

display();//数码管显示

}

}

}

以上就是关于急求红外发射与解码的c程序全部的内容,包括:急求红外发射与解码的c程序、arduino红外遥控器编码错误、51单片机红外接收端的程序怎么写,我想知道写的方法和原理,最好有一个具体的模版,好让我参考.等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/10175303.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存