您的位置:首页 > 其它

利用MCS-51系列单片机和0038模块实现红外线解码

2010-09-27 16:04 477 查看
本程序利用MCS51单片机实现了红外线解码,该程序我亲自测试过,实现了对电视机遥控板信号的解码。并应用上位机实现了对电脑鼠标的遥控。由于有一部分代码是汇编,一部分是C,所以需要在工程中进行设置,由于有很久了,我也忘记怎么设置了,本想上传整个工程文件的,结果好象在这里上传不了,需要的请留EMAIL,我发过去。否则可以自己在网上收一下C和汇编混合编程的设置。

/*************晶体为11.0592M,波特率9600bps
***************学习型红外线遥控程序*******/
#include <reg52.h>
#include "string.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char Command[10]; //用于接收从串口发来的命令,每个命令长度2字节 ///
unsigned char tmpCommand[10];//用于接收从串口发来的命令,在没有发送完一个命令时起临时记录作用 ///
unsigned int count = 0; //用于记录从串口接收发来的命令的字符串个数 ///
const unsigned int CommandLength = 2;
unsigned int readflag = 0;
///////////////////////////////////////////////////////////////////////////////////////////////////////

sbit P1_0 = P1^0;
sbit P1_1 = P1^1;
sbit P1_2 = P1^2;
sbit P1_3 = P1^3;
sbit P1_4 = P1^4;
sbit P1_5 = P1^5;
sbit P1_6 = P1^6;
sbit P1_7 = P1^7;

sbit P2_0 = P2^0;
sbit P2_1 = P2^1;
sbit P2_2 = P2^2;
sbit P2_3 = P2^3;
sbit P2_4 = P2^4;
sbit P2_5 = P2^5;
sbit P2_6 = P2^6;
sbit P2_7 = P2^7;

void Delay(void);
void Irda(void);

void Output(unsigned int h);
void Computs(unsigned char outdata[]);
void Comput(unsigned char outdata);

unsigned int Both(unsigned char data1,unsigned char data2);

unsigned char data Sys_Ma _at_ 0x1A;//分别存放红外线译码后的数据
unsigned char data Sys_FMa _at_ 0x1B;
unsigned char data User_Ma _at_ 0x1C;
unsigned char data User_FMa _at_ 0x1D;
sbit IrInput=P3^2; //红外线输入引脚,可自定义

/*******************红外线查询子程序*******************/
void Irda(void)
{
#pragma asm
MOV R6,#10
SB:
MOV R4,#19 ;延时880微秒
D1:
MOV R5,#19
DJNZ R5,$
DJNZ R4,D1

JB P3.2,EXIT ;延时882微秒后判断P3.2脚是为1
DJNZ R6, SB ;在8820微秒内如P3.2为1就退出
JNB P3.2, $ ;等待高电平避开9毫秒低电平引导脉冲

MOV R4,#10 ;延时4740微秒
D2: MOV R5,#218
DJNZ R5,$
DJNZ R4,D2
;延时4.74毫秒避开4.5毫秒的结果码

MOV R1,#1AH ;设定1AH为起始RAM区
MOV R2,#4 ;接收从1AH到1DH,用于存放操作码和操作反码
PP:
MOV R3,#8 ;每组数据为8位

SS:
JNB P3.2,$ ;等待地址码第一位的高电平信号
MOV R4,#19 ;延时880微秒
D5:
MOV R5,#19
DJNZ R5,$
DJNZ R4,D5
;高电平开始后882微秒判断信号的高低电平
MOV C,P3.2 ;将P3.2引脚此时的电平状态0或1存入C中
JNC TT ;如果为0就跳转到TT

MOV R4,#2 ;延时1000微秒
D6:MOV R5,#248
DJNZ R5,$
DJNZ R4,D6
;检测到高电平1的话延时1毫秒等待脉冲高电平结束
TT:
MOV A,@R1 ;将R1中地址的给A
RRC A ;将C中的值0或1移入A中的最低位
MOV @R1,A ;
DJNZ R3,SS ;接收满8位换一个内存
INC R1 ;对R1中的值加1,换下一个RAM
DJNZ R2,PP ;接收完所有数据
EXIT:
#pragma endasm
}

/*将两个单字节数装配成一个双字节数*/
unsigned int Both(unsigned char data1,unsigned char data2)
{
unsigned int dat;
dat|=data1;
dat<<=8;
dat|=data2;
return(dat);
}

/*外部中断0服务程序*/
void int0_int(void) interrupt 0
{

//红外接收中断服务函数
unsigned int h;
EX0=0; //关闭中断
Irda(); //红外译码
if((Sys_Ma==~Sys_FMa)&&(User_Ma==~User_FMa))//判断系统码与系统反码、
//用户码与用户反码是否正确
{ //校验正确
h=Both(Sys_FMa,User_FMa);//将系统反码(Sys_FMa),和用户反码(User_FMa)
//两个单字节数装配成一个双字节数
Comput(Sys_FMa); //串口输出系统反码遥控数据,可以用软件对电脑进行遥控
Comput(User_FMa);//串口输出用户反码遥控数据
Sys_FMa=User_FMa=0;//防止下一次误判断
}//退出if语句
EX0 = 1;//开中断

}//退出中断

/**********************串口输出字符串******************/
void Computs(unsigned char outdata[])
{
unsigned int i = 0;
for(i = 0 ; i < 10;i++)
{
Comput(outdata[i]);
}
}

/***********************串口输出**********************/
void Comput(unsigned char outdata)
{
SBUF = outdata;
while(!TI);
TI = 0;
}
/*****************延时程序**********************/

void Delay()
{
unsigned int i,j;
for(i=0;i<2;i++)
for(j=0;j<30000;j++);
}

//串口接收中断
void Serial_int(void) interrupt 4 using 1
{
unsigned char ch;
if(RI)
{
ch = SBUF;
ch = 0;
readflag = 1;

}
}

/*********************主程序***************************/

void main(void)
{

SCON = 0x50; //串口方式1,允许接收
TMOD = 0x20; //定时器1定时方式2
TH1 = 0xFD; //波特率9600
TL1 = 0xFD;
IT0 = 1; //INT0下降沿有效
EX0 = 1; //开INT0中断;
TR1 = 1; //启动定时器
P0 = 0xff;
P1 = 0xff;
P2 = 0xff;
P3 = 0xff;
EA = 1; //允许CPU中断

P1_0 = 0;

while(1)
{

}
}//主程序结束
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: