当前位置: 首页 > news >正文

STM32定时器实现红外接收与解码

1.NEC协议

         红外遥控是一种比较常用的通讯方式,目前红外遥控的编码方式中,应用比较广泛的是NEC协议。NEC协议的特点如下:

  1. 载波频率为 38KHz
  2. 8位地址和 8位指令长度
  3. 地址和命令2次传输(确保可靠性)
  4. PWM 脉冲位置调制,以发射红外载波的占空比代表“0”和“1”

        其逻辑1与逻辑0的表示如图所示

        可以看到,逻辑1的位时间为2.25ms,脉冲时间560us;逻辑0的位时间为1.12ms,脉冲时间560us。

        一个完整的NEC数据包如下:

        首次发送的是9ms高电平+4.5ms低电平,为引导码。

        接下来是8bit的地址码+8bit地址码的反码+8bit命令码+8bit命令码的反码。

        以上是一个正常的数据包,但可能存在一种情况:当长按某个键时,发送的是以110ms为周期的重复码,如下图:

        重复码由9ms高电平和2.25ms的低电平以及560us的高电平组成

2.解码程序

        在上面的图中可以看到,逻辑1和逻辑0的位时间是不同的,占空比也不同。所以我们可以根据位时间的长短来解码,也可以根据占空比的不同(1/2或1/4)来解码,或者二者同时作为解码条件。这里我们介绍根据位时间来解码。

        需要注意的是,很多红外一体接收头为了提高接受灵敏度。输入高电平,其输出的是相反的低电平。下图为示波器实际捕获的一组数据:

 

        可以看到,空闲时为高电平,引导码为9ms低电平+4.5ms高电平。根据位时间解码的话,我们就不必关系高低电平各自的时间,只需关系总时间就行,即:引导码-13.5ms,逻辑1-2.25ms,逻辑0-1.12ms。

        首先用STM32CubeMx配置定时器。系统时钟等的配置这里不在赘述,参考其它教程。

        这里使用TIM3的Channel1作为捕获通道配置如下:

  1. 定时器时钟为内部时钟
  2. Channel1配置为输入捕获模式
  3. 分频系数为63,因为系统时钟为64M,这样定时器实际时钟为64/(63+1)=1M,主要是为了程序中方便计算。
  4. 捕获方式为下降沿捕获
  5. 最后别忘了打开定时器的中断

        最后生成代码。在生成的TIM3中断函数中,屏蔽生成的中断处理还是,添加自己的解码程序如下:

uint32_t TIM3_Over_Cnt = 0;//tim3溢出次数
uint32_t TIM3_Sum_Cnt = 0;//两次下降沿之间的时间间隔
uint32_t cnt0 = 0;
uint8_t IR_Data[60];void TIM3_IRQHandler(void)
{/* USER CODE BEGIN TIM3_IRQn 0 *//* USER CODE END TIM3_IRQn 0 */
//  HAL_TIM_IRQHandler(&htim3);/* USER CODE BEGIN TIM3_IRQn 1 */if(__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_UPDATE))      //定时器溢出中断{__HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_UPDATE);    //清除中断标记TIM3_Over_Cnt++;}cnt0 = __HAL_TIM_GET_COUNTER(&htim3);TIM3_Sum_Cnt = (TIM3_Over_Cnt << 16) + cnt0;//获取计数器的值__HAL_TIM_SetCounter(&htim3,0);//清零重新计数TIM3_Over_Cnt = 0;//清零重新计数if (__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_CC1) != RESET)//TIM3CH1捕获中断{if(StartRevFlag == 1)//接收到引导码,开始解码{if(TIM3_Sum_Cnt > 36000)//大于36ms认为是结束{RevComplete = 1;//解码完成IR_Tick = 0;}else if(RevComplete == 0){if(TIM3_Sum_Cnt > 1000 && TIM3_Sum_Cnt < 1300)//1ms~1.3ms认为是低电平IR_Data[IR_Idx] = 0;else  if(TIM3_Sum_Cnt > 2100 && TIM3_Sum_Cnt < 2400)//2.1ms~2.4ms认为是高电平IR_Data[IR_Idx] = 1;else //接收错误,重新开始StartRevFlag = 0;IR_Idx++;if(IR_Idx > 59)IR_Idx = 59;}}else{if(TIM3_Sum_Cnt > 13000 && TIM3_Sum_Cnt < 14000)//13~14ms引导码{StartRevFlag = 1;}IR_Tick = 0;RevComplete = 0;//解码完成标志置零IR_Idx = 0;//有效解码位TIM3_Over_Cnt = 0;TIM3_Sum_Cnt = 0;//定时器计数清零}__HAL_TIM_CLEAR_IT(&htim3, TIM_IT_CC1);}/* USER CODE END TIM3_IRQn 1 */
}

        解码程序根据每次捕获下降沿之间的间隔判断是引导码还是逻辑1或逻辑0。接收到引导码之后,再开始将解码的数据保存下来。最后通过也是时长来判断解码结束。这里没有判断重复码,有兴趣的小伙伴可以自己加上。

         中断函数中,只是将每一位解码并保存,最后还需要在主程序中组合成字节并判断处理。

