315/433无线模块解码

逃离我推掉我的手 2022-09-26 02:12 142阅读 0赞

315/433无线模块解码

1、超外差315/433无线模块

20160915233311453

  1. 现在这种接收模块一般用PRO480R/SYN480R,外围再加一些简单的典型电路,性价比高,1块多就可以买到,可实现灯光、门禁、汽车、安防监控系统和智能家居产品的无线遥控功能。

2、315/433无线模块解码

20160915233312179

  1. 上图是接收模块接收到的发送模块按键一次发来的信息波形,可以分为5个阶段来分析,分别是:1、开始无接收信号,输出的是杂波;2、引导码;3、键码;4、相同连续的引导码和键码,如果长按发送会一直输出这样的波形;5、松开发送键,接收输出一个比较明显的结束码;
  2. 接收模块在无信号状态下接收引脚是不断输出杂波,在接到信号时,才会输出信息码,所以写程序的难点在解码。
  3. 网上找不到比较好的方案,这里是有类似的讨论:[http://www.amobbs.com/thread-959411-1-1.html][http_www.amobbs.com_thread-959411-1-1.html]
  4. 像在程序中延时解码的方式,如果其他程序需要快速的循环执行的话,会有影响,再有就是移植性不高。
  5. 我们可以设定一个较快的定时中断(下面设定24us),然后在中调用接收解码函数,每次中断只判断相应的标志,不会造成中断执行时间过长的问题。
  6. 比如其中一对收发模块,同步码为10ms低电平,之后是25位数据,只取243个字节,"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. 收到24位数据后,再接收到结束码的回调函数
  105. 相当于按键按下松开时调用函数 -- OnkeyUp()
  106. ***************************************************/
  107. void RF433M_OnRecevieEndCode(void)
  108. {
  109. if( gw_RfRxKeeppingMsCnt <= C_DELAY_KEY_PRESS_SHORT)
  110. {
  111. //短按
  112. switch(gb_RfRxData3)
  113. {
  114. case C_RF_DATA_1_KEY:
  115. {
  116. break;
  117. }
  118. case C_RF_DATA_2_KEY:
  119. {
  120. break;
  121. }
  122. case C_RF_DATA_3_KEY:
  123. {
  124. break;
  125. }
  126. case C_RF_DATA_4_KEY:
  127. {
  128. break;
  129. }
  130. }
  131. }
  132. }
  133. /***************************************************
  134. 433接收解码函数
  135. 在24us定时中断中调用433M接收解码函数
  136. 同步码,10ms低电平
  137. 之后是25位数据,只取24位3个字节
  138. "1"是1.1ms高+0.2ms低, "0"是0.45高+0.9低
  139. 所以可以只通过高电平判断
  140. ***************************************************/
  141. void RF433M_RecevieDecode(void)
  142. {
  143. g_bTimerCount++;
  144. if(g_bTimerCount == 42) //1ms=42*24us
  145. {
  146. g_bTimerCount = 0;
  147. gw_RfRxKeeppingMsCnt++;
  148. }
  149. switch(gb_RfRxStep)
  150. {
  151. case 0:
  152. if(!P_RF_REC)
  153. {
  154. //1-1.开始检测引导码10ms低电平或结束码100ms低电平
  155. gw_RfRxCnt = 0;
  156. gb_RfRxStep = 1;
  157. }
  158. break;
  159. case 1:
  160. if(!P_RF_REC)
  161. {
  162. //1-2.引导码10ms或结束码100ms低电平计时
  163. gw_RfRxCnt++;
  164. }
  165. else
  166. {
  167. //1-3.判断引导码9ms低电平或结束码100ms低电平
  168. if(gw_RfRxCnt > C_RF_END_L_MIN && gbit_RfRecOkFlag)
  169. {
  170. //结束码
  171. gbit_RfRecOkFlag = 0;
  172. //相当于按键按下松开时调用函数 -- OnkeyUp()
  173. RF433M_OnRecevieEndCode();
  174. return ;
  175. }
  176. else if((gw_RfRxCnt > C_RF_START_L_MAX) || (gw_RfRxCnt < C_RF_START_L_MIN))
  177. {
  178. goto F_RfRxError;
  179. }
  180. //引导码
  181. //gbit_RfRecOkFlag = 0;
  182. //2-1.开始接收数据,检测引导码4.5ms高电平
  183. gb_RfRxLevel = PORT_RF_REC & _field(P_RF_REC);
  184. gw_RfRxCnt = 0;
  185. gb_RfRxBitCnt = 0;
  186. gb_RfRxStep = 2;
  187. //gew_RfRxData = 0;
  188. }
  189. break;
  190. case 2://check level change
  191. a = PORT_RF_REC & _field(P_RF_REC);
  192. if(a == gb_RfRxLevel)
  193. {
  194. //电平保持不变
  195. gw_RfRxCnt++;
  196. }
  197. else
  198. { //level change,check current level
  199. gb_RfRxLevel = a;
  200. if(!P_RF_REC)
  201. {
  202. //数据0、1是通过高电平时间判断,所以电平跳变为低的时候,
  203. //也就获取到高电平的时间了,
  204. //就可以判断有效数据0,1
  205. gew_RfRxData = gew_RfRxData << 1;
  206. //slc gew_RfRxData $ 2;
  207. //"1"是1.1ms高+0.2ms低, "0"是0.45高+0.9低
  208. //所以可以只通过高电平判断,当然用低电平判断也一样类似
  209. if((gw_RfRxCnt < C_RF_DATA1_MAX) && (gw_RfRxCnt > C_RF_DATA1_MIN))
  210. {//data 1
  211. set1 gew_RfRxData.0;
  212. goto F_RfRxCheckBit;
  213. }
  214. else if((gw_RfRxCnt < C_RF_DATA0_MAX) && (gw_RfRxCnt > C_RF_DATA0_MIN))
  215. {//data 0
  216. set0 gew_RfRxData.0;
  217. goto F_RfRxCheckBit;
  218. }
  219. else
  220. {
  221. goto F_RfRxError;
  222. }
  223. F_RfRxError:
  224. gb_RfRxStep = 0;
  225. return;
  226. F_RfRxCheckBit:
  227. gb_RfRxBitCnt++;
  228. if(gb_RfRxBitCnt >= C_RF_REC_BIT_LEN)
  229. {
  230. //接收完成,设置收到数据标志
  231. gb_RfRxData3 = gew_RfRxData $ 0; //数据码
  232. gb_RfRxData2 = gew_RfRxData $ 1; //客户代码
  233. gb_RfRxData1 = gew_RfRxData $ 2; //客户代码
  234. gbit_RfRecEndCodeFlag = 0;
  235. gb_RfRxStep = 0;
  236. gb_RfRxBitCnt=0;
  237. if(!gbit_RfRecOkFlag)
  238. {
  239. gbit_RfRecOkFlag = 1;
  240. //这时候相当于按键的OnkeyDown()
  241. RF433M_OnRecevieFirstData();
  242. }
  243. //这时候相当于按键的OnkeyPressing()
  244. RF433M_OnRecevieData();
  245. }
  246. }
  247. gw_RfRxCnt = 0;
  248. }
  249. break;
  250. }
  251. }

发表评论

表情:
评论列表 (有 0 条评论,142人围观)

还没有评论,来说两句吧...

相关阅读