STM32使用HAL库解码433遥控芯片EV1527

1、首先了解一下433遥控芯片ev1527的基本资料:

这是他编码的关键信息:
在这里插入图片描述
也就是说,一帧数据是:一个同步码+20位内码+4位按键码。
内码20位=2^20=1048576个地址。
发送就是一帧数据接一帧数据不间断发送。

2、解码思路

从上面的帧结构来分析,我的解码思路是:
1、STM32单片机配置一个引脚中断,设置为上下沿触发
2、单片机配置1个定时器,用于记录时间
3、抓住关键特征,可以看到,同步码是一帧数据的开头,它的特征是124CLK的低电平时间,所以:
3.1、测量这一帧数据的低电平时间,
3.2、如果低电平时间为124clk,就认为收到同步码,接下来要开始收数据码
3.3、收到同步码后,不断测量数据码的低电平时间,并存入BUF[24]这个数组,
3.4、接收完24个低电平后,一帧数据接收完毕。如果中途接收到同步码,就从头开始接收数据码。
3.5、解码:DATA(H)的低电平是4CLK,DATA(L)的低电平是12CLK,分析数组中的低电平时间,就可以完成解码。

3、配置

定时器配置:
在这里插入图片描述
IO口配置为上下边沿触发
在这里插入图片描述
记得打开中断
在这里插入图片描述

4、程序编写

首先头文件:

#ifndef __EV1527_H
#define __EV1527_H

#include "main.h"

typedef struct
{
	uint8_t ucRecOK;	/*接收成功*/
	uint8_t ucKeyCode;	/*按键码*/
	uint32_t ulChipID;	/*芯片ID*/
	uint16_t usaLowTime[24];/*24位低电平数据时间长度*/
}ev1527Type_T;

extern ev1527Type_T g_tEV1527Rx;

void EV1527_Decode(ev1527Type_T *tpEV1527);/*EV1527解码*/
#endif

再C文件:

#include "ev1527.h"
#include "tim.h"

ev1527Type_T g_tEV1527Rx;

/*
******************************************************
* 说明:PA0引脚中断回调函数,上下边沿中断配合定时器1,统计低脉冲宽度,因为引导码的特征值是低脉冲宽度是124CLK。
* 输入:
* 输出:
******************************************************
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	uint16_t usPortLevel;
	uint16_t usLowTime;
	static uint8_t ucLeadCodeFind = 0;
	static uint8_t ucTimePos;	
	
	usPortLevel = GPIOA->IDR & 0X0001;
	
	if(usPortLevel)/*上升沿,完成低脉冲检测*/
	{
		usLowTime = __HAL_TIM_GetCounter(&htim1);
		__HAL_TIM_DISABLE(&htim1);
		
		if(usLowTime > 9920 &&  usLowTime < 14880)/*引导码,12400,误差20%*/
		{
			ucLeadCodeFind = 1;
			ucTimePos = 0;
		}
		/*可先进行低电平时间判断,滤除杂波干扰*/
		else/*其他低脉冲*/
		{
			if(ucLeadCodeFind)/*只有找到引导码的情况下,才进行数据接收*/
			{
				g_tEV1527Rx.usaLowTime[ucTimePos++] = usLowTime;
				if(ucTimePos >= 24)
				{
					ucTimePos = 0;
					ucLeadCodeFind = 0;
					g_tEV1527Rx.ucRecOK = 1;/*置位接收完成标志*/
				}
			}
		}
	}
	else/*下降沿,启动低脉冲宽度检测*/
	{
		__HAL_TIM_SetCounter(&htim1,0);	
		__HAL_TIM_ENABLE(&htim1);
	}
}
/*
******************************************************
* 说明:解码EV1527,使用低电平时间判断,低电平280-520ms之内,判断为1,否则为0;
* 输入:tpEV1527指针,解码完毕后,赋值到指向的结构体中的按键码和芯片ID;
* 输出:
******************************************************
*/
void EV1527_Decode(ev1527Type_T *tpEV1527)
{
	uint8_t i;
	uint32_t ulCombinedCode = 0;
	
	for(i=0; i< 24; i++)/**/
	{
		ulCombinedCode <<= 1; 
		/*
		* 400us,误差±30%。
		* 示波器实测最后一位的低电平时间比其他位的低电平时间要长,可考虑增加宽度。
		* 可能是发射芯片发射完最后一位后,转入到引导脉冲所需时间比较长导致。
		*/
		if(tpEV1527->usaLowTime[i] > 280 && tpEV1527->usaLowTime[i] < 520)
		{
			ulCombinedCode |= 0x01;
		}
	}
	tpEV1527->ucKeyCode = ulCombinedCode & 0x0000000f;
	tpEV1527->ulChipID = (ulCombinedCode & 0xfffffff0) >> 4;
}


文件说明:
在这里插入图片描述
接收一帧数据后,就是解码了
在这里插入图片描述
注释已经写得非常明白了。

5、使用

直接在main函数里面判断是否接收完成,然后调用解码即可:

        if(g_tEV1527Rx.ucRecOK)
        {
            g_tEV1527Rx.ucRecOK = 0;
            EV1527_Decode(&g_tEV1527Rx);			
        }

实际解码如下图:
在这里插入图片描述
在这里插入图片描述

6、写在最后

1、直接示波器测量4CLK的时间长度,不要用计算振荡电阻的结果。
2、有些芯片在发完最后一个数据位,然后紧接发同步脉冲的高电平,不知道是他们的芯片速度问题还是其他原因,最后一个数据位的低电平时间,要比其他数据位的低电平时间要长。所以,在判断的时候,要特殊关注一下。这个问题在我的解码函数里面有注释。

相关推荐

  1. STM32-寄存器和HAL以及如何使用

    2024-04-26 19:06:03       50 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-26 19:06:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-26 19:06:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-26 19:06:03       87 阅读
  4. Python语言-面向对象

    2024-04-26 19:06:03       96 阅读

热门阅读

  1. 1.mysql--常用sql(2)

    2024-04-26 19:06:03       28 阅读
  2. 【C++刷题】优选算法——动态规划第五辑

    2024-04-26 19:06:03       37 阅读
  3. leetcode2418.按身高排序

    2024-04-26 19:06:03       34 阅读
  4. 虚拟机部署openeuler网络配置

    2024-04-26 19:06:03       36 阅读
  5. npm install CERT_HAS_EXPIRED解决方法

    2024-04-26 19:06:03       38 阅读
  6. BootLooder引导传参和镜像编译

    2024-04-26 19:06:03       30 阅读