MCU裸机:一、315433MHzIR射频解码开发

MCU裸机:一、315433MHzIR射频解码开发,第1张

MCU裸机:一、315/433MHz/IR射频解码开发

Frist

文章目录
  • MCU裸机:一、315/433MHz/IR射频解码开发
  • MCU裸机开发大多基于其寄存器和一些外设信号处理的简易逻辑
  • 一、315/433MHz信号数据帧解读
  • 二、程序解码功能实现
    • 1.首先构造一个315/433MHz的解码结构体(方便后续的移植)
    • 2.解码逻辑函数编写
    • 3.应用层书写(这一层是看应用场景需求编写)
  • 总结


MCU裸机开发大多基于其寄存器和一些外设信号处理的简易逻辑

对于刚入行的我希望在博客上进行一些微处理器的开发,并将所学知识和技术以及方案进行记录总结,此篇内容将会介绍一些遥控无线模块如IR、RF433、RF315等信号基本处理。


一、315/433MHz信号数据帧解读

此例中使用WL531系列芯片作为315/433MHz的转码方案。

  1. 硬件电路如下:

  2. 逻辑分析仪抓取的波形如下:

    抓取 初始波形,可以看见是有很多乱序的杂波。(所以需要经过一定的处理)

提取完整两帧波形

放大分析得出转码波形的每一个数据bit都由一个周期的方波组成,频率为617.88Hz,定义抓取数据帧的每一个周期方波在占空比为25%(高电平时长为425us左右)时该bit=0;占空比为75%(高电平时长为1.63984ms左右)为bit=1。
红外:(NEC、RC-5协议)后续更新。

二、程序解码功能实现 1.首先构造一个315/433MHz的解码结构体(方便后续的移植)

将所需要的形参及硬件接口层进行声明和定义:

#define IR_Pin RC1 //硬件接口
typedef struct IRDecode  //解码逻辑层
{
    unsigned char LeadCode1;    //引导码(用于记忆和学习部分)
    unsigned char LeadCode2;
    unsigned char LeadCode3;
    unsigned char LeadCode4;
    unsigned char IRCode1Control;  //控制码(处理后最终编码)
    unsigned char IRCode2Control;
    unsigned char IRCode3Control;
    unsigned char IRCode4Control;
    unsigned char IRCode1Data;     //传递码(源数据帧流)
    unsigned char IRCode2Data;
    unsigned char IRCode3Data;
    unsigned char IRCode4Data;
    unsigned char IRCode1;  //采集码(原始数据解码运用)
    unsigned char IRCode2;
    unsigned char IRCode3;
    unsigned char IRCode4;
    unsigned char IRWaveCount; //连续发波计时
    unsigned char IRHighLevelCount;
    unsigned char IRLowLevelCount;  
    unsigned char IRHighLevelFlag : 1;
    unsigned char IRLowLevelFlag : 1;
    unsigned char IRCodeLength  : 6;
    unsigned char IRLearnableFlag : 1;
}IRDecode;
//应用层
typedef struct IRWorkData{  //数据帧事件处理
    unsigned char IRKeyState1 :1;
    unsigned char IRKeyState2 :1;
    unsigned char IRKeyState3 :1;
    unsigned char IRKeyState4 :2;
//    unsigned char IRKey1Transfer :1;
    unsigned char IRKey2Transfer :1;
    unsigned char IRKey3Transfer :1;
    unsigned char IRKey4Transfer :1;
    unsigned char IRKey4LongPressFlag :1;
    unsigned short int IRLongKey4Count;
}IRWorkData;
IRDecode IRDriver;
IRWorkData IRKeyHandle;
2.解码逻辑函数编写

利用125us定时器对数据入口的高低电平进行计数,计算出高低电平的时间转化为bit缓存起来,后续输出完整数据帧进行下一步工作:

