一、环境介绍

MCU: STM32F103ZET6

编程软件环境: keil5

红外线传输协议:  NEC协议---38KHZ载波:。NEC协议是红外遥控协议中常见的一种。

解码思路:  外部中断 + 定时器方式

代码风格:   模块化编程,寄存器直接操作方式

完整keil工程源码下载(解压即可编译运行测试):   

https://download.csdn.net/download/xiaolong1126626497/19863275

二、NEC协议与解码思路介绍

2.1 采用的相关硬件

  图1:  这是NEC协议的红外线遥控器:  如果自己手机没有红外线遥控器的功能,可以淘宝上买一个小遥控器来学习测试,成本不高,这个遥控器也可以自己做,能解码当然也可以编码发送,只需要一个红外光发射管即可。

     图2: 这是红外线接收头模块。如果自己的开发板没有自带这个接收头,那就单独买一个接收头模块,使用杜邦线接到开发板的IO口上即可用来测试学习,接线很方便。

 图3: 这是红外线发射管,如果自己想做遥控器的发射端,自己做遥控器,那么就可以直接购买这种模块即可。

2.2 红外线协议介绍

在光谱中波长自760nm至400um的电磁波称为红外线,它是一种不可见光。红外线通信的例子我们每个人应该都很熟悉,目前常用的家电设备几乎都可以通过红外遥控的方式进行遥控,比如电视机、空调、投影仪等,都可以见到红外遥控的影子。这种技术应用广泛,相应的应用器件都十分廉价,因此红外遥控是我们日常设备控制的理想方式。

红外线的通讯原理: 红外光是以特定的频率脉冲形式发射,接收端收到到信号后,按照约定的协议进行解码,完成数据传输,在消费类电子产品里,脉冲频率普遍采用 30KHz 到 60KHz 这个频段,NEC协议的频率就是38KHZ。 这个以特定的频率发射其实就可以理解为点灯,不要被复杂的词汇难住了,就是控制灯的闪烁频率(亮灭),和刚学单片机完成闪光灯一样的意思,只不过是灯换了一种类型,都是灯。 接收端的原理:  接收端的芯片对这个红外光比较敏感,可以根据有没有光输出高低电平,如果发送端的闪烁频率是有规律的,接收端收到后输出的高电平和低电平也是有规律对应的,这样发送端和接收端只要约定好,那就可以做数据传输了。

红外线传输协议可以说是所有无线传输协议里成本最低,最方便的传输协议了,但是也有缺点,距离不够长,速度不够快;当然,每个传输协议应用的环境不一样,定位不一样,好坏没法比较,具体要看自己的实际场景选择合适的通信方式。

2.3 NEC协议介绍

NEC协议是众多红外线协议中的一种(这里说的协议就是他们数据帧格式定义不一样,数据传输原理都是一样的),我们购买的外能遥控器、淘宝买的mini遥控器、电视机、投影仪几乎都是NEC协议。  像格力空调、美的空调这些设备使用的就是其他协议格式,不是NEC协议,但是只要学会一种协议解析方式,明白了红外线传输原理,其他遥控器协议都可以解出来。

下图是NEC协议传输一次数据的完整格式:

NEC协议一次完整的传输包含:    引导码、8位用户码、8位用户反码、8位数据码、8位数据反码。

(注意:下面的解释都是站在红外线接收端的角度来进行说明的,就是解码端的角度)

引导码:  由9ms的高电平+4.5ms的低电平组成。

4个字节的数据:  用户码+用户反码+数据码+数据反码。  这里的反码可以用来校验数据是否传输正确,有没有丢包。

重点:  NEC协议传输数据位的时候,0和1的区分是依靠收到的高、低电平的持续时间来进行区分的---这是解码关键。

标准间隔时间:0.56ms

收到数据位0:  0.56ms

收到位1:  1.68ms

所以,收到一个数据位的完整时间表示方法是这样的:

收到数据位0:   0.56m低电平+ 0.56ms的高电平

收到数据位1:  0.56ms低电平+1.68ms的高电平

红外线接收头模块输出电平的原理: 红外线接收头感应到有红外光就输出低电平,没有感应到红外光就输出高电平。

