小米红外遥控器如何适配到其他应用设备之上

news/2024/11/24 4:56:39/

                        小米红外遥控器如何适配到其他应用设备之上

 

       最近合作方公司需要匹配小米最新款的红外遥控器到一款电暖设备上,鬼知道为何要使用一个明显的TV遥控器去控制电暖器。不过这都无所谓,客户是衣食父母嘛,尽管他们有的时候会想孩子一样胡闹......所以首先我去了解了一下小米的红外传输协议,很不幸,它并不是传统的NEC或者类NEC,当然我早已经有了心理准备的,毕竟MI这样的一家科技公司怎么可能去使用人尽可驭的NEC呢,那样一点都不酷,不会用NEC的,这辈子都不会用。

 

       言归正传。我们先来看看MI的红外传输协议:

     下面进行分析,首先一段时间的低电平信号和一段时间的高电平信号表示一位,所以从左向右一直到Stop bit结束这是一帧信号,一共12位,如图依次是 Start bit,2,0,1,2,0,0,3,3,0,1,Stop bit.  每一位的脉冲宽度是这样定义的:

此图仅作为参考,不同厂家可能有细微的出入,所以我的工作就是根据接收到的脉冲宽度来区分0,1,2,3的对应关系达成解码的最终目的。下面我们看一下每一个按键对应的键码值:

3CCC 
   
 8605 
860B860D860C
 8606 
   
860886078604
   
 860E 
 860F 

 

       让我们回到MiBox协议格式那张图,可以看到该图对应的键码为0x860F,也就是最下面的那个按键。在这里有些小伙伴可能会疑惑0x860F是什么呢?其实MiBox协议进行了两次数据转换,如果没有接触过就会迷惑我们。首先我们知道根据脉冲宽度MiBox协议为只有0,1,2,3,这属于四进制吧,我们使用两位二进制就可以完整表示。那么正是如此:

我们将数据位排列对比一下,

    2       0       1       2       0       0       3       3       0       1                       这一行相当于四进制的表示                                                     10     00     01     10     00     00     11     11     00      01                    这是转换后的二进制表示,最后我们四位合成一个16进制数 

        8                 6                0                F               1

这下小伙伴们应该就明白了,至于后面的1我们就忽略掉,毕竟我们只需要判断前四位就可以区分键值了,没必要增加额外的工作量。

       那么最后我们要如何写程序呢?这里我分享一下我的代码,算是抛砖引玉了,有什么不合理的地方也请大家指正。

首先我们需要忽略掉Start bit位,然后将后面的8位数据位依次接收并存储到数组,但是有一个问题,似乎Start bit位和后面的数据位的脉冲宽度的界限很难区分。我们需要做一个处理,索性我们就丢掉第一帧,从第二帧开始接收并使用前一帧的Stop bit位做为判断是否开始接收的标志,幸运的是Mibox正是一种循环发送机制,长按会不停发送同一组码值。那么可以得出数组长度即为10

**上代码(避免误导小伙伴,这里仅贴出跟红外接收相关的代码,如有疑问,请在评论区留言咨询。)

volatile  uint16_t  ir_data = 0;

uint8_t     irdata_num=0,mcsj=0;
unsigned char  xdata  sj[10] = {0}; //脉冲时长数组
bit   self_lock_flag = 0;                  //红外接收标志位  

void T1_init(void) //100us中断一次
{
        TIMER1_MODE2_ENABLE;
        CKCON &= (~b4_msk);
        TH1=0xA4;
        TL1=0xA4;
        ET1=1;
        TR1=1;
}

void  T1_ISR(void) interrupt 3
{
        mcsj++; //脉冲时间计数
}

void  INT1_ISR(void) interrupt 2/*下降沿中断*/
{
       // if(error_be_found)
      //  {
                        if(mcsj>50) //判断是不是引导码
                        {
                                self_lock_flag = 1;
                                irdata_num=0;    
                        }
                        if(self_lock_flag)
                        {
                                sj[irdata_num]=mcsj; //脉冲时间存入数组
                                mcsj=0; //清空这一数据,准备接收下一个数据
                                irdata_num++; 
                                if(irdata_num==10) //判断是否接收完
                                {
                                        self_lock_flag = 0;
                                        JS = 1; //接收完成标志位
                                        MC=0;   //红外脉冲结束
                                        irdata_num=0;
                                        TR1=0;
                                }                                
                        }        
                        mcsj=0;                
        //}
}

        /**红外管脚电平检测,每1ms检测一次**/
        if(0==IR_input)
        {
                key_lock_10=0;
                key_count_10=0;
        }
        else if(0==key_lock_10)
        {
                key_count_10++;
                if(key_count_10>=19)
                {
                        TR1=1;
                }
        }

