微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 51单片机:红外解码的程序,其中有几处不懂,求解

51单片机:红外解码的程序,其中有几处不懂,求解

时间:10-02 整理:3721RD 点击:
下面是红外解码的程序,其中有几处不懂,求大神解释。
/*******************************************************************************
*                 
*                          普中科技
--------------------------------------------------------------------------------
* 实 验 名   : 红外线试验
* 实验说明       : 数码管显示红外线发送过来的键值。
* 连接方式       : 见连接图
* 注    意   :
*******************************************************************************/
#include<reg51.h>
//--定义使用的IO--//
#define GPIO_DIG P0
sbit LSA  = P2^2;
sbit LSB  = P2^3;
sbit LSC  = P2^4;
sbit IRIN = P3^2;
//--定义全局变量--//
unsigned char code DIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char DisplayData[8]; //用来存放要显示的8位数的值
unsigned char IrValue[6];   //用来存放读取到的红外值
unsigned char Time;
//--声明全局函数--//
void DigDisplay(); //动态显示函数
void IrInit();
void DelayMs(unsigned int );
/*******************************************************************************
* 函数名         : main
* 函数功能     : 主函数
* 输入           : 无
* 输出           : 无
*******************************************************************************/
void main()
{
// unsigned char i;
IrInit();
while(1)
{
  IrValue[4]=IrValue[2]>>4;     //高位 ?什么意思?它的值是多少?
  IrValue[5]=IrValue[2]&0x0f;  //低位?
  DisplayData[0] = 0x00;
  DisplayData[1] = DIG_CODE[IrValue[4]];
  DisplayData[2] = DIG_CODE[IrValue[5]];
  DisplayData[3] = 0x76;   //01110110
  DisplayData[4] = 0x00;
  DisplayData[5] = DIG_CODE[IrValue[4]];
  DisplayData[6] = DIG_CODE[IrValue[5]];
  DisplayData[7] = 0x76;
  
  DigDisplay();
}
}         
/*******************************************************************************
* 函数名         : DelayMs()
* 函数功能     : 延时
* 输入           : x
* 输出           : 无
*******************************************************************************/
void DelayMs(unsigned int x)   //0.14ms误差 0us
{
unsigned char i;
while(x--)
{
  for (i = 0; i<13; i++)
  {}
}
}
/*******************************************************************************
* 函数名         : IrInit()
* 函数功能     : 初始化红外线接收
* 输入           : 无
* 输出           : 无
*******************************************************************************/
void IrInit()
{
IT0=1;//下降沿触发
EX0=1;//打开中断0允许
EA=1; //打开总中断
IRIN=1;//初始化端口
}
/*******************************************************************************
* 函数名         : ReadIr()
* 函数功能     : 读取红外数值的中断函数
* 输入           : 无
* 输出           : 无
*******************************************************************************/
void ReadIr() interrupt 0
{
unsigned char j,k;
unsigned int err;
Time=0;      
DelayMs(70);
if(IRIN==0)  //确认是否真的接收到正确的信号
{  
  
  err=1000;    //1000*10us=10ms,超过说明接收到错误的信号
  /*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
  侯,程序死在这里*/
  while((IRIN==0)&&(err>0)) //等待前面9ms的低电平过去   
  {   
   DelayMs(1);
   err--;
  }
  if(IRIN==1)   //如果正确等到9ms低电平
  {
   err=500;
   while((IRIN==1)&&(err>0))   //等待4.5ms的起始高电平过去
   {
    DelayMs(1);
    err--;
   }
   for(k=0;k<4;k++)  //共有4组数据
   {   
    for(j=0;j<8;j++) //接收一组数据
    {
     err=60;  
     while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
     {
      DelayMs(1);
      err--;
     }
     err=500;
     while((IRIN==1)&&(err>0))  //计算高电平的时间长度。
     {
      DelayMs(1);//0.14ms
      Time++;
      err--;
      if(Time>30)  //这是什么意思?
      {
       EX0=1;
       return; //这个怎么返回?是中断结束?
      }
     }
     IrValue[k]>>=1;  //k表示第几组数据//这个数组都没有赋初值,又怎么知道它的元素是多少,怎么移位?
     if(Time>=8)   //如果高电平出现大于565us,那么是1
     {
      IrValue[k]|=0x80;         //数组元素是多少都不知道,怎么进行运算?
     }
     Time=0;  //用完时间要重新赋值      
    }
   }
  }
  if(IrValue[2]!=~IrValue[3])
  {
   return;
  }
}   
}
/*******************************************************************************
* 函 数 名         : DigDisplay
* 函数功能     : 使用数码管显示
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void DigDisplay()
{
unsigned char i;
unsigned int j;
for(i=0;i<8;i++)
{
  switch(i)  //位选,选择点亮的数码管,
  {
   case(0):
    LSA=0;LSB=0;LSC=0; break;//显示第0位
   case(1):
    LSA=1;LSB=0;LSC=0; break;//显示第1位
   case(2):
    LSA=0;LSB=1;LSC=0; break;//显示第2位
   case(3):
    LSA=1;LSB=1;LSC=0; break;//显示第3位
   case(4):
    LSA=0;LSB=0;LSC=1; break;//显示第4位
   case(5):
    LSA=1;LSB=0;LSC=1; break;//显示第5位
   case(6):
    LSA=0;LSB=1;LSC=1; break;//显示第6位
   case(7):
    LSA=1;LSB=1;LSC=1; break;//显示第7位
  }
  GPIO_DIG=DisplayData;//发送段码
  j=10;       //扫描间隔时间设定
  while(j--);
  GPIO_DIG=0x00;//消隐
}
}

while((IRIN==1)&&(err>0))  //计算高电平的时间长度。
     {
       DelayMs(1);//0.14ms
       Time++;
       err--;
       if(Time>30)  //这是什么意思?  DelayMs(1);每循环一次,time加一,这里判断Time有没超过30次,即时间有没超过30*0.14ms
      {
        EX0=1;
        return; //这个怎么返回?是中断结束?退出一个循环,这里是while((IRIN==1)&&(err>0))  
      }
      }
      IrValue[k]>>=1;  //k表示第几组数据//这个数组都没有赋初值,又怎么知道它的元素是多少,怎么移位?           不用赋初值,因为要用的是通过移位后得到的值
     if(Time>=8)   //如果高电平出现大于565us,那么是1
      {
       IrValue[k]|=0x80;         //数组元素是多少都不知道,怎么进行运算?通过移位后进行或运算( | ),0x80 就是2进制 1000 000 , 或了之后第八位为1,其他7位保留来的数值
不能保证完全正确,只是自己的一些理解,希望能帮助你
     }

while((IRIN==1)&&(err>0))  //计算高电平的时间长度。
     {
       DelayMs(1);//0.14ms
       Time++;
       err--;
       if(Time>30)  //这是什么意思?  DelayMs(1);每循环一次,time加一,这里判断Time有没超过30次,即时间有没超过30*0.14ms
      {
        EX0=1;//为什么要写这个?
        return; //这个怎么返回?是中断结束?退出一个循环,这里是while((IRIN==1)&&(err>0))  
      }
      }
      IrValue[k]>>=1;  //k表示第几组数据//这个数组都没有赋初值,又怎么知道它的元素是多少,怎么移位?           不用赋初值,因为要用的是通过移位后得到的值//那它移位后是多少?
     if(Time>=8)   //如果高电平出现大于565us,那么是1
      {
       IrValue[k]|=0x80;         //数组元素是多少都不知道,怎么进行运算?通过移位后进行或运算( | ),0x80 就是2进制 1000 000 , 或了之后第八位为1,其他7位保留来的数值
不能保证完全正确,只是自己的一些理解,希望能帮助你
     }

while((IRIN==1)&&(err>0))  //计算高电平的时间长度。
     {
       DelayMs(1);//0.14ms
       Time++;
       err--;
       if(Time>30)  //这是什么意思?  DelayMs(1);每循环一次,time加一,这里判断Time有没超过30次,即时间有没超过30*0.14ms
      {
        EX0=1;//为什么要写这个?
        return; //这个怎么返回?是中断结束?退出一个循环,这里是while((IRIN==1)&&(err>0))  
      }
      }
      IrValue[k]>>=1;  //k表示第几组数据//这个数组都没有赋初值,又怎么知道它的元素是多少,怎么移位?           不用赋初值,因为要用的是通过移位后得到的值//那它移位后是多少?
     if(Time>=8)   //如果高电平出现大于565us,那么是1
      {
       IrValue[k]|=0x80;         //数组元素是多少都不知道,怎么进行运算?通过移位后进行或运算( | ),0x80 就是2进制 1000 000 , 或了之后第八位为1,其他7位保留来的数值
不能保证完全正确,只是自己的一些理解,希望能帮助你
     }

见识了                     

长见识了 ,不错,支持了

数组没有赋初值,初始化为0,移位后还是0. 2楼兄弟已经解释很明白了

对这样的程序不看好,居然在中断里面延迟这么长时间,要是us级的延迟还说得过去

请问一下,一般都有什么样的红外管

不知道。

挺不错的,真好

问题解决了吗啊

嗯。解决了。谢谢。

能给我讲讲这个函数里的主函数吗,我那里不明白

void main()
{
// unsigned char i;
IrInit(); //红外线初始化。
while(1)
{
  IrValue[4]=IrValue[2]>>4;    //高位 //这两行就类似于十进制数据个位十位的分解。
  IrValue[5]=IrValue[2]&0x0f; //低位
  DisplayData[0] = 0x00;   //下面就和用数码管显示一个两位数一样。
  DisplayData[1] = DIG_CODE[IrValue[4]];//IrValue[]数组中的元素是二进制,作为DIG_CODE[]数组的下标时会自动转换成十进制。
  DisplayData[2] = DIG_CODE[IrValue[5]];
  DisplayData[3] = 0x76;   //01110110
  DisplayData[4] = 0x00;
  DisplayData[5] = DIG_CODE[IrValue[4]];
  DisplayData[6] = DIG_CODE[IrValue[5]];
  DisplayData[7] = 0x76;
  
  DigDisplay();
}
}  
纯属个人理解,如有不对之处,请多多指教。

正在学习C语言这块,







  1. [color=Silver]需要语音元件的请联系我,(淘宝:科创达)[/color]

复制代码

看看看看看看看看看看看看看看看看看看

懂了不少,在学红外这块

请问一下,为什么下降沿进入中断后要延时9.8ms?延时完了9.8ms后,红外线数据前的9ms低电平不是过去了吗?而且因为是9.8ms过去了,这个时候应该进行到4.5ms的高电平了吧?那么第一个if(IRIN==0)应该是不成立了啊?然后就是为什么是1000*10us=10ms?DelayMS(1);不是应该是1*0.14ms=0.14ms=140us在加上执行err--;和while语句的时间乘1000吗?小编,这里怎么理解,小弟初学单片机不是太懂


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top