这是使用逻辑分析采集红外线接收头输出的信号:

这是采集红外线遥控器上的LED灯输出电平时序图,刚好和接收端相反:

单片机编写解码程序的时候,常见的方式就是采用外部中断+定时器的方式进行解析,中断可以设置为低电平触发,因为接收头没有感应到红外光默认是输出高电平,如果收到NEC引导码,就会输出低电平,进入到中断服务函数,完成解码,解码过程中开启定时器记录每一段的高电平、低电平的持续时间,按照NEC协议进行判断,完成最终解码。

STM32可以使用输入捕获方式完成解码,其实输入捕获就是外部中断+定时器的组合,只不过是STM32内部封装了一层。

外部中断服务器里的解码程序如下(这个在其他单片机上思路是一样的):

/*
函数功能:  外部中断线9_5服务函数
*/
void EXTI9_5_IRQHandler(void)
{u32 time;u8 i,j,data=0;//清除中断线9上的中断请求EXTI->PR|=1<<9;time=Infrared_GetTime_L();       //得到低电平时间if(time<7000||time>10000)return; //标准时间: 9000ustime=Infrared_GetTime_H();       //得到高电平时间if(time<3000||time>5500)return;  //标准时间4500us//正式解码NEC协议for(i=0;i<4;i++){for(j=0;j<8;j++){time=Infrared_GetTime_L();       //得到低电平时间if(time<400||time>700)return;    //标准时间: 560ustime=Infrared_GetTime_H();       //得到高电平时间if(time>1400&&time<1800)         //数据1 1680us{data>>=1;data|=0x80;}else if(time>400&&time<700)   //数据0 560us{data>>=1;}else return;}InfraredRecvData[i]=data; //存放解码成功的值}//解码成功InfraredRecvState=1;
}

三、核心完整代码

本程序的解码思路是: 将红外线接收模块的输出脚接到STM32的PB9上,配置STM32的PB9为外部中断模式,下降沿电平触发;如果收到红外线信号就进入到中断服务函数里解码,如果解码过程中发现数据不符合要求就终止解码,如果数据全部符合要求就按照协议接收,直到解码完成,设置标志位,在main函数里打印解码得到的数据。

代码都是模块化编程,阅读起来也很方便。

3.1  红外线解码.c

#include "nec_Infrared.h"
u8 InfraredRecvData[4]; //存放红外线解码接收的数据
u8 InfraredRecvState=0; //0表示未接收到数据,1表示接收到数据
/*
函数功能: 红外线解码初始化(接收)
*/
void Infrared_RecvInit(void)
{Infrared_Time6_Init(); //定时器初始化/*1. 配置GPIO口*/RCC->APB2ENR|=1<<3; //PBGPIOB->CRH&=0xFFFFFF0F;GPIOB->CRH|=0x00000080;GPIOB->ODR|=1<<9;/*2. 配置外部中断*/EXTI->IMR|=1<<9; //外部中断线9,开放中断线的中断请求功能EXTI->FTSR|=1<<9; //中断线9_下降沿RCC->APB2ENR|=1<<0; //开启AFIO时钟AFIO->EXTICR[2]&=~(0xF<<1*4);AFIO->EXTICR[2]|=0x1<<1*4;STM32_NVIC_SetPriority(EXTI9_5_IRQn,1,1);
}/*
函数功能: 初始化定时器,用于红外线解码
*/
void Infrared_Time6_Init(void)
{RCC->APB1ENR|=1<<4;RCC->APB1RSTR|=1<<4;RCC->APB1RSTR&=~(1<<4);TIM6->PSC=72-1; //预分频器TIM6->ARR=65535;   //重装载寄存器TIM6->CR1|=1<<7; //开启缓存功能//TIMx->CR1|=1<<0; //开启定时器
}/*
函数功能: 测量高电平持续的时间
*/
u32 Infrared_GetTime_H(void)
{TIM6->CNT=0;TIM6->CR1|=1<<0;    //开启定时器while(NEC_IR){}     //等待高电平结束TIM6->CR1&=~(1<<0); //关闭定时器return TIM6->CNT;
}/*
函数功能: 测量低电平持续的时间
*/
u32 Infrared_GetTime_L(void)
{TIM6->CNT=0;TIM6->CR1|=1<<0;    //开启定时器while(!NEC_IR){}     //等待低电平结束TIM6->CR1&=~(1<<0); //关闭定时器return TIM6->CNT;
}/*
函数功能:  外部中断线9_5服务函数
*/
void EXTI9_5_IRQHandler(void)
{u32 time;u8 i,j,data=0;//清除中断线9上的中断请求EXTI->PR|=1<<9;time=Infrared_GetTime_L();       //得到低电平时间if(time<7000||time>10000)return; //标准时间: 9000ustime=Infrared_GetTime_H();       //得到高电平时间if(time<3000||time>5500)return;  //标准时间4500us//正式解码NEC协议for(i=0;i<4;i++){for(j=0;j<8;j++){time=Infrared_GetTime_L();       //得到低电平时间if(time<400||time>700)return;    //标准时间: 560ustime=Infrared_GetTime_H();       //得到高电平时间if(time>1400&&time<1800)         //数据1 1680us{data>>=1;data|=0x80;}else if(time>400&&time<700)   //数据0 560us{data>>=1;}else return;}InfraredRecvData[i]=data; //存放解码成功的值}//解码成功InfraredRecvState=1;
}