//可更改或优化其中计数的阈值应用在其他协议上
//码值获取(循环调用us级)
void ScanGetIRCode(void){
    
    if(IR_Pin){
        IRDriver.IRHighLevelFlag=1;
        
        if(IRDriver.IRHighLevelCount<=250) IRDriver.IRHighLevelCount++;
        
//        //低电平时长超时滤波*16us=2ms,重新读值
//        if(IRDriver.IRHighLevelCount>=16){
//            IRDriver.IRCodeLength=0;
//        } 
          
        if(IRDriver.IRLowLevelFlag){  //上升沿
            IRDriver.IRLowLevelFlag=0;
            IRDriver.IRLowLevelCount=0;
            IRDriver.IRHighLevelCount=0;
        }
    }
    else{
        IRDriver.IRLowLevelFlag=1;
       
        if(IRDriver.IRHighLevelFlag){  //下降沿
            //高电平采样编码,下降沿处理
            if((IRDriver.IRHighLevelCount>1)&&(IRDriver.IRHighLevelCount<=11)){
                //码值1获取
                if(IRDriver.IRCodeLength<8){
                   IRDriver.IRCode1=IRDriver.IRCode1>>1;
                   if((IRDriver.IRHighLevelCount>=8)&&(IRDriver.IRHighLevelCount<=11)){
                       IRDriver.IRCode1|=0x80;
                   } 
                   else{
                       IRDriver.IRCode1&=0x7F;
                   }
                }
                //码值2获取
                else if(IRDriver.IRCodeLength<16){
                   IRDriver.IRCode2=IRDriver.IRCode2>>1;
                   if((IRDriver.IRHighLevelCount>=8)&&(IRDriver.IRHighLevelCount<=11)){
                       IRDriver.IRCode2|=0x80;
                   } 
                   else{
                       IRDriver.IRCode2&=0x7F;
                   }
                }
                //码值3获取
                else if(IRDriver.IRCodeLength<24){
                   IRDriver.IRCode3=IRDriver.IRCode3>>1;
                   if((IRDriver.IRHighLevelCount>=8)&&(IRDriver.IRHighLevelCount<=11)){
                       IRDriver.IRCode3|=0x80;
                   } 
                   else{
                       IRDriver.IRCode3&=0x7F;
                   }
                }
                //码值4获取
                else{
                   IRDriver.IRCode4=IRDriver.IRCode4>>1;
                   if((IRDriver.IRHighLevelCount>=8)&&(IRDriver.IRHighLevelCount<=11)){
                       IRDriver.IRCode4|=0x80;
                   } 
                   else{
                       IRDriver.IRCode4&=0x7F;
                   }
                }
                IRDriver.IRCodeLength++;
                //只处理32位数据
                if(IRDriver.IRCodeLength>=32){
                    IRDriver.IRCodeLength=0;
                    if((IRDriver.IRCode1==IRDriver.LeadCode1)){  //原始码
                        IRDriver.IRCode1Data=IRDriver.IRCode1;
                        IRDriver.IRCode2Data=IRDriver.IRCode2;
                        IRDriver.IRCode3Data=IRDriver.IRCode3;
                        IRDriver.IRCode4Data=IRDriver.IRCode4;
                        IRDriver.IRWaveCount=0;  //数据帧结束计时
                    }
                    //接收数据帧清零
                    IRDriver.IRCode1=0xFF;  //防止误判
                    IRDriver.IRCode2=0;
                    IRDriver.IRCode3=0;
                    IRDriver.IRCode4=0;
                }
            }
            else{
                IRDriver.IRCodeLength=0;  //高电平杂波滤除
            }
            IRDriver.IRHighLevelFlag=0;
            IRDriver.IRLowLevelCount=0;
            IRDriver.IRHighLevelCount=0;            
        }
        
        if(IRDriver.IRLowLevelCount<=250) IRDriver.IRLowLevelCount++;
         
        //低电平时长超时滤波*16us=2ms,重新读值
        if(IRDriver.IRLowLevelCount>=12){
            IRDriver.IRCodeLength=0;
        }
    }
}
3.应用层书写(这一层是看应用场景需求编写)

通过对数据帧间隔信号的获取,可以处理数据帧为波包的一种标志位跟随,即有数据帧发送到MCU时缓存可见有数据,反之缓存中的数据清零。(以追求实际 *** 作信号的同步):

//数据帧及连续发波处理(循环调用ms级)
void IRContinnuousWave(void){
    
    if(IRDriver.IRWaveCount<=254) IRDriver.IRWaveCount++;
    if(IRDriver.IRWaveCount>=36&&IRDriver.IRCode4Data!=0){ //72ms完整数据帧间隔时间
       //原始码数据帧清零
       IRDriver.IRCode1Data=0;
       IRDriver.IRCode2Data=0;
       IRDriver.IRCode3Data=0;
       IRDriver.IRCode4Data=0;
    }
}

总结

上述内容可以拓展到一些内似协议的解码和编码上面去,但是程序暂时并未进行面向对象的封装以及队列的优化,暴露了C/C++的编程功底不行,需要多练多学。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/707567.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-24
下一篇 2022-04-24

发表评论

登录后才能评论

评论列表(0条)

保存