51单片机红外接收端的程序怎么写,我想知道写的方法和原理,最好有一个具体的模版,好让我参考.

51单片机红外接收端的程序怎么写,我想知道写的方法和原理,最好有一个具体的模版,好让我参考.,第1张

这是采用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

;;

进入程序设定模式

关闭所有车门系上安全带,并确定警告铃声在程序设定期间未发出声音,在六秒之内将点火开关从位置I转到位置II四次,按下遥控器任何一个按钮并按住不放直到出现一声铃响。

福特蒙迪欧作为长安福特科技含量最高、制造工艺最精良的旗舰车型,不仅搭载多项创新科技,并在至臻品质、动力系统以及安全性能等方面实现全面提升。

这是我以前写的红外遥控器。。。你看看,有帮助的

#include <AT89X51h>

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 = 0xE6; //设定时值0为38K 也就是每隔26us中断一次

TR0 = 1;//开始计数

iraddr1=3;

iraddr2=252;

do{

delay();

SendIRdata(12);

}while(1);

}

//定时器0中断处理

void

timeint(void) interrupt

1

{

TH0=0xFF;

TL0=0xE6; //设定时值为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<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

{

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;

}

endcount=10;

flag=1;

count=0;

do{}while(count<endcount);

flag=0;

}

void delay()

{

int i,j;

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

{

for(j=0;j<100;j++)

{

}

}

}

#include<reg52h>

#include<intrinsh>

#define uchar unsigned char

#define uint unsigned int

sbit lcden = P2^7;

sbit lcdrs = P2^6;

sbit lcdwr = P2^5;

sbit IR = P3^2;

uchar IRCOM[6];//数组,用于存储红外编码

uchar code table1[] = "remote control";

uchar code table2[] = "CODE:";

void delayms(uchar x)// 延时x014ms

{

uchar i;

while(x--)

for(i=0;i<13;i++){}

}

void delay(uchar x) //延时xms

{

uchar i,j;

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

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

}

/LCD部分/

void write_com(uchar com)

{

lcden = 0;

lcdrs = 0;

lcdwr = 0;

P0 = com;

delay(5);

lcden = 1;

delay(5);

lcden = 0; //别忘了lcden拉低

}

void write_date(uchar date)

{

lcden = 0;

lcdrs = 1;

lcdwr = 0;

P0 = date;

delay(5);

lcden = 1;

delay(5);

lcden = 0;

}

void lcd_init(void)

{

lcden = 0;

lcdrs = 0;

lcdwr = 0;

delay(5);

write_com(0x38);

write_com(0x0c);

write_com(0x06);

write_com(0x01);

}

/main()/

void main(void)

{

uchar count=0;

IR = 1;

lcd_init();

write_com(0x80);

while(table1[count]!='\0')

{

write_date(table1[count]);

count++;

delay(5);

}

count = 0;

write_com(0x80+0x40);

while(table2[count]!='\0')

{

write_date(table2[count]);

count++;

delay(5);

}

IE = 0x81; //开中断

TCON = 0x01;//脉冲负边沿触发

while(1);

}

/红外中断/

void IR_time() interrupt 0

{

uchar i,j,TimeNum=0;//TimeNum用来计IR高电平次数 从而判断是0还是1

EX0 = 0; //关闭中断

delayms(5);

if(1 == IR)

{

EX0 = 1;

return;

}

while(!IR) //跳过9ms前导低电平

delayms(1);

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

{

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

{

while(IR) //跳过45ms的前导高电平

delayms(1);

while(!IR) //跳过056ms的低电平

delayms(1);

while(IR)

{

TimeNum++; //计时高电平时间从而判断读取的是0还是1

delayms(1);

}

if(TimeNum>=30)//按键按下时间过长 跳过

{

EX0 = 1;

return;

}

IRCOM[i] = IRCOM[i]>>1;

if(TimeNum >= 8) //8014ms 这时读取的是1;

{

IRCOM[i] = IRCOM[i]|0x80;

}

TimeNum = 0;

}

}

if(IRCOM[2]!=~IRCOM[3])//判断八位数据和八位数据反码是否相等

{

EX0 = 1;

return;

}

IRCOM[4] = IRCOM[2]&0x0f;//取低四位

IRCOM[5] = IRCOM[2]>>4; //IRCOM[5]取IRCOM[2]高四位

if(IRCOM[4] > 9) //转换成字符

{

IRCOM[4] = IRCOM[4] + 0x37;

}

else

IRCOM[4] = IRCOM[4] + 0x30;

if(IRCOM[5] > 9)

{

IRCOM[5] = IRCOM[5] + 0x37;

}

else

IRCOM[5] = IRCOM[5] + 0x30;

delay(5);

write_com(0x80 + 0x40 + 5);

write_date(IRCOM[5]);

write_date(IRCOM[4]);

EX0 = 1; //重新开启外部中断

}

要看看你无线遥控器是走的那种信号,例如电视红外遥控器就买个红外遥控器的转串口的转换器,接到PLC的RS232或者RS485上,然后通过PLC的接收功能块跟遥控器通信。

如果能提供遥控器协议就简单,不能提供也可以通过转换器直接接到电脑RS232上监控遥控的发送数据。

目前常用的免费无线有无线433。

收费的有通过手机GPRS或者3G信号到PLC,配个GPRS DTU,3G路由器,4G路由器等。

例如:矩形N80的PLC有RCV接收功能块,支持RS232也支持RS485串口。

以上就是关于51单片机红外接收端的程序怎么写,我想知道写的方法和原理,最好有一个具体的模版,好让我参考.全部的内容,包括:51单片机红外接收端的程序怎么写,我想知道写的方法和原理,最好有一个具体的模版,好让我参考.、07蒙迪欧遥控接收器怎样检测、求一个简单的单片机红外遥控控制led灯的收发程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/10092030.html

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

发表评论

登录后才能评论

评论列表(0条)

保存