3.2  主函数.c

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include "at24c02.h"
#include "W25Q64.h"
#include "spi.h"
#include "nec_Infrared.h"int main()
{LED_Init();BEEP_Init();KeyInit();USARTx_Init(USART1,72,115200);IIC_Init();W25Q64_Init();printf("芯片ID号:0x%X\n",W25Q64_ReadID());Infrared_RecvInit();while(1){if(InfraredRecvState){InfraredRecvState=0;printf("用户码:%d,按键码:%d\n",InfraredRecvData[0],InfraredRecvData[2]);printf("user反码:%d,key反码:%d\n",(~InfraredRecvData[1])&0xFF,(~InfraredRecvData[3])&0xFF);BEEP=!BEEP;LED0=!LED0;}}
}

四、扩展提高

如果上面的NEC的解码思路已经看到,程序已经可以自己编写,就可以试着使用STM32的输入捕获+定时器方式写一版解码代码,既能更加熟悉NEC协议、也可以学习STM32定时器捕获捕获的用法;也可以做一些小东西来锻炼,比如:红外线遥控小车、音乐播放器支持红外线遥控器切歌,电机的开关、灯的开关等等。

搞定协议解码之后,我们下一步就是完成自定义的NEC协议红外线制作,采用STM32模拟一个万能红外线遥控器。

在光谱中波长自760nm至400um的电磁波称为红外线,它是一种不可见光。目前几乎所有的视频和音频设备都可以通过红外遥控的方式进行遥控,比如电视机、空调、影碟机等,都可以见到红外遥控的影子。这种技术应用广泛,相应的应用器件都十分廉价,因此红外遥控是我们日常设备控制的理想方式。

