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

;;

 论文摘要:本文介绍一款红外线遥控小车,以AT89S51单片机为核心控制器,用L289驱动直流电机工作,控制小车的运行。本款小车具有红外线遥控手动驾驶、自动驾驶、寻迹前进等功能。本系统采用模块化设计,软件用C语言编写。转贴于 51论 文网 >

#include<reg51h>

#include <intrinsh>

#define uchar unsigned char

#define uint unsigned int

#define ulong unsigned long

#define Nop() {_nop_(); _nop_(); _nop_(); _nop_(); _nop_();}

volatile ulong IRcode=0x00000000; //32位的键代码

volatile ulong Irdcode=0x00000000;

volatile uint customcode=0x0000; //16位用户码

volatile uint time_us=0x0000; //两个下降沿之间的时间

volatile uchar timeH,timeL; //保存TH1 TL的值

uchar Lcustomcode; //低8用户码

uchar Hcustomcode; //高8

uchar datacode; //8位键数据码

uchar mycode;

uchar Rdatacode; //8位键数据反码

uchar uc1ms;

uchar uc10ms;

uchar uc3ms;

uchar ucDispTime;

uchar ucDispOrder;

uchar ucDispCon;

uchar ucSpeakerTime;

unsigned char code LedData[16] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};

unsigned char code LedCon[2] = {0x8f,0x4f};

unsigned char ucDispData[2]; // 存放显示数据

sbit led1 = P3^7;

sbit led2 = P3^6;

sbit power=P1^0; //电源开关

sbit BEEP= P2^1;

bit NewIRcode=0; //指示当处理完了32位码后,就有了新的遥控码

bit DataRight=0; //为1时读取数据正确

bit bSampleOk;

bit bSampling;

bit b10msInt;

bit b1msInt;

bit bKeySound;

bit b1msMain;

bit IR_E; //表示有新的遥控键控下就更新扫描数据

bit b3msint;

void SendDataToDispDevice();

void Ir_process();

void display();

void beeping();

/ 晶振为12 MHZ/

/定时器1,12 MHZ最大定时为6553ms/

//------------------------------------------------------------------------------

void init()

{

IP=0x09; //定时器1,外部中断0优先级高

TMOD=0x11; //定时器0,工作方式1 ; 定时器1,工作方式1

TCON=0x01; //外中断0下降沿触发,(包括TR1=0,TR0=0)

TH0=0xff; //初始化定时器0,定时02ms

TL0=0x47;

TH1=0x00; //初始化定时器1

TL1=0x00;

EA=1; //开全中断

ET0=1; //开放T0中断

ET1=1; //开放T1中断

EX0=1; //开放INT0

TR1=0;

TR0=1;

}

//--------------------------------------

void TimeProg(void)

{

b1msMain = b1msInt;

b1msMain=0;

b10msInt = 0;

if(b1msInt == 1)

{

b1msMain=1;

if(++uc10ms == 10)

{

uc10ms = 0;

b10msInt = 1;

if(bKeySound==1)

{ beeping();

bKeySound=0;

}

}

}

}//void TimeProg(void)

//-------------------------------------interrupt0-------------------------------------

void IR_ISR() interrupt 0 using 1 //遥控器中断处理函数

{

static uchar cn;

TR1=0;

timeH=TH1;

timeL=TL1;

TH1=0;

TL1=0;

TR1=1; //开定时器中断1

time_us=(unsigned int)timeH;

time_us=time_us<<8;

time_us=time_us|timeL;

if(time_us>12200&&time_us<13000) {cn=1;IRcode=0;} //遇到引导码,就把cn清0,IRcode清0

//引导码的时间长度为9ms+45ms

if(cn<34)

{

if(time_us>950&&time_us<1120) //0

{

IRcode=IRcode|0x00000000;

if(cn<33) IRcode=IRcode>>1;

}

else if(time_us>1920&&time_us<2120) //1t > 1950 && t < 2150

{

IRcode=IRcode|0x80000000;

if(cn<33) IRcode=IRcode>>1;

}

//else if(time_us>10000&&time_us<11000) {Irdcode=IRcode;cn=34; } //遇到重复码

//cn用于记录接收到的数据位

}

cn++;

if(cn==34)

{ NewIRcode=1;

TR1=0;

Irdcode= IRcode; cn=0;

} //读完32位码,则有新码产生

}

