315/433无线模块解码
315/433无线模块解码
1、超外差315/433无线模块
现在这种接收模块一般用PRO480R/SYN480R,外围再加一些简单的典型电路,性价比高,1块多就可以买到,可实现灯光、门禁、汽车、安防监控系统和智能家居产品的无线遥控功能。
2、315/433无线模块解码
上图是接收模块接收到的发送模块按键一次发来的信息波形,可以分为5个阶段来分析,分别是:1、开始无接收信号,输出的是杂波;2、引导码;3、键码;4、相同连续的引导码和键码,如果长按发送会一直输出这样的波形;5、松开发送键,接收输出一个比较明显的结束码;
接收模块在无信号状态下接收引脚是不断输出杂波,在接到信号时,才会输出信息码,所以写程序的难点在解码。
网上找不到比较好的方案,这里是有类似的讨论:[http://www.amobbs.com/thread-959411-1-1.html][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位数据,只取24位3个字节
#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位数据,只取24位3个字节
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位数据,只取24位3个字节
"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)
{
//数据0、1是通过高电平时间判断,所以电平跳变为低的时候,
//也就获取到高电平的时间了,
//就可以判断有效数据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;
}
}
还没有评论,来说两句吧...