void IR_Rev()
{uint8_t num = IR_Idx / 8;uint8_t IRValue[8];if(RevComplete == 1 && StartRevFlag == 1 && IR_Tick > 20){if(num > 7)num = 7;for(uint8_t j=0;j<num;j++)//将每一位解码数据组合成字节数据{for(uint8_t i = 0;i< 8;i++){IRValue[j] = IRValue[j]>>1;if(IR_Data[j*8+i])IRValue[j] |= 0x80;}}if(IRValue[0] == 0x00 && IRValue[1] == 0xFF)//地址码正确{switch(IRValue[2])//判断数据码{case 0x46:KeyValue = S_key_Menu;break;case 0x43:KeyValue = S_key_Set;break;case 0x40:KeyValue = S_key_Rst;break;case 0x15:KeyValue = S_key_Down;break;case 0x09:KeyValue = S_key_Up;break;}}StartRevFlag = 0;RevComplete = 0;IR_Tick = 0;}
}

       

相关文章:

STM32定时器实现红外接收与解码

1.NEC协议 红外遥控是一种比较常用的通讯方式&#xff0c;目前红外遥控的编码方式中&#xff0c;应用比较广泛的是NEC协议。NEC协议的特点如下&#xff1a; 载波频率为 38KHz8位地址和 8位指令长度地址和命令2次传输&#xff08;确保可靠性&#xff09;PWM 脉冲位置调制&#…...

18- Adaboost梯度提升树 (集成算法) (算法)

Adaboost 梯度提升树: from sklearn.ensemble import AdaBoostClassifier model AdaBoostClassifier(n_estimators500) model.fit(X_train,y_train) 1、Adaboost算法介绍 1.1、算法引出 AI 39年&#xff08;公元1995年&#xff09;&#xff0c;扁鹊成立了一家专治某疑难杂症…...

zlink 介绍

zlink 是一个基于 flink 开发的分布式数据开发工具&#xff0c;提供简单的易用的操作界面&#xff0c;降低用户学习 flink 的成本&#xff0c;缩短任务配置时间&#xff0c;避免配置过程中出现错误。用户可以通过拖拉拽的方式实现数据的实时同步&#xff0c;支持多数据源之间的…...

C++之std::string的resize与reverse

std::string的resize与reverse前言1.resize2.reserve前言 在C中我们经常用std::string 来保存字符串&#xff0c;其中有两个比较常用但是却平时容易被搞混的两个函数&#xff0c;分别是resize和reserve&#xff0c;模糊意识里&#xff0c;这两个方法都是对std::string的容量或元…...

在.net中运用ffmpeg 操作视频

using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Text;namespace learun.util{/// <summary>/// ffmpeg视频相关处理的类/// </summary>public class FFmpegUtil{public static int Run(string cmd){try{//…...

05- 线性回归算法 (LinearRegression) (算法)

线性回归算法(LinearRegression)就是假定一个数据集合预测值与实际值存在一定的误差, 然后假定所有的这些误差值符合正太分布, 通过方程求这个正太分布的最小均值和方差来还原原数据集合的斜率和截距。当误差值无限接近于0时, 预测值与实际值一致, 就变成了求误差的极小值。 fr…...

JAVA补充知识01之枚举enum

目录 1. 枚举类的使用 1.1 枚举类的理解 1.2 举例 1.3 开发中的建议&#xff1a; 1.4 Enum中的常用方法 1.5 熟悉Enum类中常用的方法 1.6 枚举类实现接口的操作 1.7 jdk5.0之前定义枚举类的方式 &#xff08;了解即可&#xff09; 1.8 jdk5.0之后定义枚举类的方式 1…...

jenkins下配置maven

1. 先在jenkins服务器上安装maven 下载-解压-重命名-启动 [rootVM-0-12-centos local]# wget https://mirrors.aliyun.com/apache/maven/maven-3/3.9.0/binaries/apache-maven-3.9.0-bin.tar.gz [rootVM-0-12-centos local]# tar xf apache-maven-3.9.0-bin.tar.gz [rootVM-0…...

春季开学即将到来!大学生活必备数码清单奉上

马上就要开学了&#xff0c;你的返校装备是否已经准备齐全了呢&#xff1f;对于高校学生来说&#xff0c;很多数码产品都属于必备装备&#xff0c;比如下面这几款产品就受到了大量年轻消费者的喜爱&#xff0c;在它们的帮助下能够让大家的学习时光变得更快乐。1、不入耳黑科技骨…...

ubuntu18.04 天选2 R95900hx 3060显卡驱动安装

天选2 R95900hx 3060显卡驱动安装需求问题解决内核集显显卡驱动需求 外接显示器&#xff0c;安装nvidia驱动 问题 由于一开始直接在软件和更新中附加读懂安装了nvidia-470&#xff0c;导致系统黑屏。 解决 grub页面系统选择进入ubuntu recovery模式&#xff0c;选择root&a…...

Harbor安装部署实战详细手册

文章目录前言一、安装docker二、安装docker-compose1.下载2.赋权3.测试三、安装harbor1.下载2.解压3.修改配置文件4.部署5.配置开机自启动6.登录验证7.补充说明四、harbor使用问题1.docker login问题&#xff1a;Error response from daemon: Get https://: http: server gave …...

华为OD机试真题JAVA实现【箱子之形摆放】真题+解题思路+代码(20222023)

🔥系列专栏 华为OD机试(JAVA)真题目录汇总华为OD机试(Python)真题目录汇总华为OD机试(C++)真题目录汇总华为OD机试(JavaScript)真题目录汇总文章目录 🔥系列专栏题目输入输出描述示例一输入输出说明备注解题思路Code运行结果版权说明...

华为OD机试 - 事件推送(Python)| 真题+思路+考点+代码+岗位

事件推送 题目 同一个数轴 X 上有两个点的集合 A={A1, A2, …, Am} 和 B={B1, B2, …, Bn}, Ai 和 Bj 均为正整数,A、B 已经按照从小到大排好序,A、B 均不为空, 给定一个距离 R (正整数), 列出同时满足如下条件的所有(Ai, Bj)数对: Ai <= BjAi, Bj 之间的距离小于…...

【Linux】信号量

&#x1f387;Linux&#xff1a; 博客主页&#xff1a;一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 看似不起波澜的日复一日&#xff0c;一定会在某一天让你看见坚持…...

android-java同步方法和异步方法

接口 Java接口是一系列方法的声明&#xff0c;是一些方法特征的集合&#xff0c;一个接口只有方法的特征没有方法的实现&#xff0c;因此这些方法可以在不同的地方被不同的类实现&#xff0c;而这些实现可以具有不同的行为&#xff08;功能&#xff09;。 两种含义&#xff1a…...

Flask入门(5):请求和响应

目录5.请求和响应5.1 请求5.2 响应5.请求和响应 5.1 请求 request对象封装解析了请求报文中的数据&#xff0c;其大部分功能是由依赖包werkzeug完成的&#xff0c;并且每个request对象都是线程隔离的&#xff0c;保证了数据的安全性。 request对象的属性 1.request.method …...

记进组后第五次组会汇报

2023年2月14日 日记一、小组组会二、实验室组会1、汇报内容&#xff08;1&#xff09;参考文献&#xff08;2&#xff09;CQF机制a.研究现状b.相关思考&#xff08;3&#xff09;研究计划2、汇报反馈一、小组组会 上午十点整&#xff0c;小组组会开始&#xff0c;有两个同学我…...

nil Foundation的Placeholder证明系统(2)

前序博客&#xff1a; nil Foundation的Placeholder证明系统&#xff08;1&#xff09; nil; Foundation团队2022年11月论文《Placeholder证明系统》。[2022年11月29日版本] 8. 优化 8.1 Batched FRI 不同于单独检查每个commitment&#xff0c;可对其进行FRI聚合。如对多项…...

QHash源码解读

QT版本 v5.12.10 元素 // 重点说明QHashData的函数&#xff0c;QHashData是QHash的基础 struct QHashData {struct Node {Node *next;uint h;};Node *fakeNext; // 永为nullNode **buckets; // Node *数组QtPrivate::RefCount ref;int size; // node个数int nodeSize; /…...

【Unity细节】RigidBody中Dynamic和Kinematic的区别

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏&#xff1a;unity细节和bug ⭐Dynamic和Kinematic的区别⭐ 文章目录⭐Dynamic和Kinematic的区别⭐&#x1f3…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...