void  hwjm(void)
{
        uint8_t  k;
        uint8_t  value = 0;
        for(k=2;k<10;k++)
        {
                if(sj[k]<13)
                {
                        ir_data<<=2;
                        ir_data+=0x00;                    
                }
                else if(sj[k]>13&&sj[k]<16)
                {
                        ir_data<<=2;
                        ir_data+=0x01;                    
                }
                else if(sj[k]>16&&sj[k]<19)
                {
                        ir_data<<=2;
                        ir_data+=0x02;                    
                }
                else if(sj[k]>19)
                {
                        ir_data<<=2;
                        ir_data+=0x03;                    
                }
        }
        JS=0;
        JM=1;
}

        让我们来梳理一下,首先定义T1来捕捉脉冲宽度,每100us中断一次并且mscj++,接着判断该脉冲宽度的范围,这里采用50,如果到达停止位则开始接收,依次将mscj的值存放的数组内。最后hwjm()根据脉冲宽度来进行解码。

       通常按键都会发送多帧数据,在某些场合我们需要屏蔽这些重复的数据,所以如程序所示,在接收完成第一个10位数据之后关闭的T1定时器,那么何时打开呢?这里我采用了循环检测红外引脚的电平状态,如果按键一直处于被按下的状态,那么IR的电平就一直在变化,除非松开了按键才会保持一种状态,此时即可以打开T1定时器。

 

 

 


http://www.ppmy.cn/news/777858.html

相关文章

鸿蒙系统小米手机,华为鸿蒙系统已经发布,小米等国产手机会使用鸿蒙系统吗?...

原标题&#xff1a;华为鸿蒙系统已经发布&#xff0c;小米等国产手机会使用鸿蒙系统吗&#xff1f; “极客谈科技”&#xff0c;全新视角、全新思路&#xff0c;伴你遨游神奇的科技世界。 鸿蒙系统已于华为全球开发者大会正式发布&#xff0c;荣耀智慧屏将会率先使用鸿蒙系统。…

在VMware上安装Android虚拟机

安装 参考&#xff1a;Installing Android on VMware ESXi:A How-To Guide 简单说一下&#xff0c;安装步骤跟着上面走就完事了&#xff0c;主要是在安装成功后需要进行一个GRUB的修改&#xff0c;步骤如下&#xff1a; 进入系统后&#xff0c;打开虚拟终端&#xff0c;按下面…

199999的小米新车,你会买吗?

关于小米造车的消息都在这里了。 1 小米造车疑云 做为一个小米的mini版股东&#xff0c;我一直都很关注小米的发展&#xff0c;积极了解小米都搞了哪些事情&#xff0c;以及雷军都在忙啥。 家里也买了很多小米的产品&#xff0c;客观来讲&#xff0c;并不是每一个产品都那么好&…

B站小米商城自己写的原码

我上传到gitee上了&#xff0c;链接&#xff1a;hhp/mimiSSM 项目大概介绍&#xff1a; 全局变量&#xff1a;监听器&#xff1a;“typeList” &#xff1a;手机&#xff0c;电脑&#xff0c;电视1&#xff0c;点击“商品管理”&#xff0c;前端访问&#xff1a;http://localh…

win10无线投屏_WIN10笔记本投屏小米电视

WIN10笔记本投屏小米电视 国庆假日小编在家无聊的时候想把WIN10笔记本投屏到自家的小米电视上,在小米电视支持无线Miracast的时候,依然不成功。经过长达半个小时的调试终于弄好了!太麻烦有木有,今天小编就教大家怎么利用无线投屏器,让WIN10笔记本快速投屏到小米电视上。 利…

小米电视01

1、20180207 立即与米兔交流 Hello&#xff0c;我是机器人米兔。您是否要咨询以下问题呢&#xff1f;如果不是&#xff0c;请直接输入问题哦~ Q1. 我的商品何时到货&#xff1f; Q2. 如何取消和修改订单&#xff1f; Q3. 如何在小米网申请退货、换货、维修&#xff1f; Q4.…

小米电视 “无法访问,请检查网络链接是否正常“

小米电视 ”无法访问&#xff0c;请检查网络链接是否正常“ 别的设备都能连接 samba 访问 Linux 下的共享文件夹&#xff0c;而就小米电视不行。 经查是因为小米电视只支持老旧的 SMB1.0 &#xff0c;现在新下载的 samba 服务都已经默认关掉了这项服务。 解决办法如下&#xf…

Android电视清理系统应用,【教程】无需root!卸载小米电视/盒子内置应用竟如此简单...

你曾经被小米电视/小米盒子冗余的内置应用烦恼过吗?作为一名小米电视的用户,讲真,小米电视内置的应用着实有亿点多,就像小米商城、游戏中心和用户手册等等这些自带应用,我想绝大多数人也应该和我一样几乎从来没有用到过吧。 在智能电视以4GB和8GB存储空间为主流的今天,冗…