HX1838红外接收模块-红外遥控(外部中断+状态机)

目录

红外遥控

模块介绍

HX1838红外接收二极管

红外发射遥控器

遥控器键码

模块接线

NEC协议编码

状态机分析

驱动代码

IR.h

IR.c

main.c


红外遥控

红外遥控是利用红外光进行通信的设备,由红外LED将调制后的信号发出,由专用的红外接收头进行解调输出。红外线的波长在可见光范围外,所以人眼是看不到的。

在地球上充满了各种波长的电磁波,所谓的可见(色)光就是人眼可见的电磁波谱,其波长为 380~770nm,为了避免遥控器发射的光造成人眼不适及减少一般人造光源干扰,故选 用人眼不可见的红外线(Infrared)波长,目前业界遥控器发射头几乎都选用 940nm 波长。

模块介绍

总实物图

HX1838红外接收二极管

红外接收二极管,一般为黑色。

红外接收器是一种能够接收红外光信号并将其转换为电信号的元件。在NEC通信协议中,红外接收器会按照协议规定的解码方式,对接收到的红外光信号进行解析,以还原出原始的指令或数据。红外接收头通常被集成在一个元件中,内部包含光敏二极管等关键部件,以及用于信号放大、解调等功能的电路。

HX1838模块是可接收标准38KHz调制的遥控器信号,通过对进行编程,即可实现对遥控器信号的解码操作。它负责将接收红外遥控器发射过来的信息并将其解码成十六进制码,这样才能实现既定的通信。HX1838 红外接收头自带了滤波的功能。

红外发射遥控器

Mini薄红外遥控器,具有17个功能键,发射距离远可达8~10米(红外接收头本身质量,中间有无障碍物等因素会影响到遥控距离)。

红外发光二极管位于遥控器前部,发出的是红外线而不是可见光。它将电信号转换为红外光信号进行发送。这些红外光信号按照NEC协议的编码规则进行调制,以传输特定的指令或数据

发射管红外波长940nm
有效角度60度
晶振频率455KHZ的晶振
载波频率38KHZ
编码格式NEC
尺寸86*40*6mm
面贴材料0.125mmPET,有效寿命2万次
电源CR2025环保纽扣电池/1600mAH
电流静态电流3-5uA,动态电流3-5mA。

注意:使用前一定要记得给红外遥控器装上电池(抽出隔离贴),还有红外遥控器要对着红外接收模块使用


遥控器键码

模块接线

HX1838红外接收模块STM32F103C8T6
VCC3.3V,5V均可
GNDGND
信号输出引脚PA0

信号输出引脚空闲状态为高电平,接收到载波时为低电平

在电路中,需要反向供电,当红外发射二极管开关断开时,接收二极管为截至状态,阻抗无穷大,输出电压为5V,当红外发射二极管发射红外光时,接收二极管阻抗小。

接收不到红外光

接收到红外光

图片来源:一帧红外遥控信号,竟如此复杂,超乎你的想象!红外遥控的工作原理!_哔哩哔哩_bilibili

NEC协议编码

NEC通信协议主要用于红外(Infrared, IR)遥控系统中的电子元件。

NEC通信协议的特点

  • 载波频率:NEC协议使用38kHz的红外线载波进行通信,这使得信号在传输过程中具有较好的抗干扰能力和较远的传输距离。
  • 编码方式:NEC协议采用脉冲位置调制(PPM)的形式进行编码,通过测量脉冲和间隔的时间长度来解码出具体的数据。逻辑“1”和逻辑“0”分别对应不同的脉冲和间隔组合。
  • 数据包结构:NEC协议的数据包由引导码、地址码、地址反码、控制码和控制反码等部分组成。这种结构有助于实现数据的可靠传输和错误校验。


 

红外发射器将信号通过载波发送出来,红外接收器将接收到的红外信号进行电平解码,红外驱动根据这个解码后的电平信号进行解码操作,上图显示了NEC编码的时序规则