STM32入门开发: NEC红外线协议解码(超低成本无线传输方案)相关推荐

  1. STM32入门开发: 制作红外线遥控器(智能居家-万能遥控器)

    一.环境介绍 MCU: STM32F103ZET6 编程软件环境: keil5 红外线传输协议:  NEC协议---38KHZ载波:.NEC协议是红外遥控协议中常见的一种. 编码发送思路:  延时函数 ...

  2. 4.4 51单片机-NEC红外线遥控器解码

    4.4  NEC红外线遥控器解码 4.4.1 接收头原理图介绍 图4-4-1 实验板上的红外线接收头是接在单片机的P3.2 IO口上,要使用红外线接收功能,需要将红外线接收头的跳线帽接上. 图4-4- ...

  3. STM32入门开发工具整理总结

    本文介绍一下STM32开发都有什么工具,资料需要到什么地方下载. 一.STM32资料 ST对于其新的32bit MCU平台的重视程度可从其提供的应用笔记的数量和相应的参考代码上可见一斑. STM32的 ...

  4. STM32入门开发--LED模块实现跑马灯

    1.案例描述 利用STM32F103ZE开发板实现控制LED灯实现跑马灯现象. 正在不断学习嵌入式开发中,博客还会持续更新,敬请关注! 2.开发环境 keil 5.14 + Windows 10 + ...

  5. STM32入门开发: 编写DS18B20温度传感器驱动(读取环境温度、支持级联)

    一.环境介绍 编程软件: keil5 操作系统: win10 MCU型号: STM32F103C8T6 STM32编程方式: 寄存器开发 (方便程序移植到其他单片机) 温度传感器: DS1820 DS ...

  6. stm32入门开发板选野火还是正点原子好,哪个的视频讲到好一点?

    学习交流可以添加 微信读者交流①群 (添加微信:coderAllen,备注加群) 程序员技术交流①群:736386324 这个比较有发言权,因为全部都研究过,要是对于学习,谁的都可以,因为都是很有系统 ...

  7. STM32 NEC红外遥控器解码

    STM32 NEC红外遥控器解码 红外遥控编码格式 一体化红外接收头 STM32显示遥控器按下的数字代码 代码片 总结 原文链接:https://www.yourcee.com/newsinfo/29 ...

  8. FPGA 24 工程模块 红外遥控(NEC协议)解码

    FPGA 24 红外遥控(NEC协议)解码 主要功能 :设计了一个红外 NEC协议的解码模块 实现(设计)流程:通过遥控器发送的红外信号,外围红外信号接收传感器对数据进行接收,得到一个在基频上的高低电 ...

  9. STM32 Nucleo开发板入门(一)——概述

    在实验室找到一块 STM32 的开发板,型号是STM32 Nucleo-L031K6.趁着十一假期,入门一下,顺便随便记点东西. NUCLEO-L031K6 | Mbedhttps://os.mbed ...

  10. STM32cubemx教程及STM32入门(五)IIC

    STM32cubemx教程及STM32入门(五)IIC 2022.8.25 前言 本章主要讲解IIC协议以及stm32cubemx配置和HAL库函数 简介 I2C(Inter-Integrated C ...

最新文章

  1. Oracle面试问题汇总
  2. Numerical Geometry of Image
  3. SpringMVC Ueditor1.4.3 未找到上传数据
  4. 对搜狗输入法的个人评价
  5. ORACLE获取某个时间段之间的月份列表和日期列表
  6. 给学习java web新手们的建议和推荐一些书籍
  7. 蓝桥杯 BASIC-26 基础练习 报时助手
  8. python聊天机器人
  9. 转Win 7 快捷键
  10. java 基础知识九 类与对象
  11. java获取电脑配置_Java.Utils:获取电脑配置信息
  12. CREO:CREO软件之零件【模型】扫描之扫描、螺旋扫描、可变剖面扫描、扫描混合、混合、边界混合、可变剖面扫描的简介及其使用方法(图文教程)之详细攻略
  13. 何凯明最新一作MAE解读系列1
  14. Google Chrome谷歌浏览器繁体字修改为简体字
  15. 【单片机小白屑作】基于清翔QX-MCS51单片机的精简版定时炸弹
  16. 京牌车辆过户以后车辆保险怎么办?
  17. POJ 1198 / HDU 1401 Solitaire (记忆化搜索+meet in middle)
  18. c语言飞机源代码,C语言写的飞机源码
  19. 工作效率低?项目凌乱?用飞项做项目管理,彻底告别这些烦恼
  20. 快速云:云计算技术在计算机数据处理中的应用

热门文章

  1. 【解决方案】智慧机场:基于视频智能融合平台EasyCVR让机场数字化转型高飞
  2. 深度学习面试题100题
  3. 用Java写Flybird游戏
  4. Visual Studio 2022安装配置
  5. 前端代码审查工具_前端代码审查中应检查的内容
  6. 几种主流的分布式定时任务
  7. 毕业论文可能用到的一些东西
  8. openlayers2渐变色渲染
  9. Project 制作工作进度计划 排除休息日
  10. python有趣的简单代码-python有趣代码