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、有些芯片在发完最后一个数据位,然后紧接发同步脉冲的高电平,不知道是他们的芯片速度问题还是其他原因,最后一个数据位的低电平时间,要比其他数据位的低电平时间要长。所以,在判断的时候,要特殊关注一下。这个问题在我的解码函数里面有注释。