Start 表示起始信号,9ms_Low+4.5ms_Hight,表示一次红外传输的开始
Data表示要传输的数据,大小固定为4Bytes,每个数据位由0/1编码构成
560us_Low + 560us_High 代表数据0
560us_Low + 1680us_Hihg 代表数据1
Data的4Bytes数据构成:Address+Address反码+Command+Command反码
Address 厂商定义,一般为0x00
Command 厂商定义,红外遥控建对应的键位码
Repeat 信号 9ms_Low+2.25ms_High,当按键一直按着不放的时候会产生这个重复按键信号
Repeat 在Data后面

状态机分析

Timer.h,Timer.c文件见:HY-SRF05 超声波测距模块-CSDN博客

0.空闲状态:若处于空闲状态,则开启计时,进入等待信号状态

1.等待信号状态:取出计时器数据后清0,判断信号为Start信号还是Repeat信号,若为Start信号,则进入读取数据状态;若为Repeat信号,则将IR_Replag置1,停止计时,回到空闲状态

2.读取数据状态:取出计时器数据后清0,判断信号为"0"信号还是"1"信号,对应位赋值(难点),然后i+1;若i加至32,则已完成数据读取,然后将IR_RxData清0,检验数据是否正确(反码取反),若正确,将地址和命令分别存至IR_Address和IR_Command,随后计时器停止,返回空闲状态

误差:由于程序运行等原因,计时器的时间是有一定误差的,因此我们在判断时要对准确时间前后留有余量;若超出这个范围(出现错误),则返回等待信号状态;

图片来源:单片机学习(十)红外遥控与外部中断 - CodeReaper - 博客园 (cnblogs.com)

驱动代码

IR.h

#ifndef       _IR_H_
#define		  _IR_H_//按键
#define IR_POWER		0x45
#define IR_MODE			0x46
#define IR_MUTE			0x47
#define IR_START_STOP	0x44
#define IR_PREVIOUS		0x40
#define IR_NEXT			0x43
#define IR_EQ			0x07
#define IR_VOL_MINUS	0x15
#define IR_VOL_ADD		0x09
#define IR_0			0x16
#define IR_RPT			0x19
#define IR_USD			0x0D
#define IR_1			0x0C
#define IR_2			0x18
#define IR_3			0x5E
#define IR_4			0x08
#define IR_5			0x1C
#define IR_6			0x5A
#define IR_7			0x42
#define IR_8			0x52
#define IR_9			0x4Avoid IR_Init(void);uint8_t IR_GetKey(void);
uint8_t IR_GetAddress(void);
uint8_t IR_GetCommand(void);#endif

IR.c

