STC12红外接收与NEC解码

news/2025/1/18 7:02:29/

文章目录

  • 一、红外通信简介
  • 二、红外遥控组成
  • 三、NEC协议简介
  • 四、红外接收与NEC解码例程
  • 五、参考资料

一、红外通信简介

红外通信是一种无线通信技术,利用红外光传输信息。红外光波长介于可见光和微波之间,通常在780纳米至1毫米的范围内。红外通信在许多领域得到广泛应用,例如消费电子产品(如遥控器)、安防系统、智能家居、医疗设备、工业自动化等。它具有以下几个特点和优点:

  1. 无线性:红外通信不需要物理连接,通过红外光传输信息,实现无线通信,方便灵活。
  2. 高安全性:由于红外光的传播范围较短,相对不易受到干扰,通信较为安全。
  3. 低功耗:红外通信设备通常使用低功耗的电子元件,适合电池供电的设备。
  4. 成本较低:红外通信设备的制造和维护成本相对较低。

红外通信的一个典型应用是红外遥控器。遥控器将电信号转换成红外光信号发送给待控制的设备,设备通过红外接收器接收到信号后进行解码并执行相应操作。

请添加图片描述
在红外通信中,不同的通信协议规定了红外信号的编码和解码方式,常见的协议包括NEC、RC5、RC6等。通信双方必须使用相同的协议保证正确的通信。总体而言,红外通信是一种简单实用的无线通信技术,在广泛的应用领域发挥着重要的作用。

本篇文章使用STC12单片机接收红外遥控型号,并进行NEC解码。

二、红外遥控组成

在使用红外遥控器时,当用户按下某个按键时,驱动电路会解读按键信息,然后将对应的指令转换成特定的红外信号。红外发射装置发射出的红外光信号被目标设备的红外接收器接收并解码,完成相应的操作。

需要注意的是,不同的红外遥控器可能使用不同的红外通信协议和编码方式,因此在选择红外遥控器时,需要确保它与所控制的目标设备兼容。

总结来说,红外遥控器由按键、红外发射装置、驱动电路、电源和电路板、封装和外壳等组成,通过发射红外光信号实现与目标设备的通信和控制。
请添加图片描述
在这里插入图片描述

三、NEC协议简介

NEC编码是一种常用的红外通信协议,用于遥控器等设备的红外通信。它是由NEC Corporation(日本电气公司)开发的,被广泛应用于各种消费电子产品中,如电视遥控器、音视频设备、空调遥控器等。

NEC编码使用的是脉宽编码调制(PWM)方式,通过控制红外发射器的脉冲宽度来表示不同的信息。NEC编码的一个典型信号由一个引导码(Header Pulse)、一个逻辑"0"的时间间隔(Logic “0” Pulse)和逻辑"1"的时间间隔(Logic “1” Pulse)组成。

NEC编码的时间间隔定义如下:

  1. 引导码的脉冲宽度为9ms的高电平脉冲,后跟4.5ms的低电平间隔。
  2. 逻辑"0"的脉冲宽度为0.56ms的高电平脉冲,后跟0.56ms的低电平间隔。
  3. 逻辑"1"的脉冲宽度为0.56ms的高电平脉冲,后跟1.69ms的低电平间隔。
  4. NEC编码的数据格式通常为32位,包括一个8位的地址码(Address)和一个8位的命令码(Command),以及它们的反码。

使用NEC编码时,发送端通过在一系列时间间隔内发送特定的脉冲宽度来表示不同的信息,接收端接收到红外信号后根据脉冲宽度解码并执行相应的操作。NEC编码作为一种简单和可靠的红外通信协议,在许多遥控器和其他红外设备中得到了广泛应用。
在这里插入图片描述

四、红外接收与NEC解码例程