//--------------------------------------timer_ISR------------------------------

void Timer0_ISR() interrupt 1 using 2 //定时器0中断函数

{

TR0=0;

TH0=0xff; //初始化定时器0,定时02ms 晶振为110592 MHZ

TL0=0x47;

TR0=1;

if(++uc1ms == 5)

{

uc1ms = 0;

b1msInt=1;

if(++uc3ms==8)

{

uc3ms=0;

b3msint=1;

SendDataToDispDevice(); //n ms送一次显示

}

}

}//void Timer0IntProg() interrupt 1 using 1

void Timer1_ISR() interrupt 3 using 3 //定时器1中断函数

{

TR1=0;

TH1=0x00; //初始化定时器1

TL1=0x00;

TR1=1;

}

//--------------------SendDataToDispDevice----------

void SendDataToDispDevice()

{

unsigned char n;

//watchdog();

if(++ucDispOrder >= 2) ucDispOrder = 0; // 下一显示巡回

// 下面为发送控制数据 位控

if(ucDispOrder==0)

{led1=0;

led2=1;

Nop();

Nop();

}

if(b3msint==1)

{if(ucDispOrder==1)

{led2=0;

led1=1;

Nop();

Nop();

}

}

// 下面为发送显示数据

n = LedData[ucDispData[ucDispOrder]];

P0=n;

} //void SendDataToDispDevice()

//------------------------------------main()----------------------------------------------

void main()

{

init();

beeping();

while(1)

{

TimeProg();

Ir_process();

display();

}

}

void Ir_process()

{

if(NewIRcode==1) //如果有新的遥控码就读

{

NewIRcode=0; //读完之后清零,表示新码已读

customcode=(Irdcode>>16); //取红外码中的按码键

//取低8位用户码

Lcustomcode=customcode>>8;//取低8位按码键

datacode=(unsigned char)(customcode&0x00ff); //取高8位按码键

Rdatacode=Lcustomcode; //取低8位按码键的反码

if(~Rdatacode!=datacode)

{ DataRight=0;

Irdcode=0;

datacode=Rdatacode=0;

} //校验用户码,反码

else

{ DataRight=1;

IR_E=1;

mycode=datacode;}

if(DataRight==1) { bKeySound = 1;DataRight=0; }

}

}

void display()

{

/ unsigned char a[2];

a[0] = mycode & 0x0f;

mycode = mycode >> 4;

a[1] = mycode & 0x0f;

ET0 = 0;

ucDispData[0] = a[0];

ucDispData[1] = a[1];

ET0 = 1;/

if(IR_E==1)

{

ET0 = 0;

ucDispData[0] = mycode & 0x0f;

mycode = mycode >> 4;

ucDispData[1] = mycode & 0x0f;

IR_E=0;

ET0 = 1;

}

}

//

void delay(unsigned char x) //x014MS

{

unsigned char a;

while(x--)

{

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

}

}

//

void beeping()

{

unsigned char i;

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

{

delay(4);

BEEP=!BEEP; //BEEP取反

}

BEEP=1;

//关闭蜂鸣器

}

以上就是关于51单片机红外接收端的程序怎么写,我想知道写的方法和原理,最好有一个具体的模版,好让我参考.全部的内容,包括:51单片机红外接收端的程序怎么写,我想知道写的方法和原理,最好有一个具体的模版,好让我参考.、51单片机的红外遥控小车设计和制作的C语言程序、求51单片机红外摇控接收c程序,并在数码管上显示键值出来等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存