单片机学习小组
直播中

好名字

9年用户 869经验值
擅长:可编程逻辑
私信 关注

STC15F104W是怎样使用315/433MHz超再生模块发送及接收数据的

315/433MHz超再生模块的发送端与接收端的原理是什么?
STC15F104W是怎样使用315/433MHz超再生模块发送及接收数据的?

回帖(1)

颜廷波

2022-2-15 10:28:27
一、原理图


实验所用到的 315/433 MHz 超再生模块

发送端原理图

接收端原理图


二、发送端代码

使用 NEC 协议发送数据

#include
#include


#define FOSC  6000000L                                //IRC频率


sfr P3M1 = 0xB1;
sfr P3M0 = 0xB2;


***it SEND = P3 ^ 4;                                        //数据发送引脚
***it btn  = P3 ^ 2;                                        //发送按键


#ifndef uchar
        #define uchar unsigned char
#endif
#ifndef uint
        #define uint unsigned int
#endif
       
uchar tx_buff[4];                        //发送缓冲区


void Delay9ms()                //@6.000MHz
{
        unsigned char i, j;


        i = 53;
        j = 132;


        do {
                while(--j);
        } while(--i);
}
void Delay4ms()                //@6.000MHz
{
        unsigned char i, j;


        i = 24;
        j = 85;


        do {
                while(--j);
        } while(--i);
}
void Delay560us()                //@6.000MHz
{
        unsigned char i, j;


        i = 4;
        j = 65;


        do {
                while(--j);
        } while(--i);
}
void Delay20us()                //@6.000MHz
{
        unsigned char i;


        _nop_();
        _nop_();
        i = 27;


        while(--i);
}




//发送逻辑1,逻辑1为2.25ms,脉冲时间560us
void send_logic_1()
{
        SEND = 1;
        Delay560us();
        SEND = 0;
        Delay560us();
        Delay560us();
        Delay560us();
}
//发送逻辑0,逻辑0为1.12ms,脉冲时间560us
void send_logic_0()
{
        SEND = 1;
        Delay560us();
        SEND = 0;
        Delay560us();
}
//发送指定长度的数据
void send(uchar *dat, uint len)
{
        uchar i, j, temp;
       
        //引导码
        SEND = 1;
        Delay9ms();        //9ms高电平
        SEND = 0;
        Delay4ms();        //4ms低电平


        //数据码
        for(j = 0; j < len; j++){
                temp = *dat;
                for(i = 0; i < 8; i++) {
                        if((temp & 0x01) == 0x01) {
                                send_logic_1();
                        } else {
                                send_logic_0();
                        }


                        temp = temp >> 1;
                }
                dat++;
        }
        //结束码
        SEND = 1;
        Delay4ms();        //4ms高电平
        SEND = 0;
}


void main()
{
        INT0 = 1;
        IT0 = 1;                    //设置INT0的中断类型 (1:仅下降沿 0:上升沿和下降沿)
        EX0 = 1;                    //使能INT0中断
        EA = 1;


        P3M1 &= 0xEF;                                //P3.4推挽输出
        P3M0 &= 0xFF;
       
        tx_buff[0] = 0x40;
        tx_buff[1] = ~tx_buff[0];        //取反
        tx_buff[2] = 0x56;
        tx_buff[3] = ~tx_buff[2];        //取反
       
        while(1) {
               
        }
}


//中断服务程序
void ex_int0() interrupt 0       //INT0中断入口
{
        if(btn == 0) {
                Delay20us();


                if(btn == 0) {
                        Delay20us();
                        send(tx_buff, 4);
                }


                while(!btn);//等待 按起
        }
}

三、接收端代码

使用 NEC 协议接收数据

#include
#include


#ifndef FOSC
        #define FOSC  6000000L                                //IRC频率
#endif


#ifndef uchar
        #define uchar unsigned char
#endif
#ifndef uint
        #define uint unsigned int
#endif


sfr P3M1 = 0xB1;
sfr P3M0 = 0xB2;
       
***it RECEIVE = P3 ^ 2;                //数据接收引脚,INT0
bit  exint0;
bit  flag = 0;                                //接收标志
       
***it LED = P3 ^ 3;                        //LED


uchar recv[4];                        //接收缓冲区


void Delay2ms()                //@6.000MHz
{
        unsigned char i, j;


        i = 12;
        j = 169;


        do {
                while(--j);
        } while(--i);
}


void Delay200us()                //@6.000MHz
{
        unsigned char i, j;


        i = 2;
        j = 39;


        do {
                while(--j);
        } while(--i);
}


void Init_Int0(void)
{
        INT0 = 1;
        IT0 = 0;                    //设置INT0的中断类型 (1:仅下降沿 0:上升沿和下降沿)
        EX0 = 1;                    //使能INT0中断
}


void main()
{
        Init_Int0();
        EA = 1;


        P3M1 &= 0xF7;                //P3.3        推挽输出
        P3M0 &= 0xFF;
       
        flag = 0;


        while(1) {
                if(flag) {
                        flag = 0;
                        LED = !LED;                //接收到数据反转一次IO输出
                }
        }
}


//中断服务程序
void External_INT0() interrupt 0       //INT0中断入口
{
        uchar i, j, N;
        uint k;
        exint0 = INT0;                //保存INT0口的状态, INT0=0(下降沿); INT0=1(上升沿)
       
        EX0 = 0;        //关中断


        flag = 0;
       
        Delay2ms();


        if(RECEIVE == 0) {
                EX0 = 1;
                flag = 0;
                return;
        }


        k = 100;


        //确认RECEIVE信号出现
        while(RECEIVE && k) {                //等RECEIVE变为低电平,跳过9ms的前导高电平信号。
                Delay200us();
                k--;
        }


        k = 100;


        while(!RECEIVE && k) {                 //等 RECEIVE 变为高电平,跳过4ms的前导低电平信号。
                Delay200us();
                k--;
        }


        for(i = 0; i < 4; i++) {                                //4组数据
                for(j = 0; j < 8; j++) {                                        //每组数据有8位
                        k = 100;


                        while(RECEIVE && k) {                                                //等RECEIVE变为低电平
                                Delay200us();
                                k--;
                        }


                        k = 100;
                        N = 0;


                        while(!RECEIVE && k) {                                                //计算RECEIVE低电平时长
                                Delay200us();
                                N++;
                                k--;


                                if(N >= 30) {
                                        EX0 = 1;
                                        flag = 0;
                                        return;                                                //0.14ms计数过长自动离开。
                                }
                        }                                                                        //低电平计数完毕


                        recv = recv >> 1;                        //数据最高位补“0”


                        if(N >= 8) {
                                recv = recv | 0x80;                //数据最高位补“1”
                        }


                        N = 0;


                }
        }
       
        if((recv[0] == ~recv[1]) && (recv[2] == ~recv[3])){                //数据校验成功
                flag = 1;
        }
        else{
                flag = 0;
               
        }
       
        EX0 = 1;                //开中断


}
四、接收输出波形图

举报

更多回帖

发帖
×
20
完善资料,
赚取积分