找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1594|回复: 1
打印 上一主题 下一主题
收起左侧

315/433M无线模块解码程序

[复制链接]
跳转到指定楼层
楼主
ID:1012383 发表于 2024-7-30 08:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
现在这种接收模块一般用PRO480R/SYN480R,外围再加一些简单的典型电路,性价比高,1块多就可以买到,可实现灯光、门禁、汽车、安防监控系统和智能家居产品的无线遥控功能。

2、315/433无线模块解码

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

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

      网上找不到比较好的方案,这里是有类似的讨论:"最精间的PT2262解码程序与大家共享"

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

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

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



  1. /******************H头文件*********************************/



  2. #ifndef RF433MDecode_H_



  3. #define RF433MDecode_H_



  4. /***************************************************/



  5. //Define I/O Register



  6. #define PORT_RF_REC     pa



  7. #define P_RF_REC         pa.7



  8. #define PC_RF_REC         pac.7



  9. #define PPH_RF_REC     paph.7







  10. //**************************************************//



  11. //Define Constant



  12. //在24us定时中断中调用433M接收解码函数







  13. //同步码,10ms低电平



  14. #define C_RF_START_L_MAX        500        //12MS //10MS--10000/24=416



  15. #define C_RF_START_L_MIN     250        //6MS







  16. //之后是25位数据,只取24位3个字节



  17. #define C_RF_REC_BIT_LEN    24   



  18. //"1"是1.1ms高+0.2ms低, "0"是0.45高+0.9低



  19. //所以可以只通过高电平判断



  20. #define C_RF_DATA1_MAX        54        //1.3ms



  21. #define C_RF_DATA1_MIN        37        //0.9ms



  22. #define C_RF_DATA0_MAX        25        //0.6ms



  23. #define C_RF_DATA0_MIN        13        //0.3ms







  24. //结束码,短按:130ms低电平,长按:500ms,这里取大于70ms



  25. //#define C_RF_END_L_MAX        500        //140MS



  26. #define C_RF_END_L_MIN     2916        //70MS











  27. #define C_RF_DATA_CLENT_1     0xAD        //客户码1



  28. #define C_RF_DATA_CLENT_2     0x2F        //客户码2



  29. #define C_RF_DATA_1_KEY          0x01        //A键值



  30. #define C_RF_DATA_2_KEY     0x02        //B键值



  31. #define C_RF_DATA_3_KEY     0x04        //C键值



  32. #define C_RF_DATA_4_KEY     0x08        //D键值







  33. #define C_DELAY_KEY_PRESS_SHORT        500        //1000*1MS



  34. #define C_DELAY_KEY_PRESS_LONG        2000    //3000*1MS



  35. /****************************************************/



  36. // Define General Register







  37. //**************************************************



  38. //Define FUNCTION



  39. void RF433M_Init(void);



  40. void RF433M_RecevieDecode(void);







  41. #endif



  42. /******************C文件*********************************/



  43. //***************************************************



  44. //CUSTOMER:



  45. //OBJECT:433M解码程序



  46. //AUTHOR:TJY



  47. //DESCRIPTION:



  48. //        在24us定时中断中调用433M接收解码函数



  49. /*************************************************************************

  50. /*************************************************************************/



  51. #include    "extern.h"



  52. #include    "Rf433MDecode.h"







  53. byte    gb_RfRxStep;                //IR接收步骤



  54. word    gw_RfRxCnt;                //接收计数器







  55. eword    gew_RfRxData;            //接收数据暂存,//同步码之后是25位数据,只取24位3个字节



  56. byte    gb_RfRxData1;                //接收数据--//客户代码1



  57. byte    gb_RfRxData2;                //客户代码2



  58. byte    gb_RfRxData3;                //数据码











  59. byte    gb_RfRxLevel;



  60. byte    gb_RfRxBitCnt;                //接收数据位



  61. bit     gbit_RfRecOkFlag;            //收到完整的24位数据置1,相当于g_bitKeyDownFlag



  62. bit     gbit_RfRecEndCodeFlag;        //收到结束码



  63. byte g_bTimerCount



  64. word    gw_RfRxKeeppingMsCnt;        //接收第一个数据后开始的计数器



  65. word    gw_RfRxKeeppingIntervalCount;







  66. bit        gbit_ResetFlag;



  67. /***************************************************

  68. 接收初始化函数

  69. ***************************************************/



  70. void RF433M_Init(void)



  71. {



  72.     $ P_RF_REC     High;



  73.     $ P_RF_REC     In, NoPull;        //设置为输入模式







  74.     gb_RfRxStep = 0;



  75.     gbit_RfRecOkFlag = 0;



  76.     gbit_RfRecEndCodeFlag = 0;



  77. bTimerCount = 0;



  78. }   







  79. /***************************************************

  80. 第一次收到完整的24位数据的回调函数



  81. 相当于按键按下调用函数 -- OnkeyDown()

  82. 只在开始的时候进一次

  83. ***************************************************/



  84. void RF433M_OnRecevieFirstData(void)



  85. {



  86.     gw_RfRxKeeppingMsCnt = 0;



  87. }







  88. /***************************************************

  89. 收到完整的24位数据后的回调函数



  90. 相当于按键按下调用函数 -- OnkeyPressing()

  91. 在按下期间,会不断进入

  92. ***************************************************/



  93. void RF433M_OnRecevieData(void)



  94. {



  95.     if(gw_RfRxKeeppingMsCnt >= C_DELAY_KEY_PRESS_LONG)



  96.     {



  97.         //长按



  98.         if(gb_RfRxData3 == C_RF_DATA_1_KEY)



  99.         {



  100.                     



  101.         }



  102.     }



  103. }







  104. /***************************************************

  105. 收到24位数据后,再接收到结束码的回调函数



  106. 相当于按键按下松开时调用函数 -- OnkeyUp()

  107. ***************************************************/



  108. void RF433M_OnRecevieEndCode(void)



  109. {







  110.     if( gw_RfRxKeeppingMsCnt <= C_DELAY_KEY_PRESS_SHORT)



  111.     {



  112.         //短按



  113.         switch(gb_RfRxData3)



  114.         {



  115.             case C_RF_DATA_1_KEY:



  116.             {



  117.                 break;



  118.             }



  119.             case C_RF_DATA_2_KEY:



  120.             {



  121.                 break;



  122.             }



  123.             case C_RF_DATA_3_KEY:



  124.             {   



  125.                 break;



  126.             }



  127.             case C_RF_DATA_4_KEY:



  128.             {



  129.                 break;



  130.             }



  131.         }



  132.     }







  133. }







  134. /***************************************************

  135. 433接收解码函数



  136. 在24us定时中断中调用433M接收解码函数

  137. 同步码,10ms低电平

  138. 之后是25位数据,只取24位3个字节

  139. "1"是1.1ms高+0.2ms低, "0"是0.45高+0.9低

  140. 所以可以只通过高电平判断

  141. ***************************************************/



  142. void RF433M_RecevieDecode(void)



  143. {



  144. g_bTimerCount++;



  145.     if(g_bTimerCount == 42) //1ms=42*24us



  146.     {



  147.         g_bTimerCount = 0;



  148.         gw_RfRxKeeppingMsCnt++;



  149.     }







  150.     switch(gb_RfRxStep)



  151.     {



  152.         case    0:



  153.             if(!P_RF_REC)



  154.             {



  155.                 //1-1.开始检测引导码10ms低电平或结束码100ms低电平



  156.                 gw_RfRxCnt = 0;



  157.                 gb_RfRxStep = 1;



  158.             }   



  159.             break;







  160.         case    1:



  161.             if(!P_RF_REC)



  162.             {



  163.                 //1-2.引导码10ms或结束码100ms低电平计时



  164.                 gw_RfRxCnt++;



  165.             }



  166.             else



  167.             {   



  168.                 //1-3.判断引导码9ms低电平或结束码100ms低电平



  169.                 if(gw_RfRxCnt > C_RF_END_L_MIN && gbit_RfRecOkFlag)



  170.                 {



  171.                     //结束码



  172.                     gbit_RfRecOkFlag = 0;



  173.                     //相当于按键按下松开时调用函数 -- OnkeyUp()



  174.                     RF433M_OnRecevieEndCode();



  175.                     return ;



  176.                 }



  177.                 else if((gw_RfRxCnt > C_RF_START_L_MAX) || (gw_RfRxCnt < C_RF_START_L_MIN))



  178.                 {



  179.                     goto F_RfRxError;            



  180.                 }







  181.                 //引导码            



  182.                 //gbit_RfRecOkFlag = 0;







  183.                 //2-1.开始接收数据,检测引导码4.5ms高电平   



  184.                 gb_RfRxLevel = PORT_RF_REC & _field(P_RF_REC);



  185.                 gw_RfRxCnt = 0;



  186.                 gb_RfRxBitCnt = 0;



  187.                 gb_RfRxStep = 2;



  188.                 //gew_RfRxData = 0;



  189.         



  190.             }



  191.             break;







  192.         case    2://check level change



  193.             a = PORT_RF_REC & _field(P_RF_REC);



  194.             if(a == gb_RfRxLevel)



  195.             {



  196.                 //电平保持不变



  197.                 gw_RfRxCnt++;



  198.             }



  199.             else



  200.             {    //level change,check current level



  201.                 gb_RfRxLevel = a;



  202.                 if(!P_RF_REC)



  203.                 {   



  204.                     //数据0、1是通过高电平时间判断,所以电平跳变为低的时候,



  205.                     //也就获取到高电平的时间了,



  206.                     //就可以判断有效数据0,1



  207.                     



  208.                     gew_RfRxData = gew_RfRxData << 1;



  209.                     //slc    gew_RfRxData $ 2;







  210.                     //"1"是1.1ms高+0.2ms低, "0"是0.45高+0.9低



  211.                     //所以可以只通过高电平判断,当然用低电平判断也一样类似



  212.                     if((gw_RfRxCnt < C_RF_DATA1_MAX) && (gw_RfRxCnt > C_RF_DATA1_MIN))



  213.                     {//data 1



  214.                         set1 gew_RfRxData.0;



  215.                         goto F_RfRxCheckBit;



  216.                     }   



  217.                     else if((gw_RfRxCnt < C_RF_DATA0_MAX) && (gw_RfRxCnt > C_RF_DATA0_MIN))



  218.                     {//data 0



  219.                         set0 gew_RfRxData.0;



  220.                         goto F_RfRxCheckBit;                    



  221.                     }



  222.                     else



  223.                     {



  224.                         goto F_RfRxError;



  225.                     }







  226. F_RfRxError:



  227.                     gb_RfRxStep = 0;               



  228.                     return;







  229. F_RfRxCheckBit:



  230.                     gb_RfRxBitCnt++;



  231.                     if(gb_RfRxBitCnt >= C_RF_REC_BIT_LEN)



  232.                     {   



  233.                         //接收完成,设置收到数据标志



  234.                         gb_RfRxData3 = gew_RfRxData $ 0;    //数据码



  235.                         gb_RfRxData2 = gew_RfRxData $ 1;    //客户代码



  236.                         gb_RfRxData1 = gew_RfRxData $ 2;    //客户代码



  237.                         



  238.                         gbit_RfRecEndCodeFlag = 0;



  239.                         gb_RfRxStep = 0;



  240.                         gb_RfRxBitCnt=0;







  241.                         if(!gbit_RfRecOkFlag)



  242.                         {



  243.                             gbit_RfRecOkFlag = 1;



  244.                             //这时候相当于按键的OnkeyDown()



  245.                             RF433M_OnRecevieFirstData();



  246.                         }



  247.                         //这时候相当于按键的OnkeyPressing()



  248.                         RF433M_OnRecevieData();



  249.                     }



  250.                 }



  251.                 gw_RfRxCnt = 0;



  252.             }



  253.             break;



  254.     }



  255. }


  256. ————————————————
  257.                     
复制代码




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1091035 发表于 2025-3-7 23:46 | 只看该作者
大佬可以发一下完整的代码学习一下吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表