#include <STC12C5A60S2.H>
#include <intrins.h>//定义接口功能
sbit buzzer 					= P2^3;//蜂鸣器
sbit IR								= P3^2;//红外接收器//时钟选择宏定义
#define MAIN_Fosc		11059200L
//#define MAIN_Fosc		12000000L//相关接口功能宏定义
#define buzzer_OFF	buzzer = 1;//关蜂鸣器
#define buzzer_ON		buzzer = 0;//开蜂鸣器
#define EA_ON				EA 		 = 1;//开总中断
#define EA_OFF			EA     = 0;//关总中断//对已有数据类型重新定义
typedef signed char int8;  		//8位有符号型
typedef signed int  int16; 		//16位有符号型
typedef unsigned char uint8;  //8位无符号型
typedef unsigned char uchar;  //8位无符号型
typedef unsigned int  uint16; //16位无符号型
typedef unsigned int  uint; 	//16位无符号型
typedef unsigned long uint32; //32位无符号型
typedef unsigned char BYTE;	  //8位无符号型
typedef unsigned int WORD;	  //16位无符号型//变量宏定义
uchar IRtime; 			//检测红外高电平持续时间(脉宽)
uchar IRcord[4];    //此数组用于储存分离出来的4个字节的数据(用户码2个字节+键值码2个字节)
uchar IRdata[33];   //此数组用于储存红外的33位数据(第一位为引导码用户码16+键值码16)
bit IRpro_ok, IRok; //第一个用于红外接收4个字节完毕。IRok用为检测脉宽完毕//基于STC12单片机1ms延时函数
//函数说明:内部调用
static void Delay1ms()		
{# if MAIN_Fosc == 11059200L//晶振11.0592MHzunsigned char i, j;_nop_();i = 11;j = 190;do{while (--j);} while (--i);#elif MAIN_Fosc == 12000000L//晶振12.000000MHZunsigned char i, j;_nop_();_nop_();i = 12;j = 168;do{while (--j);} while (--i);#endif}//基于STC12单片机ms延时函数
//函数说明:外部调用
void Delay_ms(uint16 time)
{int i;for(i=0; i<time; i++){Delay1ms();}
}//串口初始化,晶振11.0592,波特率9600
void UartInit(void)//9600bps@11.0592MHz
{PCON &= 0x7F;		//波特率不倍速SCON = 0x50;		//8位数据,可变波特率AUXR |= 0x04;		//独立波特率发生器时钟为Fosc,即1TBRT = 0xDC;			//设定独立波特率发生器重装值AUXR |= 0x01;		//串口1选择独立波特率发生器为波特率发生器AUXR |= 0x10;		//启动独立波特率发生器
}/****************************************函数名称:void sendArray(uchar *s, uint len)*函数输入:*s 发送的数组指针,len数组长度*函数返回:无*函数说明:向串口发送一段数组***************************************/
void sendArray(uchar *s, uint len)
{uint i;for(i=0; i<len; i++){SBUF = *s++;while(!TI);TI = 0;}
}//定时器0初始化
void Timer0_Init(void)
{TMOD = 0x22; //定时器0和定时器1工作方式2,8位自动重装TH0 = 0x00;  //高8位装入0那么定时器溢出一次的时间是256个机器周期TL0 = 0x00;ET0 = 1;	   //定时器0中断TR0 = 1;     //启动定时器0
}//外部中断0初始化
void externalInterrupt0_Init(void)
{IT0 = 1;	   //设置外部中断0为跳沿触发方式,来一个下降沿触发一次EX0 = 1;	   //启动外部中断0
}//提取它的33次脉宽进行数据解码
void IRcordpro(void)
{uchar i, j, k, cord, value;	/*i用于处理4个字节,j用于处理一个字节中每一位,k用于33次脉宽中的哪一位cord用于取出脉宽的时间判断是否符合1的脉宽时间*/k = 1; 						//从第一位脉宽开始取,丢弃引导码脉宽for(i = 0; i < 4; i++){for(j = 0; j < 8; j++){cord = IRdata[k];	    //把脉宽存入cordif(cord > 5)	 		//如果脉宽大于我11.0592的t0溢出率为约278us*5=1390那么判断为1value = value | 0x80;	/*接收的时候是先接收最低位,把最低位先放到value的最高位在和0x08按位或一下这样不会改变valua的其他位的数值只会让他最高位为1*/if(j < 7){value = value >> 1;	//value位左移依次接收8位数据。}k++;				//每执行一次脉宽位加1}IRcord[i] = value;	   //每处理完一个字节把它放入IRcord数组中。value = 0; 			   //清零value方便下次在存入数据}IRpro_ok = 1;				   //接收完4个字节后IRpro ok置1表示红外解码完成	
}void main()
{	UartInit();										//串口初始化Timer0_Init();								//定时器0初始化externalInterrupt0_Init();		//外部中断0初始化EA_ON;												//开总中断while(1){if(IRok)    		//判断脉宽是否检测完毕                    {   IRcordpro();	//根据脉宽解码出4个字节的数据IRok = 0;			//重新等待脉宽检测if(IRpro_ok) 	//判断是否解码完毕  {sendArray(&IRcord[0], 4);IRpro_ok = 0;}}}
}//定时器0中断处理函数
void timer0(void) interrupt 1
{IRtime++;
}//外部中断0处理函数
void int0() interrupt 0
{static uchar i;	 			//	声明静态变量(在跳出函数后在回来执行的时候不会丢失数值)i用于把33次高电平的持续时间存入IRdatastatic bit startflag;		//开始储存脉宽标志位if(startflag)	 			//开始接收脉宽检测{if( (IRtime < 53) && (IRtime >= 32) ) /*判断是否是引导码,底电平9000us+高4500us	这个自己可以算我以11.0592来算了NEC协议的引导码低8000-10000+高4000-5000 如果已经接收了引导码那么i不会被置0就会开始依次存入脉宽*/i = 0;				 //如果是引导码那么执行i=0把他存到IRdata的第一个位IRdata[i] = IRtime;  		 //以T0的溢出次数来计算脉宽,把这个时间存到数组里面到后面判断IRtime = 0;				 //计数清零,下一个下降沿的时候在存入脉宽i++; 					 //计数脉宽存入的次数if(i == 33) 				 //如果存入34次 数组的下标是从0开始i等于33表示执行了34次{IRok = 1;				 //那么表示脉宽检测完毕i = 0; 				 //把脉宽计数清零准备下次存入//开蜂鸣器buzzer_ON;Delay_ms(500);//关蜂鸣器buzzer_OFF;Delay_ms(500);}}else		  {IRtime = 0; 				 //引导码开始进入把脉宽计数清零开始计数startflag = 1;			 //开始处理标志位置1}
}

五、参考资料

本文章及例程主要参考清翔电子51单片机入门教程,文章开源供单片机学习交流。


http://www.ppmy.cn/news/1055939.html

相关文章

LeetCode千位分隔数

给你一个整数 n&#xff0c;请你每隔三位添加点&#xff08;即 “.” 符号&#xff09;作为千位分隔符&#xff0c;并将结果以字符串格式返回。 示例 1&#xff1a; 输入&#xff1a;n 987 输出&#xff1a;“987” 示例 2&#xff1a; 输入&#xff1a;n 1234 输出&…

第8天----【位运算进阶之----异或(^)】

今天我们来学习C语言中的异或。 文章目录 一、基本知识&#xff1a;异或操作满足的定律&#xff1a;(important) 二、拓展应用&#xff1a;1. 交换两个变量的值&#xff1a;2. 判断两个数的奇偶性&#xff1a;3. 检测落单的数(出现奇数次的数)&#xff1a;检测丢失的数: 4. 加密…

VbScript脚本Request获取RFID读卡器以HTTP提交的访问文件中的参数Response回应驱动读卡器显示、播报语音

本示例使用的设备&#xff1a;RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com) <%LANGUAGE"VBSCRIPT" CODEPAGE"65001"%><% Function bin2str(bindata)Dim rsStream, strlsSet rsStream Server.CreateObject…

七大排序算法详解

1.概念 1.排序的稳定性 常见的稳定的排序有三种&#xff1a;直接插入排序&#xff0c;冒泡排序&#xff0c;归并排序 对于一组数据元素排列&#xff0c;使用某种排序算法对它进行排序&#xff0c;若相同数据之间的前后位置排序后和未排序之前是相同的&#xff0c;我们就成这种…

设计模式(3)抽象工厂模式

一、概述&#xff1a; 1、提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无须指定它们具体的类。 2、结构图&#xff1a; 3、举例代码&#xff1a; &#xff08;1&#xff09; 实体&#xff1a; public interface IUser {public void insert(User user);public…

设计模式-责任链

在现代的软件开发中&#xff0c;程序低耦合、高复用、w易拓展、易维护 什么是责任链 责任链模式是一种行为设计模式&#xff0c; 允许你将请求沿着处理者链进行发送。收到请求后&#xff0c; 每个处理者均可对请求进行处理&#xff0c; 或将其传递给链上的下个处理者。 使用场景…

源码分析CompletableFuture使用默认线程池ForkJoinPool的弊端

先说结论&#xff1a; 假如有20CompletableFuture任务并发执行时&#xff0c;都使用默认线程池ForkJoinPool&#xff0c;但cpu的核心数又小于3&#xff0c;那么就会新建20个线程&#xff08;不使用默认线程池了&#xff09;&#xff0c;这20个线程相互竞争cpu资源和内存&#x…

有关Arm CE支持的sha1 sha224 sha256 sha384 sha512指令

快速链接: . 👉👉👉 个人博客笔记导读目录(全部) 👈👈👈 付费专栏-付费课程 【购买须知】:【精选】ARMv8/ARMv9架构入门到精通-[目录] 👈👈👈再某一款SOC(cortex-A53)上进行数字摘要计算的时候, 发现sha1 sha224 sha256的性能很高,sha384 sha512的性能…