STM32如何接收红外的信号
STM32如何接收红外的信号
STM32 接收红外信号(主要指来自电视遥控器等设备的红外遥控信号)主要涉及硬件连接和软件解码两个核心部分。以下是详细步骤和关键点:
核心原理: 红外遥控器将按键信息编码(常用 NEC、RC5、Sony SIRC 等协议)后,调制在约 38kHz 的载波上发射出来。STM32 需要:
- 通过 红外接收头 将光信号转换成电信号,并解调(去掉 38kHz 载波)。
- 通过 GPIO 引脚 读取解调后的数字波形。
- 在 软件中解码 该波形,提取出地址码、命令码等信息。
步骤详解:
-
硬件准备与连接:
- 红外接收头模块: 这是必不可少的元件(如 VS1838B, TSOP382xx, HS0038B 等)。它通常有 3 个引脚:
VCC: 接 3.3V 或 5V 电源(确保与 STM32 逻辑电平兼容,推荐 3.3V)。GND: 接地。OUT: 连接到 STM32 的一个 GPIO 引脚。这个引脚需要配置为输入模式。接收头的输出在没有接收到信号时一般是高电平(或上拉到高电平),接收到有效红外信号时,它会随着原始编码信号的高低电平变化。
- STM32 开发板: 如 STM32F103C8T6 (Blue Pill), STM32F407 Discovery, Nucleo 系列等。
- 连接示意图:
[红外接收头] VCC ---- STM32 3.3V GND ---- STM32 GND OUT ---- STM32 GPIOx_Pin_y (e.g., PA0, PB10)
- 红外接收头模块: 这是必不可少的元件(如 VS1838B, TSOP382xx, HS0038B 等)。它通常有 3 个引脚:
-
软件开发(解码): 解码的关键在于准确测量接收头
OUT引脚上高低电平的持续时间。常用方法有:-
方法 1:外部中断 + 定时器(推荐且常用)
- GPIO 配置: 将连接接收头
OUT的 GPIO 引脚配置为 浮空输入或上拉输入 模式。 - 外部中断配置: 使能该引脚的外部中断(EXTI),设置为 双边沿触发(
EXTI_Trigger_Rising_Falling),这样引脚电平每次变化(从高到低或从低到高)都会触发中断。 - 定时器配置: 启用一个基本定时器(如 TIM2)。配置其时钟源(通常内部时钟),设置较高的计数速度和足够长的自动重装载值(ARR)。停止计数 并 清零计数器 作为初始状态。
- 中断服务程序(ISR):
- 当 EXTI 触发(检测到边沿)时:
- 获取定时器当前的计数器值(
TIM_GetCounter())。 - 记录这个时刻(
capture_time = TIM_GetCounter())。
- 获取定时器当前的计数器值(
- 判断边沿类型(上升沿或下降沿):
- 如果是 下降沿(通常代表脉冲开始):记录起始时间
start_time = capture_time。 - 如果是 上升沿(通常代表脉冲结束):记录结束时间
end_time = capture_time,计算本次脉冲的持续时间:pulse_width = end_time - start_time; // 注意处理定时器溢出!
- 如果是 下降沿(通常代表脉冲开始):记录起始时间
- 将
pulse_width与协议规定的时序(引导码、逻辑 0、逻辑 1、重复码等)进行比较,判断当前脉冲代表什么含义(起始位、逻辑位、停止位、重复码)。 - 根据协议规则组装数据位(address, command)。
- 检测到完整的帧(如 NEC 的 32 位)后,进行校验(如 NEC 的命令反码校验),若校验通过,则存储或处理接收到的数据。
- 超时处理: 在每次进入 EXTI 中断时启动一个软件计时器或利用另一个定时器实现超时检测。如果超过协议规定的最大帧间隔时间(通常几十毫秒)都没有新的边沿触发,则认为上一帧结束或出错,重置解码状态机。
- 当 EXTI 触发(检测到边沿)时:
- GPIO 配置: 将连接接收头
-
方法 2:定时器输入捕获模式(更精确,利用硬件)
- 定时器配置: 使用支持输入捕获的定时器(如 TIMx_CHx)。
- GPIO 配置: 将接收头的
OUT引脚连接到选定的定时器捕获通道引脚(如 TIM2_CH1 -> PA0),并配置该引脚为浮空输入或上拉输入。 - 输入捕获配置: 配置定时器通道为输入捕获模式,设置为 双边沿捕获(
TIM_ICPolarity_BothEdge)。 - 中断/事件配置: 使能定时器的捕获中断(
TIM_IT_CCx)。 - 中断服务程序(ISR):
- 当捕获事件发生时(
TIM_GetITStatus(TIMx, TIM_IT_CCx) == SET):- 读取当前捕获寄存器值(
capture_val = TIM_GetCapturex(TIMx))。
- 读取当前捕获寄存器值(
- 判断触发捕获的边沿(通过检查通道配置极性标志位或状态寄存器):
- 如果是 下降沿:记录
start_val = capture_val。 - 如果是 上升沿:
- 记录
end_val = capture_val。 - 计算脉冲宽度:
pulse_width = end_val - start_val; // 注意处理定时器溢出!
- 记录
- 如果是 下降沿:记录
- 后续步骤与方法 1 中的第 3-6 步相同:判断脉冲类型、组装数据、校验、超时处理。
- 当捕获事件发生时(
-
-
协议解码(以 NEC 协议为例):
- 引导码:9ms 低电平 + 4.5ms 高电平。
- 数据码:32 位(地址 16bit + 地址反码 16bit + 命令 16bit + 命令反码 16bit。常用简化版本是地址 8bit + 地址反码 8bit + 命令 8bit + 命令反码 8bit)。
- 逻辑
0:560us 低电平 + 560us 高电平。 - 逻辑
1:560us 低电平 + 1.69ms 高电平。 - 重复码:9ms 低电平 + 2.25ms 高电平 + 560us 低电平(之后不再发送数据,代表上次按键持续按下)。
- 解码逻辑:
- 检测到符合
9ms low + 4.5ms high的引导码,开始接收数据。 - 对后续每个脉冲(
560us low后跟一个高电平):- 测量高电平持续时间。
- 如果高电平持续约
560us,判为逻辑0。 - 如果高电平持续约
1.69ms,判为逻辑1。
- 连续接收 32 位数据(按特定顺序,通常是 LSB first)。
- 检查地址部分的反码是否正确。
- 检查命令部分的反码是否正确。
- 如果检验通过,提取有效的地址(
address)和命令(command)。 - 如果是重复码(
9ms low + 2.25ms high),则视为重复上次的命令。
- 检测到符合
关键注意事项:
- 电平逻辑: 红外接收头输出是 反相 的!发送端的高电平(载波开启)在接收头输出是低电平;发送端的低电平(载波关闭)在接收头输出是高电平。解码时序时务必注意这个反相关系。
- 时序精度: 红外协议对时间要求严格(误差通常在 ±100us 内)。STM32 的系统时钟和定时器配置要确保足够精确和分辨率(微秒级)。
- 定时器溢出处理: 在计算
pulse_width = end_val - start_val时,如果end_val < start_val,说明定时器发生了溢出。此时脉冲宽度应为(TimerPeriod - start_val) + end_val(TimerPeriod是定时器自动重装载值 ARR + 1)。 - 干扰滤波: 红外信号易受日光灯、环境光干扰。可以在软件中加入简单的滤波逻辑,比如连续多次检测到边沿才认为是有效信号,或者在读取 GPIO 时做多次采样取平均值。
- 协议多样性: 不同遥控器可能使用不同协议。NEC 最常见,但也可能是 RC5, RC6, Sony SIRC 等。需要根据目标遥控器的协议调整解码逻辑。有些库支持多种协议。
- 中断优先级: EXTI 中断和定时器捕获中断需要设置合理的优先级,确保能及时响应电平变化,避免丢失信号。
- 现有库: 可以利用现有的开源红外解码库(如 IRremote 库的 STM32 移植版)来简化开发,这些库通常已经实现了多种协议的解码和硬件抽象。
简化代码框架(基于外部中断 + 定时器):
// 变量定义
volatile uint32_t lastEdgeTime = 0;
volatile uint32_t pulseWidth = 0;
volatile uint8_t state = 0; // 解码状态机状态
volatile uint32_t irData = 0; // 存放接收到的数据
volatile uint8_t bitCount = 0;
// 接收头OUT连接的GPIO和EXTI配置 (例如 PA0)
void IR_GPIO_EXTI_Init(void) {
// ... 配置GPIOA Pin0为输入, 上拉/浮空
// ... 配置EXTI Line0 连接到 PA0
// ... 设置EXTI为双边沿触发
// ... 配置并启用EXTI中断 (NVIC)
}
// 定时器初始化 (例如 TIM2)
void IR_Timer_Init(void) {
// ... 配置TIM2时钟源, 预分频(PSC), 自动重装载值(ARR) 以获得微秒级计数
// ... 停止定时器 (TIM_Cmd(DISABLE))
// ... 清零计数器 (TIM_SetCounter(0))
}
// EXTI中断服务程序 (例如 EXTI0_IRQHandler)
void EXTI0_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
uint32_t currentTime = TIM_GetCounter(TIM2); // 获取当前定时器值
// 判断是否是下降沿 (接收头OUT输出从高变低, 对应发送端载波开启/发射)
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_RESET) {
pulseWidth = currentTime - lastEdgeTime; // 计算高电平持续时间
lastEdgeTime = currentTime;
HandlePulse(pulseWidth, 0); // 处理高电平脉冲 (逻辑判断在下降沿做)
} else { // 上升沿 (接收头OUT输出从低变高, 对应发送端载波关闭/停止发射)
pulseWidth = currentTime - lastEdgeTime; // 计算低电平持续时间
lastEdgeTime = currentTime;
// NEC协议通常在下降沿判断逻辑位,上升沿这里只记录时间起点或处理特殊码
}
EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志
}
}
// 处理测量到的脉冲宽度
void HandlePulse(uint32_t width, uint8_t edgeType) {
// 重置超时计时器
switch (state) {
case 0: // 等待引导码
if (width > NEC_HEADER_HIGH_MIN && width < NEC_HEADER_HIGH_MAX) {
// 检测到可能是引导码后的高电平部分
state = 1;
}
break;
case 1: // 等待引导码低电平或重复码
if (width > NEC_HEADER_LOW_MIN && width < NEC_HEADER_LOW_MAX) {
state = 2; // 进入数据接收状态
bitCount = 0;
irData = 0;
} else if (width > NEC_REPEAT_HIGH_MIN && width < NEC_REPEAT_HIGH_MAX) {
// 处理重复码 (触发上次命令)
handleRepeat();
state = 0; // 回到初始状态
} else {
state = 0; // 时序错误,复位
}
break;
case 2: // 接收数据位 (在下降沿判断)
// 根据上一个高电平脉冲的宽度(pulseWidth)判断逻辑值
if (width > NEC_BIT_1_MIN && width < NEC_BIT_1_MAX) {
irData = (irData << 1) | 0x01; // 逻辑 '1' (MSB first)
} else if (width > NEC_BIT_0_MIN && width < NEC_BIT_0_MAX) {
irData = irData << 1; // 逻辑 '0' (MSB first)
} else {
state = 0; // 时序错误,复位
break;
}
bitCount++;
if (bitCount >= 32) { // 接收完32位
// 校验地址和命令反码
if (/* 地址反码正确 && 命令反码正确 */) {
uint8_t address = (irData >> 24) & 0xFF;
uint8_t command = (irData >> 8) & 0xFF;
handleCommand(address, command); // 处理有效命令
}
state = 0; // 回到初始状态
}
break;
}
}
总结:
STM32 接收红外信号需要 红外接收头模块 作为前置硬件进行信号转换和解调。软件核心是利用 外部中断 或 定时器输入捕获 功能精确测量接收头输出引脚上 高低电平的持续时间。开发者需要根据目标遥控器使用的 特定红外协议(如 NEC)编写解码逻辑,将测量到的脉冲宽度序列解析为有效的地址码和命令码。注意电平反相、时序精度、定时器溢出和干扰过滤等关键点。利用现有开源库可以加速开发。
STM32红外接收分析
title: STM32红外接收分析date: 2020-06-18 00:45:12tags:categories: STM32学习记录
资料下载
贾熹
2021-12-01 09:51:06
如何使用STM32单片机实现红外测温仪的设计
利用嵌入式高性能ARM 的Cortex-M3 内核微控制器芯片STM32 进行红外测温仪的研制,给出了硬件设计的原理框图。重点阐述了信号处理、带
资料下载
佚名
2020-03-02 16:59:05
红外接收二极管接收光的多少和输出信号的关系?
红外接收二极管:光的多少与输出信号的巧妙关系一、引言在光电检测系统中,红外接收二极管是一种非常重要的元件。它的作用是
2023-09-12 08:30:21
STM32红外接收分析相关资料分享
title: STM32红外接收分析date: 2020-06-18 00:45:12tags:categories: STM32学习记录
换一换
- 如何分清usb-c和type-c的区别
- 中国芯片现状怎样?芯片发展分析
- vga接口接线图及vga接口定义
- 芯片的工作原理是什么?
- 华为harmonyos是什么意思,看懂鸿蒙OS系统!
- 什么是蓝牙?它的主要作用是什么?
- ssd是什么意思
- 汽车电子包含哪些领域?
- TWS蓝牙耳机是什么意思?你真的了解吗
- 什么是单片机?有什么用?
- 升压电路图汇总解析
- plc的工作原理是什么?
- 再次免费公开一肖一吗
- 充电桩一般是如何收费的?有哪些收费标准?
- ADC是什么?高精度ADC是什么意思?
- EDA是什么?有什么作用?
- dtmb信号覆盖城市查询
- 中科院研发成功2nm光刻机
- 苹果手机哪几个支持无线充电的?
- type-c四根线接法图解
- 华为芯片为什么受制于美国?
- 怎样挑选路由器?
- 元宇宙概念股龙头一览
- 锂电池和铅酸电池哪个好?
- 什么是场效应管?它的作用是什么?
- 如何进行编码器的正确接线?接线方法介绍
- 虚短与虚断的概念介绍及区别
- 晶振的作用是什么?
- 大疆无人机的价格贵吗?大约在什么价位?
- 苹果nfc功能怎么复制门禁卡
- 单片机和嵌入式的区别是什么
- amoled屏幕和oled区别
- 复位电路的原理及作用
- BLDC电机技术分析
- dsp是什么意思?有什么作用?
- 苹果无线充电器怎么使用?
- iphone13promax电池容量是多少毫安
- 芯片的组成材料有什么
- 特斯拉充电桩充电是如何收费的?收费标准是什么?
- 直流电机驱动电路及原理图
- 传感器常见类型有哪些?
- 自举电路图
- 通讯隔离作用
- 苹果笔记本macbookpro18款与19款区别
- 新斯的指纹芯片供哪些客户
- 伺服电机是如何进行工作的?它的原理是什么?
- 无人机价钱多少?为什么说无人机烧钱?
- 以太网VPN技术概述
- 手机nfc功能打开好还是关闭好
- 十大公认音质好的无线蓝牙耳机