打印

红外通信键值不准确?

[复制链接]
1162|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
最近编写红外发射程序时发现了一个问题:
程序如下:
此时for循环里J,K的位置如图。
编译没有错误也没有警告,但是实际运行时数码管对应的键值却不是正常键值。比如1对应66,2也应66.,3对应6A,4对应A6。这些都不是正常键值。
通过修正发现,当for循环J,K位置互换是才能得到正确键值,正确结果如图:
我以为是U8  J,K;的问题。
但是即使图一情况下for循环J,K位置不变,改变为U8   K,J;仍然得不到正确结果。

有没有大神解释下?

相关帖子

沙发
gujiamao12345| | 2018-4-11 14:14 | 只看该作者
这...很难解释呀
要不你都把初始值加起来?

使用特权

评论回复
板凳
xyz549040622| | 2018-4-11 20:30 | 只看该作者
位置互换才能得到你认为的正确键值,只有两个可能
1.你程序的思路出了问题,互换就好了
2.你键值的解析出了问题

使用特权

评论回复
地板
airwill| | 2018-4-11 20:32 | 只看该作者
着应该又是个时序性问题, 可能出现的是初值问题

使用特权

评论回复
5
ljc424| | 2018-4-12 09:11 | 只看该作者
本帖最后由 ljc424 于 2018-4-12 09:16 编辑

我基本上做这样的不用delay延时,容易浪费CPU,定时时间也不太好控制

使用特权

评论回复
6
ljc424| | 2018-4-12 10:11 | 只看该作者
本帖最后由 ljc424 于 2018-4-12 10:13 编辑

我临时写了下解码程序,大体上应该没问题,没有调试过,你自己调试下
里面的时间宽度可以根据实际情况调整,时间宽度卡得越严,解码的成功率就越低,如果太宽就容易被干扰如果还有什么不明白的加我QQ:283442309
union _IrCntTypedef{
  u16 Word;
  strutc{
    u8 H;     //根据编译器注意高低位的顺序
    u8 L;
  }Byte;
};
u8 dIrScan = 0;
u8 dIrNum;
u8 fIrOk;
u32 uIrData;
union _IrCntTypedef uIrCnt;
void ReadIr() interrupt 0   //中断定时50us
{
  switch(dIrScan)
  {
    default:
    case 0: //等待低电平
      if((0 == fIrOk)(0 == IRIN))
      {
        dIrScan = 1;
      }
    case 1: //等待高电平
      if(1 == IRIN)
      {
        dIrScan++;
        uIrCnt.Word = 0;
      }
      break;
    case 2: //解头码9ms高电平
      if(1 == IRIN)
      {
        if(++uIrCnt.Word >= (15*20))  //高电平时间不能大于15ms否则解码错误
        {
          dIrScan = 0;
        }
      }
      else
      {
        if(uIrCnt.Word >= (5*20))   //高电平宽度在5-15ms内认为有效
        {
          dIrScan++;
          uIrCnt.Byte.L = 100;      //100*50us=5ms
        }
        else
        {
          dIrScan = 0;
        }
      }
      break;
    case 3: //解头码2.25ms低电平
      if(0 == IRIN)
      {
        if(--uIrCnt.Byte.L == 0)  //低电平时间不能大于5ms否则解码错误
        {
          dIrScan = 0;
        }
      }
      else
      {
        if(uIrCnt.Byte.L > 20)    //低电平宽度在1ms-5ms内认为有效
        {
          dIrScan++;
          uIrCnt.Byte.L = 0;
          dIrNum = 32;            //解32位数据
          uIrData = 0;
        }
        else
        {
          dIrScan = 0;
        }
      }
      break;
    case 4: //解数据码高电平
      if(1 == IRIN)
      {
        if(++uIrCnt.Byte.L == 0)
        {
          //高电平解码错误
          dIrScan = 0;
        }
      }
      else
      {
        if((uIrCnt.Byte.L < 4) || (uIrCnt.Byte.L > 16))
        {
          //数据位的高电平小于200us或者大于800us认为解码错误
          dIrScan = 0;
        }
        else
        {
          dIrScan++;
          uIrCnt.Byte.L = 0;
        }
      }
      break;
      case 5: //解数据码低电平
      if(0 == IRIN)
      {
        if(++uIrCnt.Byte.L == 0)
        {
          //低电平解码错误
          dIrScan = 0;
        }
      }
      else
      {
        if((uIrCnt.Byte.L < 4) || (uIrCnt.Byte.L > 45))
        {
          //数据位的高电平小于200us或者大于2.25ms认为解码错误
          dIrScan = 0;
        }
        else
        {
          uIrData <<= 1;
          if(uIrCnt.Byte.L >= 22)
          {
            //如果低电平宽度大于1.1ms认为数据发送的是‘1’
            uIrData |= 1;
          }
          if(--dIrNum == 0)
          {
            dIrScan--;  //数据没有解码完毕,解下一个数据
          }
          else
          {
            //数据解码成功
            fIrOk = 1;
            dIrScan = 0;
          }
        }
      }
      break;
  }
}

使用特权

评论回复
7
dirtwillfly| | 2018-4-14 19:07 | 只看该作者
建议用逻辑分析仪观察一下时许吧。看看你要接收的键值的时序是怎么样的,然后对照时序写识别代码

使用特权

评论回复
8
零三翟邢止胃| | 2019-3-29 10:43 | 只看该作者
我基本上做这样的不用delay延时,容易浪费CPU,定时时间也不太好控制

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

39

帖子

1

粉丝