美文网首页
单片机小白学习之路(三十六)---红外遥控编码

单片机小白学习之路(三十六)---红外遥控编码

作者: 飞向深空 | 来源:发表于2018-10-14 17:04 被阅读0次

    目标:红外遥控编程

    、鉴别引导码、数据码和连发代码

    引导码为1个下降沿(负跳变)后13.5ms跟着第1位数据码下降沿;
    
    数据码根据发送的0和1不同,在1个下降沿之后1.125ms(数据0)或2.25ms(数据1)后是下1位数据下降沿;
    

    连发代码是在1个结束码下降沿后108ms之后产生;

    所有的判断都是基于下降沿(触发外部中断)开始到下一个下降沿之间的时间长短,这个时间是判断所有传输数据类型的唯一条件。

    2、数据位的读取:设定变量a和b,分别在计时器中断和外部中断中进行累加,在每1个下降沿触发外部中断都重置计时器累加变量(a=0),同时在计时器中断中判断a累加计时是否超过1.125ms,而小于2.25ms,如果有则对应序号为b的数据位=1;

    3、判断计时器中断中累加计时a,计时时间超过15ms(引导码时长13.5ms)表示错误或数据以及传输完,重置a和b;

    作者:zhb2004xp
    来源:CSDN
    原文:https://blog.csdn.net/zhb2004xp/article/details/80951011?utm_source=copy
    版权声明:本文为博主原创文章,转载请附上博文链接!

    #include <reg52.h>
    
    typedef unsigned int u16;
    typedef unsigned char u8;
    
    sbit LSA = P3^0;
    sbit LSB = P3^1;
    sbit LSC = P3^3;   //数码管位选
    
    sbit IRIN = P3^2; //数据输入/输出端口
    
    u8 IrValue[6];
    u8 Time;  //用于计数的间接数值
    
    u8 DisplayData[8];
    u8 code ShuzList[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
    0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X76};
       //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、H的显示码
    
    
    void delay(u16 i)  //延时函数,输入1相当于延时10us
    {
        while(i--);
    }
    
    
    void DigDisplay()  //数码管显示函数
    {
        u8 i;
        for(i=0;i<3;i++){
            switch(i){
                case(0): LSA = 0;LSB = 0;LSC = 0;break;
                case(1): LSA = 1;LSB = 0;LSC = 0;break;
                case(2): LSA = 0;LSB = 1;LSC = 0;break;
            }
            P0 = DisplayData[i]; //发送数据
            delay(100);//间隔一段时间扫描
            P0 = 0x00; //消隐
        }
    }
    
    
    void IrInit()   //初始化红外线接收
    {
        IT0 = 1;  //设置为下降沿触发
        EX0 = 1;  //打开外部中断0允许位
        EA = 1;   //开启总中断
    
        IRIN = 1; //初始化端口,这步可以省略
    }
    
    void main()
    {
        IrInit();
        while(1){
            DisplayData[0] = ShuzList[IrValue[2]/16];    //数据的高位
            DisplayData[1] = ShuzList[IrValue[2]%16];    //数据的低位
            DisplayData[2] = smgduan[16];
            DigDisplay();
        }
    }
    
    
    void ReadIr() interrupt 0
    {
        u8 j,k;
        u16 err;    //一个用于延时的间接数
        Time = 0;   
        delay(700);    //先延时7ms
    
        if(IRIN==0){
            err = 1000;    // 1000*10us= 10ms
            while((IRIN==0)&&(err>0)){  //只要这两个条件任意一个不满足就跳出循环
                delay(1);               //err是1000,进入1000此后此时又延时10ms,大于引导码低电平时间,说明传输失败
                err--;
            }
    
            if(IRIN==1){
                err=500;   //500*10us= 5ms
                while((IRIN==1)&&(err>0)) //延时大约5ms
                {
                    delay(1);
                    err--;
                }     //**此行上面是引导波形的设置**
    
                for(k=0;k<4;k++){   //4个字节
                    for(j=0;j<8;j++){  //每个字节8位
                         err = 60;
    
                         while((IRIN==0)&&(err>0)){ //低电平延时约560us
                            delay(1);
                            err--;
                         }
    
                         err=500; //500*100us= 50ms, 这里是随便弄得,计时判断关键是Time
                         while((IRIN==1)&&(err>0)){ //计算高电平的时间长度
                            delay(10); //延时100us
                            err--;
                            Time++;
    
                            if(Time>30){
                                return; //此时已经远远超过了判断时间,错误
                            }
                         }
    
                         IrValue[k]>>=1; //数据移位,由于数据是低位先传输所以是右移,k表示第几组数据
    
                         if(Time>8){   //如果高电平出现大于565us,那么是1
                            IrValue[k] |= 0x80;
                         }
                         Time = 0;   //用完时间要重新赋值
                    }
                }
                if(IrValue[2] != ~IrValue[3]){   //第2组数据(键数据码)不等于第3组(键数据补码)的取反那么信息错误
                    return;
                }   
            }
        }
    }
    
    

    步骤梳理:

    • 先延迟约7ms,判断输入(IRIN)是高低电平,如果此时还是低的话则延时判断如果超过10ms大于引导码的低电平时间则传输失败。发先 是高电平了再延时大约5ms。这是引导码的部分
    • 因为是4个字节,每个字节又是8位,所以用一个嵌套循环,for4里面嵌套for8,先延时个560us(560us是关键点,因为0和1的低电平都是560us,判断位是0,1的关键就是后面高电平的长度),这里需要借助一个中间量Time来判断高电平的长度,也就是Time每加1就相当于延时了100us。后面先进行移位,再判断Time大小,Time大于8相当于高电平已经持续了0.8ms,超过了数据0的高电平时间所以判断传输的是1。如果是0就不用往里面写了因为初始8位都是0.
    • 最后在嵌套循环外面判断一下第2组数据(键数据码)等不等于第3组(键数据补码)的取反。

    相关文章

      网友评论

          本文标题:单片机小白学习之路(三十六)---红外遥控编码

          本文链接:https://www.haomeiwen.com/subject/ilgzaftx.html