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

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

      我们可以设定一个较快的定时中断(下面设定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;

    }

}

 

 

 

 

 

     

    

  • 17
    点赞
  • 121
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值