RF433无线接收器EV1527 解码程序:简单易懂、移植性超强

EV1527 是一种常用的射频编码芯片,通常用于无线遥控器、智能家居设备等领域。然而,对于很多开发者来说,网上现有的 EV1527 解码函数不够清晰易懂,而且在移植到不同平台时可能会遇到一些困难。本文将介绍一种简单易懂、移植性超强的 EV1527 解码程序,并详细解释其原理和实现。

背景介绍
EV1527 是一种常见的射频编码解码芯片,通常用于无线遥控器。它采用了简单的调制方式,使得信号解码相对容易。然而,网上现有的解码函数大多数都缺乏清晰的注释和易懂的逻辑结构,给开发者阅读和理解带来了一定的困难。

解码原理
EV1527 采用了一种简单的调制方式,将数据通过一定的编码方式转换成射频信号进行传输。解码过程主要包括对射频信号的采样和解析,以及对编码数据的还原。本文的解码程序将这些过程清晰地分解,使得逻辑结构更加清晰易懂。

EV1527 协议介绍
EV1527 是一种常见的射频编码芯片,通常用于无线遥控器等设备中。每个 EV1527 帧数据由同步码和 24 位的数据码组成,其中数据码又分为地址码(20 位)和按键码(4 位)。下面以 433MHz EV1527 遥控器为例,来详细介绍其帧结构和解码原理。

帧结构

同步码
同步码是 EV1527 帧的开头部分,用于同步接收器的时钟。在 433MHz EV1527 遥控器中,同步码的高电平持续时间为 400us,低电平持续时间为 9ms。

数据码
数据码由地址码和按键码组成:

地址码:20 个数据位,共 24ms。它用于识别设备的唯一地址。
按键码:4 个数据位,共 4.8ms。它表示用户按下的具体按键信息。
波形示意图
在波形示意图中,红色线条部分表示同步码,绿色线条部分表示地址码,蓝色线条部分表示按键码。

解码原理
EV1527 的解码原理主要是通过定时器计算高低电平持续时间来判断同步码、bit1、bit0。具体来说:

bit0:400us 高电平+800us 低电平
bit1:1ms 高电平+200us 低电平
根据不同的高低电平持续时间,可以准确判断出同步码、地址码和按键码,从而完成数据的解码工作。

代码实现
以下提供了一种简单易懂、移植性超强的 EV1527 解码程序,其代码结构清晰,注释详尽。使用的主控为PY32F002B,STM32同样适用,以下是代码示例:

/**
 * @file EV1527.c
 * @author cyWu (1917507415@qq.com)
 * @brief EV1527解码框架,定时器中断的方式解码,使用80us的定时器,直接放中断服务函数就可以,适用于所有单片机。
 * @version 0.1
 * @date 2024-03-28
 * @copyright Copyright (c) 2024
 * 
 */
#include "EV1527.h"

// 定时周期
#define TIME_CYCLE 80

// 定义引导码的最小和最大持续时间(单位:us)
#define MIN_LEAD_CODE (5600 / TIME_CYCLE)
#define MAX_LEAD_CODE (16000 / TIME_CYCLE)

// 定义数据位持续时间的最小和最大范围(单位:us)
#define MIN_BIT_DURATION (80 / TIME_CYCLE)
#define MAX_BIT_DURATION (2400 / TIME_CYCLE)

// 定义功能字节在接收缓冲区中的索引位置
#define FUNCTION_BYTE_INDEX 2

// 定义功能值
#define FUNCTION_1 0x08
#define FUNCTION_2 0x04
#define FUNCTION_3 0x02

// 定义数据解码状态枚举
typedef enum
{
    LEAD_CODE,       // 引导码状态
    HIGH_BIT,        // 高位数据位状态
    LOW_BIT,         // 低位数据位状态
    DATA_PROCESS,    // 数据处理状态
    FUNCTION_PROCESS // 功能处理状态
} Decode_State_t;

