打印
[MCU]

315/433无线模块解码

[复制链接]
551|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 119163wzj 于 2020-8-5 16:28 编辑

315/433无线模块解码

       上图是接收模块接收到的发送模块按键一次发来的信息波形,可以分为5个阶段来分析,分别是:1、开始无接收信号,输出的是杂波;2、引导码;3、键码;4、相同连续的引导码和键码,如果长按发送会一直输出这样的波形;5、松开发送键,接收输出一个比较明显的结束码;

      接收模块在无信号状态下接收引脚是不断输出杂波,在接到信号时,才会输出信息码,所以写程序的难点在解码。

      网上找不到比较好的方案,这里是有类似的讨论:http://www.amobbs.com/thread-959411-1-1.html

      像在程序中延时解码的方式,如果其他程序需要快速的循环执行的话,会有影响,再有就是移植性不高。

      我们可以设定一个较快的定时中断(下面设定24us),然后在中调用接收解码函数,每次中断只判断相应的标志,不会造成中断执行时间过长的问题。

      比如其中一对收发模块,同步码为10ms低电平,之后是25位数据,只取24位3个字节,"1"是1.1ms高+0.2ms低, "0"是0.45高+0.9低,所以可以只通过高电平判断,下面是具体的程序,需要注意的是各回调函数中不能执行太久,最好是设置标志就好了:

/******************H头文件*********************************/ #ifndef RF433MDecode_H_ #define RF433MDecode_H_ /***************************************************/ //Define I/O Register #define PORT_RF_REC     pa #define P_RF_REC         pa.7 #define PC_RF_REC         pac.7 #define PPH_RF_REC     paph.7   //**************************************************// //Define Constant //24us定时中断中调用433M接收解码函数   //同步码,10ms低电平 #define C_RF_START_L_MAX        500        //12MS //10MS--10000/24=416 #define C_RF_START_L_MIN     250       //6MS   //之后是25位数据,只取243个字节 #define C_RF_REC_BIT_LEN    24    //"1"1.1ms+0.2ms,"0"0.45+0.9 //所以可以只通过高电平判断 #define C_RF_DATA1_MAX        54        //1.3ms #define C_RF_DATA1_MIN        37        //0.9ms #define C_RF_DATA0_MAX        25        //0.6ms #define C_RF_DATA0_MIN        13        //0.3ms   //结束码,短按:130ms低电平,长按:500ms,这里取大于70ms //#define C_RF_END_L_MAX        500        //140MS #define C_RF_END_L_MIN     2916       //70MS     #define C_RF_DATA_CLENT_1     0xAD       //客户码1 #define C_RF_DATA_CLENT_2     0x2F       //客户码2 #define C_RF_DATA_1_KEY          0x01        //A键值 #define C_RF_DATA_2_KEY     0x02       //B键值 #define C_RF_DATA_3_KEY     0x04       //C键值 #define C_RF_DATA_4_KEY     0x08       //D键值   #define C_DELAY_KEY_PRESS_SHORT        500        //1000*1MS #define C_DELAY_KEY_PRESS_LONG        2000   //3000*1MS /****************************************************/ // Define General Register   //************************************************** //Define FUNCTION void RF433M_Init(void); void RF433M_RecevieDecode(void);   #endif /******************C文件*********************************/ //*************************************************** //CUSTOMER: //OBJECT:433M解码程序 //AUTHOR:TJY //DESCRIPTION: //        24us定时中断中调用433M接收解码函数 /************************************************************************* /*************************************************************************/ #include    "extern.h" #include    "Rf433MDecode.h"   byte   gb_RfRxStep;                //IR接收步骤 word   gw_RfRxCnt;                //接收计数器   eword   gew_RfRxData;            //接收数据暂存,//同步码之后是25位数据,只取243个字节 byte   gb_RfRxData1;                //接收数据--//客户代码1 byte   gb_RfRxData2;                //客户代码2 byte   gb_RfRxData3;                //数据码     byte   gb_RfRxLevel; byte   gb_RfRxBitCnt;                //接收数据位 bit    gbit_RfRecOkFlag;            //收到完整的24位数据置1,相当于g_bitKeyDownFlag bit    gbit_RfRecEndCodeFlag;        //收到结束码 byte g_bTimerCount word   gw_RfRxKeeppingMsCnt;        //接收第一个数据后开始的计数器 word   gw_RfRxKeeppingIntervalCount;   bit       gbit_ResetFlag; /*************************************************** 接收初始化函数 ***************************************************/ void RF433M_Init(void) {     $P_RF_REC     High;     $P_RF_REC     In, NoPull;        //设置为输入模式      gb_RfRxStep = 0;    gbit_RfRecOkFlag = 0;    gbit_RfRecEndCodeFlag = 0; bTimerCount = 0; }       /*************************************************** 第一次收到完整的24位数据的回调函数 相当于按键按下调用函数 -- OnkeyDown() 只在开始的时候进一次 ***************************************************/ void RF433M_OnRecevieFirstData(void) {    gw_RfRxKeeppingMsCnt = 0; }   /*************************************************** 收到完整的24位数据后的回调函数 相当于按键按下调用函数 -- OnkeyPressing() 在按下期间,会不断进入 ***************************************************/ void RF433M_OnRecevieData(void) {     if(gw_RfRxKeeppingMsCnt >=C_DELAY_KEY_PRESS_LONG)     {         //长按         if(gb_RfRxData3 == C_RF_DATA_1_KEY)         {                              }     } }   /*************************************************** 收到24位数据后,再接收到结束码的回调函数 相当于按键按下松开时调用函数 -- OnkeyUp() ***************************************************/ void RF433M_OnRecevieEndCode(void) {       if(gw_RfRxKeeppingMsCnt <= C_DELAY_KEY_PRESS_SHORT)     {         //短按         switch(gb_RfRxData3)         {            case C_RF_DATA_1_KEY:            {                break;            }            case C_RF_DATA_2_KEY:             {                break;            }            case C_RF_DATA_3_KEY:            {                    break;            }            case C_RF_DATA_4_KEY:            {                break;            }         }     }   }   /*************************************************** 433接收解码函数 24us定时中断中调用433M接收解码函数 同步码,10ms低电平 之后是25位数据,只取243个字节 "1"1.1ms+0.2ms,"0"0.45+0.9 所以可以只通过高电平判断 ***************************************************/ void RF433M_RecevieDecode(void) { g_bTimerCount++;     if(g_bTimerCount == 42) //1ms=42*24us     {        g_bTimerCount = 0;        gw_RfRxKeeppingMsCnt++;     }       switch(gb_RfRxStep)     {         case   0:            if(!P_RF_REC)            {                //1-1.开始检测引导码10ms低电平或结束码100ms低电平                gw_RfRxCnt = 0;                gb_RfRxStep = 1;            }                break;           case   1:            if(!P_RF_REC)            {                 //1-2.引导码10ms或结束码100ms低电平计时                gw_RfRxCnt++;            }            else            {                    //1-3.判断引导码9ms低电平或结束码100ms低电平                if(gw_RfRxCnt >C_RF_END_L_MIN && gbit_RfRecOkFlag)                 {                     //结束码                     gbit_RfRecOkFlag = 0;                     //相当于按键按下松开时调用函数 -- OnkeyUp()                     RF433M_OnRecevieEndCode();                     return ;                }                else if((gw_RfRxCnt > C_RF_START_L_MAX) ||(gw_RfRxCnt < C_RF_START_L_MIN))                {                     goto F_RfRxError;                            }                  //引导码                            //gbit_RfRecOkFlag = 0;                   //2-1.开始接收数据,检测引导码4.5ms高电平                    gb_RfRxLevel = PORT_RF_REC & _field(P_RF_REC);                gw_RfRxCnt = 0;                gb_RfRxBitCnt = 0;                gb_RfRxStep = 2;                //gew_RfRxData = 0;                     }            break;           case   2://check level change            a = PORT_RF_REC & _field(P_RF_REC);            if(a == gb_RfRxLevel)            {                //电平保持不变                gw_RfRxCnt++;             }            else            {    //level change,check current level                gb_RfRxLevel = a;                if(!P_RF_REC)                {                         //数据01是通过高电平时间判断,所以电平跳变为低的时候,                     //也就获取到高电平的时间了,                     //就可以判断有效数据0,1                                          gew_RfRxData = gew_RfRxData<< 1;                     //slc   gew_RfRxData $ 2;                       //"1"1.1ms+0.2ms, "0"0.45+0.9                     //所以可以只通过高电平判断,当然用低电平判断也一样类似                     if((gw_RfRxCnt < C_RF_DATA1_MAX) &&(gw_RfRxCnt > C_RF_DATA1_MIN))                     {//data 1                         set1 gew_RfRxData.0;                         goto F_RfRxCheckBit;                     }                        else if((gw_RfRxCnt < C_RF_DATA0_MAX) &&(gw_RfRxCnt > C_RF_DATA0_MIN))                     {//data 0                         set0 gew_RfRxData.0;                         goto F_RfRxCheckBit;                                         }                     else                     {                         goto F_RfRxError;                     }   F_RfRxError:                     gb_RfRxStep = 0;                                    return;   F_RfRxCheckBit:                     gb_RfRxBitCnt++;                     if(gb_RfRxBitCnt >= C_RF_REC_BIT_LEN)                     {                             //接收完成,设置收到数据标志                         gb_RfRxData3 =gew_RfRxData $ 0;    //数据码                         gb_RfRxData2 = gew_RfRxData$ 1;    //客户代码                         gb_RfRxData1 =gew_RfRxData $ 2;    //客户代码                                                  gbit_RfRecEndCodeFlag =0;                         gb_RfRxStep = 0;                         gb_RfRxBitCnt=0;                           if(!gbit_RfRecOkFlag)                         {                             gbit_RfRecOkFlag = 1;                             //这时候相当于按键的OnkeyDown()                             RF433M_OnRecevieFirstData();                         }                         //这时候相当于按键的OnkeyPressing()                         RF433M_OnRecevieData();                     }                }                gw_RfRxCnt = 0;            }            break;     } }

使用特权

评论回复

相关帖子

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

本版积分规则

21

主题

56

帖子

2

粉丝