stm32与红外遥控器(NEC协议)
1.器件简介
本次测试采用R903V1红外接收头与NEC协议的红外遥控器,接收头原理图如下:
器件的供电电压VCC在2.7V~5.5V之间,输出电压VOUT正常在0.2v ~(VCC-0.3±0.2)v,注意高低电平输出脉冲宽度最小都在400us~800us之间。
NEC 码的位定义:一个脉冲对应 560us 的连续载波,一个逻辑 1 传输需要 2.25ms(560us脉冲+1680us 低电平),一个逻辑 0 的传输需要 1.125ms(560us 脉冲+560us 低电平)。而遥控接收头在收到脉冲的时候为低电平,在没有脉冲的时候为高电平,这样,我们在接收头端收到的信号为:逻辑 1 应该是 560us 低+1680us 高,逻辑 0 应该是 560us 低+560us 高。同时NEC码还规定了连发码由 9ms 低电平+2.5m 高电平+0.56ms 低电平+97.94ms 高电平组成。
NEC协议的数据格式:同步码头、地址码、地址反码、控制码、控制反码。同步码由一个 9ms 的低电平和一个 4.5ms 的高电平组成,地址码、地址反码、控制码、控制反码均是8 位数据格式。正常是按照低位在前,高位在后的顺序发送,但是我测试是按照高位在前,低位在后的。采用反码是为了增加传输的可靠性(可用于校验)。
2.硬件连接
简单说一下,红外接收器电压接3.3V,VOUT连接单片机的输入捕获引脚即可。
3.软件设计
使用stm32单片机的输入捕获功能,用stm32cubemx进行设置:
这里解释主要参数部分:
prescaler:预分频器,设置为72
counter mode:计数模式,设为向上计数
counter period:计数周期,设为65535
polarity selection:边沿检测方式,选择下降沿检测,程序里还是改成了上升沿检测
input filter:输入滤波器,设为8,是指连续采集到8个一样的高/低电平才计作高/低电平
在MAIN中开启输入捕获:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
while (1)
{
switch(cap_state)
{
case 0:
__HAL_TIM_SET_CAPTUREPOLARITY(&htim5, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING);//设置为上升沿捕获
HAL_TIM_IC_Start_IT(&htim5, TIM_CHANNEL_2); //启动输入捕获
cap_state++;
break;
} /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */
}
main循环体
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
/定时器输入捕获中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//捕获中断发生时执行
{
if(htim->Instance==TIM5)
{
switch(cap_state)
{
case 1:
rise_value[rise_i] = HAL_TIM_ReadCapturedValue(&htim5,TIM_CHANNEL_2);//取上升沿时刻
__HAL_TIM_SET_CAPTUREPOLARITY(&htim5,TIM_CHANNEL_2,TIM_ICPOLARITY_FALLING); //设置为下降沿捕获
cap_state++;
break;
case 2:
fall_value[fall_i] = HAL_TIM_ReadCapturedValue(&htim5,TIM_CHANNEL_2);//取下降沿时刻
if(fall_value[fall_i] > rise_value[rise_i])
{
rising_time[t_i] = fall_value[fall_i] - rise_value[rise_i];//高电平时间获取
}else
{
rising_time[t_i] = 65535 + fall_value[fall_i] - rise_value[rise_i];//高电平时间获取
}
//控制码
if(same_i == 1)
{
cnt+=1;
//地址码1~8
if(t_i<8)
{
if(rising_time[t_i]>500&&rising_time[t_i]<600)
{
address <<= 1;
address+=0;
}else if(rising_time[t_i]>1500&&rising_time[t_i]<1800)
{
address <<= 1;
address+=1;
}
}else if(t_i>16&&t_i<25)//控制码17~24
{
if(rising_time[t_i]>500&&rising_time[t_i]<600)
{
rec <<= 1;
rec+=0;
}else if(rising_time[t_i]>1500&&rising_time[t_i]<1800)
{
rec <<= 1;
rec+=1;
}
}
t_i++;
rise_i++;
fall_i++;
}
//同步码
if(rising_time[t_i]>4300&&rising_time[t_i]<4700)
{
//同步码正确
same_i=1;
t_i++;
rise_i++;
fall_i++;
}
HAL_TIM_IC_Stop_IT(&htim5,TIM_CHANNEL_2); //停止捕获
cap_state=0;
break;
}
}
}
输入捕获中断回调
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
//按键中断回调
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
//KEY0
if (GPIO_Pin==GPIO_PIN_5)
{
HAL_Delay(20);/* 延时一小段时间,消除抖动 */
if (HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_5)==0)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_8); for(int i=0;i<=fall_i;i++)
{
if(fall_value[i] > rise_value[i])
{
rising_time[i] = fall_value[i] - rise_value[i];//高电平时间获取
}else
{
rising_time[i] = 65535 + fall_value[i] - rise_value[i];//高电平时间获取
printf("hear:%d\r\n",i);
}
printf("高电平[%d]:%d us 下降沿时刻[%d]:%d us 上升沿时刻[%d]:%d us\r\n",i,rising_time[i],i,fall_value[i],i,rise_value[i]);
} printf("地址:%d 控制码:%lld\r\n",address,rec);
rise_i=fall_i=same_i=t_i=cnt=address=rec=0;
}
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_5);
}
}
按键中断回调
大致说一下程序流程,在main中循环开启上升沿检测输入捕获功能(case 0),接着在输入捕获中断回调里记下上升沿触发时刻(rise_value),并改为下降沿检测捕获,再记下下降沿触发时刻(fall_value)并关闭捕获功能。
高电平持续时间(rising_time) = 下降沿触发时刻(fall_value) - 上升沿触发时刻(rise_value)
获取到一系列高电平以后(看示波器图),根据高电平持续时间进行数值移位换算,可以得到对应的地址码和控制码,串口打印如下:
打印结果中的hear是下降沿时刻溢出的情况,计算时需要在下降沿时刻基础上再加65535才可以。
感兴趣的可以试一试,需要原工程的留言我发。
stm32与红外遥控器(NEC协议)的更多相关文章
- 红外遥控NEC协议使用总结
最近做了一个调试红外遥控三色灯的实习,花了一个多月的时间研究基于NEC协议的红外遥控,下面是这次实习技术方面的总结. 一.NEC协议特征: 8位地址和8位命令长度 每次传输两遍地址(用户码)和命令(按 ...
- 手把手教你DIY尼康ML-L3红外遥控器
项目介绍 ML-L3是用于尼康部分型号相机的无线红外遥控器,可以通过红外方式来控制快门的释放,支持B门拍摄.官方售价100RMB左右,山寨版售价10RMB左右.虽然也能实现基本的遥控功能,但是功能还是 ...
- 红外NEC协议
注意: 用示波器在接收头抓的电平看起来和NEC协议刚好相反, 那是因为:HS0038B 这个红外一体化接收头,当收到有载波的信号的时候,会输出一个低电平,空闲的时候会输出高电平. 具体情况,具体分析. ...
- 红外协议之NEC协议
NEC协议载波:38khz 其逻辑1与逻辑0的表示如图所示: 逻辑1为2.25ms,脉冲时间560us:逻辑0为1.12ms,脉冲时间560us.所以我们根据脉冲时间长短来解码.推荐载波占空比为1/3 ...
- 基于Arduino、STM32进行红外遥控信号接收
catalogue . 遥控器原理简介 . 红外遥控原理 . 常见红外遥控器红外线信号传输协议 . 遙控器的发展 . 实验过程 . 攻击面 . 基于STM32实现红外信号解码 1. 遥控器原理简介 0 ...
- NEC协议
注意: 用示波器在接收头抓的电平看起来和NEC协议刚好相反, 那是因为:HS0038B 这个红外一体化接收头,当收到有载波的信号的时候,会输出一个低电平,空闲的时候会输出高电平. 具体情况,具体分析. ...
- 基于STM32的红外遥控重点解析
本文有两个内容:一.红外遥控协议的的讲解:二.解码程序解析(参考正点原子的代码) 红外的介绍.优点.缺点就不给大家说了,进入正题 一.红外遥控协议的的讲解 红外遥控的编码目前广泛使用的是:NEC Pr ...
- STM32之红外遥控信号自学习实现
一.序言 很早前就想实现这个红外遥控自学习的这个实验,用于来自己控制房子里如空调等红外遥控设备的自动化,NEC的标准到具体的产品上可能就被厂家定义为不一样了,所以自学习就应该是接收到什么就发送什么,不 ...
- IRM3800 红外遥控器解码 linux驱动
这一次还是接在 Cemera 上.用 中断引脚 EINT20 也就是 GPG12. 之前焊的 51 板子上有一个红外接收器. 请注意了,是 标准的 NEC 码规范:首次发送的是9ms的高电平脉冲,其后 ...
随机推荐
- 基于MAXIMO的发电行业EAM解决方案
1. 行业背景 随着我国以“厂网分开,竞价上网”为特点的电力市场的起步和发展,发电厂.发电集团成为独立企业参与市场竞争,原有的“生产型”管理模式已经不再适应市场的需求.发电企业在重视安全质量.保证电力 ...
- SpringBoot框架:配置文件application.properties和application.yml的区别
一.格式 1.application.properties格式: server.port=8080 server.servlet.context-path=/cn spring.datasource. ...
- shiro 退出过滤器 logout ---退出清除HTTPSession数据
重写LogouFilter类 import org.apache.shiro.web.filter.authc.LogoutFilter; public class ShiroLogoutFilter ...
- Spring 系列之jdbcTemplate的使用
Spring系列之 jdbcTemplate 啥是jdncTemplate? t他是spring框架中提供的一个对象,是对原始的jdbcAPI对象的简单封装,spring框架为我们提供了很多操作,模板 ...
- Python 3 入门,看这篇就够了(超全整理)
史上最全Python资料汇总(长期更新).隔壁小孩都馋哭了 --- 点击领取 今天和大家分享的内容是Python入门干货,文章很长. 简介 Python 是一种高层次的结合了解释性.编译性.互动性和面 ...
- Arduino Uno微控制器采用的是Atmel的ATmega328
参考:https://www.yiboard.com/thread-831-1-1.html 在本篇文章中,我们将详细介绍Arduino开发板的硬件电路部分,具体来说,就是介绍Arduino Uno开 ...
- 基于COCA词频表的文本词汇分布测试工具v0.2
update: 简单整理了一下代码的组织. 处理的单词封装成类,单词的修正,信息的显示都作为其内的方法. 写得还比较糙,工具本身可以封装,还有对于单词的变形基本没什么处理,以后有时间再改. 项目托管到 ...
- 跟我一起学.NetCore之WebApi接口裸奔有风险(Jwt)
前言 撸码需谨慎,裸奔有风险.经常在一些技术交流群中了解到,还有很多小伙伴的项目中Api接口没有做任何安全机制验证,直接就裸奔了,对于一些临时项目或是个人小项目还好,其余的话,建议小伙伴们酌情考虑都加 ...
- 每日一题 LeetCode 42.接雨水 【双指针】
题目链接 https://leetcode-cn.com/problems/trapping-rain-water/ 题目说明 题解 主要方法:双指针 + 正反遍历 解释说明: 正向遍历:先确定池子左 ...
- ansible-基础和安装
什么是ansible ansible是python中的一套模块,系统中的一套自动化工具,可以用来作系统管理.自动化命令.等任务. ansible优势 (1) ansible是python中的一套完整的 ...