// 定义全局变量和缓冲区
static uint32_t Lead_Code_Count = 0;               // 引导码计数
static uint32_t High_Bit_Count = 0;                // 高位数据位计数
static uint32_t Low_Bit_Count = 0;                 // 低位数据位计数
static uint32_t High_Bit_Duration = 0;             // 高位数据位持续时间
static uint32_t Low_Bit_Duration = 0;              // 低位数据位持续时间
static uint8_t Received_Buffer[ARRAY_SIZE] = {0};  // 接收数据缓冲区
static uint8_t lastDataArray[ARRAY_SIZE] = {0};    // 上一次接收数据缓冲区
static uint8_t Received_Byte_Count = 0;            // 接收数据字节计数
static uint8_t consecutiveEqualCount = 0;          // 数据接收相同计数
static uint8_t Bit_Count = 0;                      // 接收数据位计数
static uint8_t Received_Data = 0;                  // 接收到的数据
static Decode_State_t RF_Decode_State = LEAD_CODE; // 数据解码状态

void Decode_Data(void);
void Execute_Function(void);
void Reset_Decode_Parameters(void);

/**----------------------------------------------------------------------------------------------**
 **函数名  :EV1527端口配置
 **功能说明:初始化IO口,不同单片机的配置输入模式不一样,自行修改。
 **----------------------------------------------------------------------------------------------**/
void EV1527_Init(void)
{
    DATA_433_GPIO_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct;
    // 配置上拉输入
    GPIO_InitStruct.Pin = DATA_433_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(DATA_433_GPIO_PORT, &GPIO_InitStruct);
}

/**----------------------------------------------------------------------------------------------**
 **函数名  :RF信号解码函数
 **功能说明:解码从433MHz接收到的信号,并根据解码结果执行相应功能
 **调用说明:80us调用一次
 **----------------------------------------------------------------------------------------------**/
void RF_Signal_Decode(void)
{
    switch (RF_Decode_State)
    {
    case LEAD_CODE: // 引导码
        // 判断是否低电平
        if (HAL_GPIO_ReadPin(DATA_433_GPIO_PORT, DATA_433_PIN) == GPIO_PIN_RESET)
        {
            Lead_Code_Count++;
        }
        else // 高电平判断范围
        {
            // 判断引导码范围是否合法
            if (Lead_Code_Count >= MIN_LEAD_CODE && Lead_Code_Count <= MAX_LEAD_CODE)
            {
                Lead_Code_Count = 0;
                Reset_Decode_Parameters();  // 重置解码参数
                RF_Decode_State = HIGH_BIT; // 进入高位数据位判断状态
            }
            else
            {
                Reset_Decode_Parameters(); // 引导码范围不合法,重置解码参数
            }
        }
        break;

    case HIGH_BIT:
        // 判断是否高电平
        if (HAL_GPIO_ReadPin(DATA_433_GPIO_PORT, DATA_433_PIN) == GPIO_PIN_SET)
        {
            High_Bit_Count++;
        }
        else // 低电平判断范围
        {
            // 判断高位数据位范围是否合法
            if (High_Bit_Count >= MIN_BIT_DURATION && High_Bit_Count <= MAX_BIT_DURATION)
            {
                High_Bit_Duration = High_Bit_Count; // 保存计数值,用于区分0和1
                High_Bit_Count = 0;
                RF_Decode_State = LOW_BIT; // 进入低位数据位判断状态
            }
            else
            {
                Reset_Decode_Parameters(); // 高位数据位范围不合法,重置解码参数
            }
        }
        break;

    case LOW_BIT:
        // 判断是否低电平
        if (HAL_GPIO_ReadPin(DATA_433_GPIO_PORT, DATA_433_PIN) == GPIO_PIN_RESET)
        {
            Low_Bit_Count++;
        }
        else // 高电平判断范围
        {
            // 判断低位数据位范围是否合法
            if (Low_Bit_Count >= MIN_BIT_DURATION && Low_Bit_Count <= MAX_BIT_DURATION)
            {
                Low_Bit_Duration = Low_Bit_Count; // 保存计数值,用于区分0和1
                Low_Bit_Count = 0;
                RF_Decode_State = DATA_PROCESS; // 进入数据处理状态
            }
            else
            {
                Reset_Decode_Parameters(); // 低位数据位范围不合法,重置解码参数
            }
        }
        break;

    case DATA_PROCESS:
        Decode_Data(); // 解码数据
        if (Received_Byte_Count == 3)
        {
            // 接收到全部数据,包括地址和数据
            RF_Decode_State = FUNCTION_PROCESS;  
        }
        else
        {                               // 数据没接收完
            RF_Decode_State = HIGH_BIT; // 继续解码数据
        }
        break;

    case FUNCTION_PROCESS:
        Execute_Function();        // 执行功能
        Reset_Decode_Parameters(); // 重置解码参数
        break;

    default:
        Reset_Decode_Parameters(); // 默认状态,重置解码参数
        break;
    }
}