#include "stm32f10x.h"                  // Device header
#include "IR.h"
#include "Timer.h"uint8_t IR_RepFlag=0;
uint8_t IR_RxFlag=0;
uint8_t IR_RxData[4];
uint8_t IR_Address=0;
uint8_t IR_Command=0;void IR_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_Init(&EXTI_InitStructure);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);Timer_Init();
}uint8_t IR_GetKey(void)
{if(IR_RepFlag || IR_RxFlag){IR_RepFlag=0;IR_RxFlag=0;return 1;}return 0;}uint8_t IR_GetAddress(void)
{return IR_Address;
}uint8_t IR_GetCommand(void)
{return IR_Command;
}void EXTI0_IRQHandler(void)
{uint16_t time=0;static uint8_t i=0;static uint8_t IR_State=0;if (EXTI_GetITStatus(EXTI_Line0) == SET){if(IR_State==0){TIM2->CNT=0;TIM_Cmd(TIM2, ENABLE);IR_State=1;}else if(IR_State==1){time=TIM2->CNT;TIM2->CNT=0;if(time>13500-500 && time<13500+500)  //13000~14000us{IR_State=2;}else if(time>11250-500 && time<11250+500) //10750~11750{IR_RepFlag=1;TIM_Cmd(TIM2, DISABLE);IR_State=0;}else{IR_State=1;}}else if(IR_State==2){time=TIM2->CNT;TIM2->CNT=0;if(time>1120-500 && time<1120+500)  //620~1620us{IR_RxData[i/8]&=~(0x01<<(i%8));i++;}else if(time>2250-500 && time<2250+500)//1750~2750{IR_RxData[i/8]|=0x01<<(i%8);i++;}else{IR_State=1;i=0;}if(i==32){i=0;if(IR_RxData[0] == (uint8_t)~IR_RxData[1] && IR_RxData[2] == (uint8_t)~IR_RxData[3]){IR_Address = IR_RxData[0];IR_Command = IR_RxData[2];IR_RxFlag=1;}TIM_Cmd(TIM2, DISABLE);IR_State=0;}}EXTI_ClearITPendingBit(EXTI_Line0);}
}

main.c

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "IR.h"uint8_t Address=0;
uint8_t Command=0;int main(void)
{OLED_Init();IR_Init();OLED_ShowString(1,1,"Address:xx");OLED_ShowString(2,1,"Command:xx");while (1){if(IR_GetKey()){OLED_ShowHexNum(1,9,IR_GetAddress(),2);OLED_ShowHexNum(2,9,IR_GetCommand(),2);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/51395.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity + Hybridclr + Addressable + 微信小程序 热更新报错

报错时机&#xff1a; Generate All 怎么All 死活就是报错 生成微信小程序&#xff0c;并启动后 报错内容&#xff1a; MissingMethodException:AoT generic method notinstantiated in aot.assembly:Unity.ResourceManager:dll, 原因&#xff1a; Hybridclr 开发文档 解…

SSL/TLS和SSL VPN

1、SSL/TLS SSL安全套接字层&#xff1a;是一种加密协议&#xff0c;用于在网络通信中建立安全连接。它在应用层和传输层&#xff08;TCP/IP&#xff09;之间提供数据加密、服务器身份验证以及信息完整性验证 SSL只保护TCP流量&#xff0c;不保护UDP协议 TLS&#xff1a;传输层…

成为git砖家(4): git status 命令简介

1. untracked 和 tracked 状态 Remember that each file in your working directory can be in one of two states: tracked or untracked. Tracked files are files that were in the last snapshot, as well as any newly staged files; they can be unmodified, modified, o…

Nginx周末部署

背景 Nginx是本人学习的一类中间件&#xff0c;上次完成了vue的搭建&#xff0c;所以顺便把项目加入Nginx吧 1. 镜像拉取与测试 查询dockerHub&#xff0c;选择最新最稳定的版本 docker pull nginx:stable-perl 执行下载 docker run -d --name mynginx -p 8080:80 -v D:\IM…

基于bert的自动对对联系统

目录 概述 演示效果 核心逻辑 使用方式 1.裁剪数据集 根据自己的需要选择 2.用couplet数据集训练模型 模型存储在model文件夹中 3.将模型转换为ONNX格式 4.打开index.html就可以在前端使用此自动对对联系统了。 本文所涉及所有资源均在传知代码平台可获取。 概述 这个生成器利用…

面完英伟达算法岗,心态崩了。。。

最近这一两周看到不少互联网公司都已经开始秋招提前批了。不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球友解…

DS1302时钟芯片全解析——概况,性能,MCU连接,样例代码

DS1302概述&#xff1a; 数据&#xff1a; DS1302是一个可充电实时时钟芯片&#xff0c;包含时钟&#xff08;24小时格式或12小时格式&#xff09;、日历&#xff08;年&#xff0c;月&#xff0c;日&#xff0c;星期&#xff09;、31字节RAM&#xff08;断电数据丢失&#x…

Fantastic-admin:Vue 中后台管理系统

Fantastic-admin&#xff1a;Vue 中后台管理系统 在当今的前端开发世界里&#xff0c;fantastic-admin 作为一款功能强大的 Vue 中后台管理系统框架&#xff0c;简直是开发者的福音。本文将介绍 fantastic-admin 的基本信息、特点&#xff0c;以及如何快速上手和使用。 项目简介…

面试场景题系列--(4)设计一个支持敏感数据存储和传输安全的加解密平台--xunznux

文章目录 设计一个支持敏感数据存储和传输安全的加解密平台1. 设计背景2. 需求分析日常开发中的加解密程序常见问题解决方案具体来说系统主要用例过程和功能系统需求 3. 概要设计3.1 部署模型3.2 加解密调用流程 4. 详细设计4.1 密钥领域模型4.2 核心服务类设计4.3 加解密数据接…

WSL for Windows

1、安装 超详细Windows10/Windows11 子系统&#xff08;WSL2&#xff09;安装Ubuntu20.04&#xff08;带桌面环境&#xff09;_wsl安装ubuntu20.04-CSDN博客https://blog.csdn.net/weixin_44301630/article/details/122390018 注意&#xff0c;安装之后首次启动 Ubuntu 时&…

【Web开发手礼】探索Web开发的魅力(十二)-Vue(2)用户动态页面

前言 主要介绍了用vue框架创建用户动态页面的具体过程&#xff0c;可以帮助学习vue框架的基本知识&#xff01;&#xff01;&#xff01;&#xff01; 用户动态页面 用户信息 用户头像 通过 Bootstrap 所提供的 .img-fluid 类让图片支持响应式布局。其原理是将 max-width: 10…

三子棋小程序

一.自定义头文件(game.h) 放入源文件需要用到的标准库头文件和函数的声明 ROW 和COL为棋盘的行和列&#xff0c;三子棋嘛&#xff0c;肯定为3啦 #pragma once #include<stdio.h> #include<String.h> #include<stdlib.h> #include<time.h> #define ROW…

《Java初阶数据结构》----10.<Map和Set---TreeSet和TreeMapHashSet和HashMap >

前言&#xff1a; 大家好&#xff0c;我目前在学习java。我准备利用这个暑假&#xff0c;来复习之前学过的内容&#xff0c;并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区进行讨论&#xff01;&#xff01;&#xff01; 喜欢我文…

C/C++大雪纷飞代码

目录 写在前面 C语言简介 EasyX简介 大雪纷飞 运行结果 写在后面 写在前面 本期博主给大家带来了C/C实现的大雪纷飞代码&#xff0c;一起来看看吧&#xff01; 系列推荐 序号目录直达链接1爱心代码https://want595.blog.csdn.net/article/details/1363606842李峋同款跳…

【LeetCode】141.环形链表、142. 环形链表 II(算法 + 图解)

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;数据结构 &#x1f4da;本系列文章为个人学…

AI学习记录 - 本地知识库实现的相关知识

在公司内部实现了个知识库&#xff0c;但这里只介绍在实现知识库的过程中用到的知识。 1、分词器 先分词&#xff0c;中文可以使用jieba分词 2、构造数据集 将词汇向量化是自然语言处理中的重要任务&#xff0c;它可以将文本数据转化为计算机能够理解和处理的向量形式。以…

在react中如何计算本地存储体积

1.定义useLocalStorageSize钩子函数 // 计算localStorage大小 function useLocalStorageSize() {const [size, setSize] useState(0);useEffect(() > {const calculateSize () > {let totalSize 0;for (let key in localStorage) {//过滤掉继承自原型链的属性if (loc…

抄作业-跟着《React通关秘籍》捣鼓React-playground-上集

文章目录 前言1. 搭建react 开发环境2、react hooks 知识3. 目标&#xff1a;跟着小册实现 react-playground3.1 整体布局初始化项目使用Alloment 来实现左右分屏的拖拉功能 3.2 代码编辑器Monaco Editor 3.3 实现了多文件的切换用 useContext 来共享数据。优化 tab的样式&…

扫雷游戏小程序

目录 一.文件 1.头文件 2.源文件 二.游戏界面和执行(test.c) 三.函数实现(void game部分,源文件game.c) 1.定义雷二维数组和展示二维数组 2.初始化地雷数组 3.初始化显示的数组 4.显示当前的情况 5.随机放置地雷 6.排雷 ps:深度优先遍历数组 四.结束 一.文件 1.头…

《Single-Stage Extensive Semantic Fusion for multi-modal sarcasm detection》

系列论文研读目录 文章目录 系列论文研读目录文章题目含义ABSTRACTKeywords1. Introduction2. Related work3. Method3.1. Multi-modal projection 多模态投影3.2. Extensive Semantic Fusion Multiway Transformer 可拓语义融合多路Transformer3.3. Multi-objective optimizat…