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

来源:互联网 发布:部落冲突怎么恢复数据 编辑:程序博客网 时间:2024/09/21 09:07

本程序利用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)
 {
 
  

  
 }
  }//主程序结束