专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

单片机红外遥控解码HS0038B用1602液晶显示

作者:wangyin   来源:本站原创   点击数:  更新时间:2013年07月07日   【字体:

一个红外遥控接收头解码的列子 试验成功,51单片机+1602液晶显示,完整的源码下载地址是:http://www.51hei.com/bbs/dpj-19538-1.html 下面给出主要程序的预览:
/**************************************************
*程序名称: HS0038B红外遥控键值显示      
*晶    振: 11.0592MHZ             
*作    者: Kevin.Xie  
*时    间: 2009\4\04   
*地    址: 51hei 
***************************************************/
/*            HS0038B 知识点补充:            
out脚在没有接收到红外时输出高电平,接收到则输出低电平。

红外发射的编码中,数据“0”和“1”是这样定义的:
  高电平0.565ms,低电平0.56ms,周期1.125ms,表数据“0”;
  高电平0.565ms,低电平1.685ms,周期2.25ms,表数据“1”;
***************************************************/
#include <reg52.h>
#include <intrins.h>
#include "lcd1602.h"


sbit IR_GET = P3^2;        //红外接收头数据输入端
uchar hdata=0x10,ldata=0x10;     //分别存放显示的红外编码的高四位和低四位。
uchar  RXDDATA[]={0x00,0x00,0x00,0x00};//存放接收到的四组红外编码


/************************************************************
      约0.1ms延时函数
*************************************************************/
void delay(uchar x)  
{
 unsigned char i;
 while(x--)
 {
  for (i = 0; i<10; i++);
 }
}

/************************************************************
      主函数
*************************************************************/
void main(void)
{
 EA= 1;      //允许总中断中断,
 EX0= 1;  //使能 INT0 外部中断
 IT0 =1;      //外中断0下降沿触发
 IR_GET=1;         //I/O口初始化
 display_1602();

 while(1) 
 {
  hangwei(1,7);
  if(ldata<0x09)
   wdat_1602(ldata+0x30);
  else
   wdat_1602(ldata+0x40);
  if(hdata<0x09)
   wdat_1602(hdata+0x30);
  else
   wdat_1602(hdata+0x40);
  wdat_1602('H');  //H
 }
}
/************************************************************
      外部中断0服务函数
*************************************************************/
void intt_0() interrupt 0 //下降沿触发:接收不到红外时OUT高电平,接收到红外时OUT低电平。
{
 uchar four,one,num=0;
 EX0 = 0;   //关中断0使能,防止处理过程中再接收红外信号
 delayms(2);   //稍延时2ms,防干扰
 if (IR_GET) //再检测红外接收脚(9ms的前导低电平),为高电平说明是干扰
 {
  EX0 =1;  //使能中断0
  return;  //退出中断程序
 }
 while(!IR_GET);     //等IR变为高电平,跳过9ms的前导低电平信号。
 while (IR_GET);    //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
 for (four=0;four<4;four++)  //四组数据
 {
  for (one=0;one<8;one++)   //每组数据8位
  {
   while (!IR_GET);  //等 IR 变为高电平
   while (IR_GET)    //计算IR高电平时长(低电平时长是一样的,不用计)
   {
    delay(1);  //计时
    num++;      //计时N次    
    if (num>=20) //20*0.1ms=2ms
    {   //数据“1”的时长最长也就1.685ms,计数超过则数据错误,退出中断
     EX0=1; //使能中断0
     return; //退出中断
    }                 
   }    //高电平计数完毕    
   RXDDATA[four]>>=1;   //从低位读出,随着one的循环8次刚好读出一字节
   if(num>6&&num<20)  // 20*0.1ms=2ms>1.685ms
    RXDDATA[four]|=0x80;  //数据“1”
   num=0; //计时值清0,为下一位数据的计时做准备
  }//一组数据接收结束
 }//全部四组数据接收结束
 if (RXDDATA[2]!=~RXDDATA[3])  //检测接收到的数据是否正确
 {      //不正确则
  EX0=1;    //使能中断0
  return;   //退出中断
 }
 ldata=RXDDATA[2]&0x0F;   //取键码的低四位
 hdata=RXDDATA[2]>>4;     //取键码的高四位
 EX0 = 1;  //处理完红外接收,使能中断0,退出中断0
}

关闭窗口

相关文章