目录

ASK介绍EV1527编码芯片介绍模块介绍无线发射芯片无线接收芯片解码程序发射电路原理图

ASK介绍

ASK是幅移键控,通过调幅将数据发送出去,所以发送与接收都是多位二进制数。

ASK如何区分0和1?

0:发送 433.92Mhz 无线波形(载波频率)振幅低 1:发送 433.92Mhz 无线波形(载波频率)振幅高

OOK 如何区分 0 和 1?(OOK 是 ASK 的一种特殊形式) 0:不发送数据(振幅为0) 1:发送 433.92Mhz 无线波形(载波频率)

EV1527编码芯片介绍

编码芯片是硬件编码,MCU是软件编码,都是输出数据到无线发射芯片 20个位元,可组成不同的编码 4个按键输入,最多可组合15个按键 内含振荡电路,无需外接晶振,通过外接电阻的阻值选择振荡频率 图片中LCK应该是CLK 24个二进制才算一个完整的数据帧,前20位是地址或者叫ID,后4位是按键数据 一次完整的输出需要先输出同步信号,再输出一个数据帧 同步起始信号是4个CLK时间的高电平+124CLK时间的低电平 信号1是12个CLK的高电平+4个CLK的低电平 信号0是4个CLK的高电平+12个CLK的低电平 网上关于CLK的时间均不同,但是应当满足高低电平的比值,具体时间根据容错率决定

模块介绍

遥控器发射,右边接收模块。 遥控器里有发射芯片,功能是编码加按键 接收模块有接收芯片和MCU,二者之间通过某引脚通信,MCU输出各路开关信号,此模块有学习功能,将遥控器的键值存储在MCU中

重点:

编码格式:ev1527或其他发射频率:由晶振频率决定,具体看数据手册

这种键值是没有加密的,传送的都是明文,所以保密性不高,通常用于遥控开关,家具等。当用到安全比较高的场合,这种编码就不可靠了。往往针对这些,我们需要用到其他编码以及数据组合形式。例如曼切斯特编码,has,xxtea,aes等加密方式进行通信。

无线发射芯片

WS4460 是一款集成编码器的真正单晶圆全新一代 OOK 发射 SOC 芯片,可完全兼容 1527 编码产品,支持常用的 315Mhz/433.92Mhz 频率,拥有 4 个独立按键和 6 个组合按键。另外,有一些12路遥控器是通过MCU编码,无线发射芯片调制后发射。按键比较少的遥控器用的是集成IO的无线发射芯片。

编码+无线发射

无线接收芯片

WS490H 是一款高集成度、低功耗的单片 ASK/OOK 射频接收芯片。自动接收并解调信号,通过DO引脚与MCU通信。由MCU解码二进制数据,并输出各路开关量。有些模块上MCU有解码程序,并带学习功能,即将遥控器按键码值存储到MCU中。

编码+无线接收

解码程序

EV1527.c

/**

* @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

#include

#include

#include

/*********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

发射电路原理图

组合按键需要二极管