华芯微特SWM34-使用定时器捕获快速解码EV1527编码
在无线应用领域,很多433Mhz和315Mhz的遥控器,红外探测器,门磁报警器,无线门铃等都使用EV1527编码格式来发射数据。发射和接收均有对应的RF芯片完成,而且成本极低(目前市场价3毛钱不到)。接收芯片解调出来数据后,需要进行编码的解码,分离地址码和数据码,以便后续代码使用。
EV1527的编码格式如下:


需要特别注意点:
- 一帧数据由三个部分组成:同步码,地址码(20bit),数据位(4bit)
- 同步码:4个clock的高电平时间+124个clock的低电平时间。
- 数据1:12个clock的高电平时间+4个clock的低电平时间。
- 数据0:4个clock的高电平时间+12个clock的低电平时间。
- 同步码和数据码的脉冲宽度不是用时间来描述的,而是用时钟周期的个数来描述。这就说明,即使用相同的发射芯片,由于使用不同的振荡电阻和制造工艺,pcb走线的不同也会导致脉冲的时间是不同的。但是对于同样工艺,同样设计的pcb,同样芯片的不同产品之间量产具有一致性(同一批产品具有一致性)。
有了以上的基本知识后,我们有两个思路来进行解码:
一. 使用边沿中断加定时器的方式解码.–适合低端单片机,解码复杂。
二. 使用带有脉冲捕获功能的定时器解码。–解码简单。
我们以华芯微特SWM341为例子来讲解如何快速解码:
先定义各个编码的脉冲时间参数(要根据你的发射器实际测量来调整),并且可以允许一定的误差,本项目允许±10%的时间误差(一般的发射器时钟误差小于3%)。
#define EV1527_H4 328 //窄脉冲基本宽度 us,不同的遥控器要实测后确定
#define EV1527_H4_MIN (EV1527_H4 *90 / 100)
#define EV1527_H4_MAX (EV1527_H4 *110 / 100)#define EV1527_H12 998 //宽脉冲基本宽度 us,不同的遥控器要实测后确定
#define EV1527_H12_MIN (EV1527_H12 *90 / 100)
#define EV1527_H12_MAX (EV1527_H12 *110 / 100)#define EV1527_L4 EV1527_H4 //宽脉冲基本宽度 us
#define EV1527_L4_MIN (EV1527_L4 *90 / 100)
#define EV1527_L4_MAX (EV1527_L4 *110 / 100)#define EV1527_L12 EV1527_H12 //宽脉冲基本宽度 us
#define EV1527_L12_MIN (EV1527_L12 *90 / 100)
#define EV1527_L12_MAX (EV1527_L12 *110 / 100)#define EV1527_SYN_L (11981-328) // 同步脉冲低时间,高时间=EV1527_H4
#define EV1527_SYN_MIN (EV1527_SYN_L *90 / 100)
#define EV1527_SYN_MAX (EV1527_SYN_L *110 / 100)
初始化一个带有捕获功能的定时器,测量时间基本单位为1us:
//增强定时器0,捕获应用
void Timer0Init(void)
{PORT_Init(PORTB, PIN15, PORTB_PIN15_TIMR0_IN, 1); //pb15,timer0 in for captureTIMR_Init(TIMR0, TIMR_MODE_IC, CyclesPerUs, 0xFFFFFF, 0);TIMR_IC_Init(TIMR0, 1, 1);TIMR_Start(TIMR0);
}
定义几个变量:
static uint32_t highCnt = 0 ,lowCnt = 0; //脉冲的高电平和低电平时间
static uint32_t syn = 0,code = 0,pulseCnt = 0; //同步标志,解码后的code,解码过程中的bit计数
//解码错误后的恢复
static void EV1527Reset(void)
{highCnt = 0;lowCnt = 0;syn = 0;code = 0;pulseCnt = 0;
}
收到一个有效位后的解码:
static void EV1527Decode(uint32_t v)
{code <<= 1;if(v){code |= 1;}pulseCnt++;
// DebugPrintf("c: %d,p= %d \r\n", v,pulseCnt);if(pulseCnt == 24){//这里可以根据需要,做不同处理://1. 连续两帧码值相同判定为一次有效码//2. 一直是同一个编码的话(中间没有被打断或者停止过),就只有第一次发送,后面的不发送。//3. 如果有需要持续按键的应用(比如按住按键调光),可以在满足第一个条件后持续的向上层发送编码信息//4. 通过消息队列将解码后的数据发送到应用DebugPrintf("Addr: %d,code= %d\r\n", code >> 4,code & 0x000000FF);EV1527Reset();}
}
捕获中断的处理,也就是一个bit(一个高电平和一个低电平)的解码,每一个脉冲的电平翻转都会产生一次中断,也就能获取到高低电平的持续时间:
void TIMR0_Handler(void)
{if(TIMR_IC_CaptureH_INTStat(TIMR0)){//脉冲的下降沿中断,也就是高电平结束了TIMR_IC_CaptureH_INTClr(TIMR0);highCnt = TIMR_IC_GetCaptureH(TIMR0);}else if(TIMR_IC_CaptureL_INTStat(TIMR0)){//脉冲的上升沿中断,也就是低电平结束了TIMR_IC_CaptureL_INTClr(TIMR0);lowCnt = TIMR_IC_GetCaptureL(TIMR0);if(syn == 1){//收到同步码后才解码if( (lowCnt > EV1527_L4_MIN) && (lowCnt < EV1527_L4_MAX)){if((highCnt > EV1527_H12_MIN) && (highCnt < EV1527_H12_MAX)){ //现在是一个短脉冲,前面必定是一个有效的长脉冲,数据为1,否则就是一个错误脉冲EV1527Decode(1);}else{EV1527Reset(); //有错误}}else if((lowCnt > EV1527_L12_MIN) && (lowCnt < EV1527_L12_MAX)){if((highCnt > EV1527_H4_MIN) && (highCnt < EV1527_H4_MAX)){ //现在是一个长脉冲,前面必定是一个有效的短脉冲,数据为0,否则就是一个错误脉冲EV1527Decode(0);}else{EV1527Reset(); //有错误}}}else {if((lowCnt > EV1527_SYN_MIN) && (lowCnt < EV1527_SYN_MAX)){//有满足同步脉冲特征的低电平出现了if((highCnt > EV1527_H4_MIN) && (highCnt < EV1527_H4_MAX)){ //并且前面是一个有效的同步高脉冲,同步开始(也可能是一个误码)syn = 1;pulseCnt = 0;code = 0;
// DebugPrintf("syn: %d\r\n", lowCnt);}}}}
}
解码程序短小精悍,有几个技巧说明如下:
- 由于无线模块会不断输出其他非规则的干扰脉冲,我们需要在中断中快速的处理,降低CPU的负荷。
- 根据ev1527的编码特征,我们可以知道无论是同步码还是数据1和数据0,必定是一个高电平后接一个低电平脉冲, 所以高电平结束我们只记录脉宽不做解码,解码在低电平结束后进行。3.
- 快速解码的处理方法:先寻找同步脉冲,只有同步脉冲出现后才继续解码后面的有效数据,否则都是干扰数据。
- 有同步脉冲后,我们只需要判定低电平脉冲的宽度,然后结合前一个高电平脉冲的宽度就能确定是数据位1还是0.
- 要考虑干扰和脉冲丢失的情况,如果出现这种情况,就复位相关变量,丢弃当前帧。等待下一帧数据再次解码。
- 因为EV1527编码并不带有任何数据校验位,为了保证数据的可靠性,我们通常会连续接收两帧数据,确认数据相同,才认为是一个有效的数据。
- 解码完成一帧数据后,可以根据各自的应用不同做后续处理。
原创文章,欢迎转载,请注明来源,未经书面允许,请勿用于商业用途。
关注微信公众号:嵌入式开发实战营,了解更多。某宝搜索<新龙电子>或者<新龙微科技>了解相关产品应用
相关文章:
华芯微特SWM34-使用定时器捕获快速解码EV1527编码
在无线应用领域,很多433Mhz和315Mhz的遥控器,红外探测器,门磁报警器,无线门铃等都使用EV1527编码格式来发射数据。发射和接收均有对应的RF芯片完成,而且成本极低(目前市场价3毛钱不到)。接收芯片…...
小程序安卓手机点击uni-data-select 下拉框选择器会出现蓝色阴影
解决方法:在导入的包中找到uni-data-select.vue,接着找到.uni-stat__select样式,把cursor: pointer去掉。 如果出现穿透问题,uni-select__selector的z-index加高,默认是2。...
playwright vscode 插件源码解析
Playwright vscode插件主要功能 Playwright是微软开发的一款主要用于UI自动化测试的工具,在vscode中上安装playwright vscode插件,可以运行,录制UI自动化测试。 playwright vscode插件主要包括两块功能,功能一是在Test Explorer中…...
Mysql: SQL-DDL
一.SQL通用语法 1.SQL可以单行或者多行书写,以分号结尾。 2.SQL语句可以使用空格/缩进来增强语句的可读性。 3.MySQL数据库的SQL语句不区分大小写,关键字建议用大写。 4.注释: 单行注释:注释内容或#注释内容(Mysql特有) 多行注释:/*注释内容*/ 二.SQL分类 1.D…...
Java中的加密与解密:实现安全的数据传输
Java中的加密与解密:实现安全的数据传输 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!在当今信息安全至关重要的时代,保护数据的安全性…...
基于SSM的美食推荐系统
文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SSM的美食推荐系统,java项目。 ecli…...
Pycharm利用Anaconda环境
创建环境 conda create --name d2l python3.11 -y 激活环境 conda activate d2l 配置环境 以torch环境为例 我们可以按如下⽅式安装PyTorch的CPU或GPU版本: pip install torch pip install torchvision 我们的下⼀步是安装d2l包,以⽅便调取本书中经…...
Python函数魔术:深入理解18个高级函数特性
今天,我们将一起探索那些让代码瞬间变得优雅而强大的高级函数。准备好,让我们一起揭开它们的神秘面纱吧! 1. map():一招制胜,批量操作 想象一下,你需要给一个数字列表的每个元素加上5。普通的循环是不是让…...
在大型单页应用(SPA)中,如何处理状态管理的
在大型单页应用(SPA)中,如何处理状态管理的 在大型单页应用(SPA)中,状态管理是一个关键环节,确保数据的一致性和可预测的变更。以下是一些常见的状态管理方法: Redux: …...
力扣78 子集
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的 子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入:nums [1,2,3] 输出:[[],[1],[2],[1,2],[3],…...
C语言从头学24——函数原型
前面学习函数时已经知道必须先存在一个函数然后才能使用,且这个函数的位置还要在 main()函数之前,否则的话编译时会报错。但我们写程序时,main() 函数是程序入口,程序的主要部分都在 main() 函数中,且其它函数也都要通…...
Vue中使用ElementUI组件Form组件的校验validate
先准备一些el-form元素 这里面el-form中:model(v-bind:model)是单项绑定的,如果你写成了v-model""可能会出现校验没有效果的情况。 这是校验过后的结果了 现在开始使用下吧! 1.在el-form中绑定一个ref,名字自拟,后续触发检验结果…...
PostgreSQL性能优化之分区表 #PG培训
在处理大规模数据时,PostgreSQL的性能优化是一个非常重要的话题,其中分区表(Partitioned Tables)是提高查询和数据管理效率的重要手段。本文将详细介绍PostgreSQL分区表的概念、优势、创建与管理方法以及一些常见的优化策略。 #P…...
SAPUI5基础知识9 - JSON Module与数据绑定
1. 背景 在前面的博客中,我们已经学习了SAPUI5中视图和控制器的使用,在本篇博客中,让我们学习下MVC架构中的M-模型了。 SAPUI5中的JSON Model是一个客户端模型,可以用于在SAPUI5应用程序中处理和操作JSON数据。SAPUI5提供了绑定…...
解决vue3使用ref 获取不到子组件属性问题
需求: 父子组件使用<script setup>语法糖,父组件通过给子组件定义ref访问子组件内部属性或事件。 关键点: 子组件中,setup语法糖需要用defineExpose把要读取的属性和方法单独暴露出去,否则会访问失败…...
使用STL容器还是Qt容器?
在C编程中,选择合适的容器库对于编写高效、可维护的代码至关重要。两大主流选择是STL容器(如std::map,std::vector等)和Qt容器(如QMap,QVector等)。本文将探讨两者的优缺点,以帮助开…...
Android 2ndBLE的实现
没有需求创造需求 有没有想过一件事情,假如你的手机关机了,而且在家里怎么都找不到的情况? 那么通过另外一种手机进行查找是不是可以?听上去有点搞笑,但实际上确实有这样的需求存在。实现方案是用超低功耗蓝牙&#…...
常见硬件工程师面试题(二)
大家好,我是山羊君Goat。 对于硬件工程师,学习的东西主要和电路硬件相关,所以在硬件工程师的面试中,对于经验是十分看重的,像PCB设计,电路设计原理,模拟电路,数字电路等等相关的知识…...
java构造方法的重载
在java中,与普通方法一样,构造方法也可以重载,在一个类中可以定义多个构造方法,但是要求每个构造方法的参数类型或参数不同。在创建对象时,可以通过调用不同的构造方法为不同属性赋值。 示例代码如下 class Student5…...
webpack 压缩图片
压缩前: 压缩后: 压缩后基本上是压缩了70-80%左右 1.依赖版本及配置 "imagemin-webpack-plugin": "^2.4.2", "imagemin-mozjpeg": "^7.0.0", "imagemin-pngquant": "^5.0.1", "webpa…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