/**----------------------------------------------------------------------------------------------**
 **函数名  :Reset_Decode_Parameters
 **功能说明:重置解码参数,用于开始新的解码周期
 **----------------------------------------------------------------------------------------------**/
void Reset_Decode_Parameters(void)
{
    Bit_Count = 0;
    Received_Data = 0x00;
    Received_Byte_Count = 0;
    Lead_Code_Count = 0;
    High_Bit_Count = 0;
    Low_Bit_Count = 0;
    High_Bit_Duration = 0;
    Low_Bit_Duration = 0;
    RF_Decode_State = LEAD_CODE;
}

/**----------------------------------------------------------------------------------------------**
 **函数名  :Decode_Data
 **功能说明:解码数据位,将解码后的数据存入相应的缓冲区中
 **----------------------------------------------------------------------------------------------**/
void Decode_Data(void)
{
    Received_Data <<= 1;
    // 根据高低电平持续时间判断0和1,然后将数据移位存入缓冲区
    if (High_Bit_Duration > Low_Bit_Duration)
    {
        Received_Data |= 0x01;
    }
    else
    {
        Received_Data &= 0xFE;
    }

    Bit_Count++;

    // 每接收8位数据,存入数据数组
    if (Bit_Count == 8)
    {
        Received_Buffer[Received_Byte_Count] = Received_Data;
        Received_Data = 0x00;
        Bit_Count = 0;
        Received_Byte_Count++;
    }
}

/**----------------------------------------------------------------------------------------------**
 **函数名  :Execute_Function
 **功能说明:执行功能,根据解码后的数据进行相应操作
 **----------------------------------------------------------------------------------------------**/
void Execute_Function(void)
{
    // 判断解码后的功能字节,并执行相应操作
    switch (Received_Buffer[FUNCTION_BYTE_INDEX])
    {
    case FUNCTION_1:
        // 执行功能1
        break;

    case FUNCTION_2:
        // 执行功能2
        break;

    case FUNCTION_3:
        // 执行功能3
        break;

    default:
        // 默认操作
        break;
    }
}


EV1527.h

/**
 * @file EV1527.h
 * @author cyWu (1917507415@qq.com)
 * @brief EV1527解码框架
 * @version 0.1
 * @date 2024-03-28
 * @copyright Copyright (c) 2024
 *
 */

#ifndef __EV1527_H
#define __EV1527_H

#include "main.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>

/*********433 DATA GPIO**********/
// 433数据输入
#define DATA_433_PIN GPIO_PIN_7
#define DATA_433_GPIO_PORT GPIOA
#define DATA_433_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE();
/*******************************/

void EV1527_Init(void);
void RF_Signal_Decode(void);

#endif


总结
通过本文的介绍,我希望能够为开发者提供一种简单易懂、移植性超强的 EV1527 解码程序,使得开发工作更加高效和愉快。同时,也欢迎各位开发者对我的代码提出改进意见和建议,共同进步。

以上就是我的 EV1527 解码程序介绍,希望能对您有所帮助!

 

此文章收录于csdn, 文章地址:https://blog.csdn.net/wcynbl/article/details/137114077