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

2019-07-15 18:43发布

下面是红外解码的程序,其中有几处不懂,求大神解释。。。。
/*******************************************************************************
*                 
*                          普中科技
--------------------------------------------------------------------------------
* 实 验 名   : 红外线试验
* 实验说明       : 数码管显示红外线发送过来的键值。
* 连接方式       : 见连接图
* 注    意   :
*******************************************************************************/
#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;//消隐
}
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
19条回答
蒙奇路飞
2019-07-15 21:13
linjiashengl 发表于 2014-8-24 21:27
while((IRIN==1)&&(err>0))  //计算高电平的时间长度。
     {
       DelayMs(1);//0.14ms

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位保留来的数值

不能保证完全正确,只是自己的一些理解,希望能帮助你
     }

一周热门 更多>