红外遥控解码(NEC)

  • 基本介绍
    • 什么是红外线?
    • 红外线系统的组成
    • 发射管和接收管
    • 红外遥控发射(载波频率)
  • 重要介绍
    • NEC协议
    • 数据格式(必看)
    • 位定义(必看)
  • 编写程序思路(2种)
    • 方式一
    • 方式二
  • 程序代码(在1602显示)
    • 方式一
    • 方式二
    • LCD1602相关代码
  • 项目展示

基本介绍

什么是红外线?

人的眼睛能看到的可见光按波长从长到短排列,依次为红、橙、黄、绿、青、蓝、紫。其中红光的波长范围为0.62~0.76μm;紫光的波长范围为0.38~0.46μm。比紫光波长还短的光叫紫外线,比红光波长还长的光叫红外线.红外线遥控就是利用波长为0.76~1.5μm之间的近红外线来传送控制信号的。

红外线系统的组成

红外线系统一般由红外发射装置和红外接收设备两大部分组成。红外发射装置又可由键盘电路、红外编码芯片、电源和红外发射电路组成。红外接收设备可由红外接收电路、红外解码芯片、电源和应用电路组成。通常为了使信号更好的被发射端发送出去,经常会将二进制数据信号调制成为脉冲信号,通过红外发射管发射。常用的有通过脉冲宽度来实现信号调制的脉宽调制(PWM)和通过脉冲串之间的时间间隔来实现信号调制的脉时调制(PPM)两种方法。

发射管和接收管

发送
是一只特殊的发光二极管;由于其内部材料不同于普通发光二极管,因而在其两端施加一定电压时,它便发出的是红外线而不是可见光。目前大量的使用的红外发光二极管发出的红外线波长为940nm左右,外形与普通φ5发光二极管相同。



接收
红外遥控接收器的主要作用是将遥控发射器发来的红外光信好转换成电信号,再放大、限幅、检波、整形,形成遥控指令脉冲,输出至遥控微处理器。

红外遥控发射(载波频率)

通常红外遥控为了提高抗干扰性能和降低电源消耗,红外遥控器常用载波的方式传送二进制编码,常用的载波频率为38kHz,这是由发射端所使用的455kHz晶振来决定的。

重要介绍

NEC协议

NEC功能特点包含:

1.地址码与地址反码,以及命令码与命令反码,具有数据校验作用,增强结果的准确性

2.脉冲距离调制,调制占空比

3.载波频率38KHZ

4.逻辑位时间为逻辑0:1.125ms或逻辑1:2.25ms

5.发送的信号与接收到的信号是反向的

数据格式(必看)

数据格式包括了引导码、用户码、用户反码、数据码和数据码反码,编码总占32位。 数据反码是数据码反相后的编码,编码时可用于对数据的纠错。注意:第二段的用户码也可以在遥控应用电路中被设置成第一段用户码的反码。

位定义(必看)

用户码或数据码中的每一个位可以是位 ‘1’ ,也可以是位 ‘0’。区分 ‘0’和 ‘1’是利用脉冲的时间间隔来区分,这种编码方式称为脉冲位置调制方式,英文简写PPM。

编写程序思路(2种)

1.这个红外一般都是用在中断的,像在我的板子是P3.2口,是外部中断0,中断我们知道可以设定为下降沿触发或者低电平触发。

方式一

第一种方式就是直接模拟数据格式的图来编写程序。(一次中断做完一帧的数据)
一开始 是9ms低电平 ——> 4.5高电平 ——> 0.56ms低电平——>位1/位0的高电平时间…

void ReadIr() interrupt 0
{u8 j,k;u16 err;Time=0;                     delay(700);    //7msif(IRIN==0)      //确认是否真的接收到正确的信号{    err=1000;             //1000*10us=10ms,超过说明接收到错误的信号/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时侯,程序死在这里*/    while((IRIN==0)&&(err>0))  //等待前面9ms的低电平过去         {           delay(1);err--;} if(IRIN==1)          //如果正确等到9ms低电平{err=500;while((IRIN==1)&&(err>0))       //等待4.5ms的起始高电平过去{delay(1);err--;}for(k=0;k<4;k++)       //共有4组数据{               for(j=0;j<8;j++)  //接收一组数据{err=60;       while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去{delay(1);err--;}err=500;while((IRIN==1)&&(err>0))    //计算高电平的时间长度。{delay(10);    //0.1ms  Time++;err--;if(Time>30) //大于3ms  退出程序{return;}}IrValue[k]>>=1;    //k表示第几组数据if(Time>=8)          //如果高电平出现大于0.8ms,那么是1{IrValue[k]|=0x80;}Time=0;        //用完时间要重新赋值                         }}}if(IrValue[2]!=~IrValue[3]) //对比 数据码 和数据反码 是否成立 不对则退出{return;}}
}

方式二

第二种是每触发中断就记录一次时间,通过记录时间的长短来确定是引导位还是数据位 位1还是位0(只记下降沿到下一次下降沿的时间)

void readIr() interrupt 0
{count++;if(count == 1){irTime=0;}if(irTime > 40)   //判断前导码是否接近9ms{bitNum = 0; }irData[bitNum] = irTime;irTime = 0;bitNum++;if(bitNum == 33){irDataOk = 1;   //32位数据接收完标志位count = 0;       //次数清零}}

程序代码(在1602显示)

方式一

main.c

#include "reg52.h"          //此文件中定义了单片机的一些特殊功能寄存器
#include "lcd1602.h"  typedef unsigned int u16;     //对数据类型进行声明定义
typedef unsigned char u8;sbit IRIN=P3^2; //红外引脚
u8 IrValue[4] = {'\0'};
u8 Time;/*延时函数,i=1时,大约延时10us*/
void delay(u16 i)
{while(i--);
}/*显示函数*/
void DigDisplay()
{u8 i;write_com(0x83);for(i=0;i<4;i++){if(IrValue[i]/16<10){write_data(IrValue[i]/16 + 0x30); }else{write_data(IrValue[i]/16 + 0x37);    }if(IrValue[i]%16<10){write_data(IrValue[i]%16 + 0x30); }else{write_data(IrValue[i]%16 + 0x37);    }}
}/*配置外部中断0(初始化红外线接收)*/
void IrInit()
{IT0=1;//下降沿触发EX0=1;//打开中断0允许EA=1;   //打开总中断IRIN=1;//初始化端口
}/*主函数*/
void main()
{   IrInit(); //调用中断0(红外初始化)init_lcd(); //初始化1602while(1){    DigDisplay();   //显示    }
}/*读取红外数值的中断函数*/
void ReadIr() interrupt 0
{u8 j,k;u16 err;Time=0;                     delay(700);    //7msif(IRIN==0)      //确认是否真的接收到正确的信号{    err=1000;             //1000*10us=10ms,超过说明接收到错误的信号/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时侯,程序死在这里*/    while((IRIN==0)&&(err>0))  //等待前面9ms的低电平过去         {           delay(1);err--;} if(IRIN==1)          //如果正确等到9ms低电平{err=500;while((IRIN==1)&&(err>0))       //等待4.5ms的起始高电平过去{delay(1);err--;}for(k=0;k<4;k++)       //共有4组数据{               for(j=0;j<8;j++)  //接收一组数据{err=60;       while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去{delay(1);err--;}err=500;while((IRIN==1)&&(err>0))    //计算高电平的时间长度。{delay(10);    //0.1ms  Time++;err--;if(Time>30) //大于3ms  退出程序{return;}}IrValue[k]>>=1;    //k表示第几组数据if(Time>=8)          //如果高电平出现大于0.8ms,那么是1{IrValue[k]|=0x80;}Time=0;        //用完时间要重新赋值                         }}}if(IrValue[2]!=~IrValue[3]) //对比 数据码 和数据反码 是否成立 不对则退出{return;}}
}

方式二

main.c

#include <reg52.h>
#include "lcd1602.h"unsigned char irTime = 0;  //电平时间
unsigned char bitNum = 0;  //位数
unsigned char count = 0; //记录次数
unsigned char irDataOk = 0; //红外数据接收标志位
unsigned char irValueOk = 0; //红外编码完成标志位
unsigned char irValue[4] = {'\0'}; //存放键值
unsigned char irData[33] = {'\0'}; //存放电平时间/*配置外部中断0  和 定时器0*/
void interrupt0Config()
{EX0 = 1; //触发方式为负跳变IT0 = 1; //打开中断0允许位TMOD = 0x02;  //定时器0 方式2(8位自动重装)TH0 = 0x00;      //200usTL0 = 0x48;ET0 = 1;    //打开定时器0 允许位TR0 = 1;   //启动定时器0EA = 1; //打开总开关
}/********红外数据处理函数*********/
void irDataProcessing()
{unsigned char i,j;unsigned char k = 1;unsigned char value = 0;for(i=0;i<4;i++){for(j=0;j<8;j++){value>>=1; //右移一次 if(irData[k] > 7 )   // 8X200us=1.6ms  大于1.6则记为1{value |= 0x80;}k++;}irValue[i] = value;}irValueOk = 1;irDataOk = 0;
}/*********显示函数**********/
void display()
{unsigned char i;write_com(0x83);if(irValueOk == 1 && irValue[2]==~irValue[3])//判断是否接收完和数据码有无错{for(i=0;i<4;i++){if(irValue[i]/16<10){write_data(irValue[i]/16 + 0x30);    }else{write_data(irValue[i]/16 + 0x37);    }if(irValue[i]%16<10){write_data(irValue[i]%16 + 0x30); }else{write_data(irValue[i]%16 + 0x37);    }}irValueOk=0;}
}
/*主函数*/
void main()
{interrupt0Config(); //调用中断函数init_lcd();    //初始化1602while(1){if(irDataOk == 1){irDataProcessing(); //红外数据处理函数}display();    //显示函数}
}/*红外接收函数*/
void readIr() interrupt 0
{count++;if(count == 1){irTime=0;}if(irTime > 40)   //判断前导码是否接近9ms{bitNum = 0; }irData[bitNum] = irTime;irTime = 0;bitNum++;if(bitNum == 33){irDataOk = 1;   //32位数据接收完标志位count = 0;       //次数清零}}void time0() interrupt 1
{irTime++;
}

LCD1602相关代码

lcd1602.c

#include <reg52.h>
#include "lcd1602.h"#define LCD P0
sbit E = P2^7;
sbit RS = P2^6;
sbit RW = P2^5;/******延迟5毫秒函数********/
void delay5ms()   //误差 -0.000000000001us
{unsigned char a,b;for(b=15;b>0;b--)for(a=152;a>0;a--);
}/******LCD1602写命令函数********/
void write_com(unsigned char command)
{RS = 0; RW = 0;  //高读低写LCD = command;delay5ms(); //这里延时最低要30纳秒 我们直接给5msE = 1;      //使能拉高 delay5ms(); //最低要求延迟150纳秒 我们直接给5msE = 0;
}/******LCD1602写数据函数********/
void write_data(unsigned char dat)
{RS = 1;RW = 0;LCD = dat;delay5ms(); //这里延时最低要30纳秒 我们直接给5msE = 1;       //使能拉高 delay5ms(); //最低要求延迟150纳秒 我们直接给5msE = 0;
}
/******初始化LCD1602********/
void init_lcd()
{   write_com(0x06); //写入数据后光标自动右移 整屏不移动。 0x40(光标左移 整屏不移动)0x05(左移 整屏右移)0x07(右移 整屏右移)write_com(0x0c); //开显示功能 无光标 不闪烁write_com(0x38); //数据总线8位 16X2显示 5*7点阵write_com(0x01); //清屏 0000 0001}

lcd1602.h

#ifndef _LCD1602_H_
#define _LCD1602_H_void write_com(unsigned char command);   //写命令函数
void write_data(unsigned char dat);     //写数据函数
void init_lcd();  //初始化LCD1602函数
void delay5ms();  //延时5ms函数 #endif

项目展示

基于51单片机+红外遥控解码+LCD1602显示相关推荐

  1. 基于51单片机驱动ADXL346 (LCD1602显示)

    基于51单片机驱动ADXL346 (LCD1602显示) 一.ADXL346传感器介绍 1.实物图 2.产品说明 3.电气参数 4.通信协议 二.驱动代码 1.引脚定义 2.初始化函数 3.主函数 三 ...

  2. 基于51单片机的电子钟万年历LCD1602显示

    本设计是51单片机的电子钟万年历LCD1602显示(proteus仿真+程序+报告+器件清单) 仿真图proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 编号C0002 ...

  3. 63、基于51单片机红外遥控人体感应自动门控制系统设计

    毕设帮助.开题指导.技术解答(有偿)见文末. 目录 摘要 一.硬件方案 二.设计功能 三.实物图 四.原理图 五.PCB图 六.Protues仿真 七.程序 部分代码 八.资料包括 摘要 伴随着电气技 ...

  4. 基于51单片机红外遥控人体感应自动车库门控制设计(程序+Proteus仿真+原理图+PCB图+参考论文+开题报告+任务书等)

    一.硬件方案 单片机的红外遥控人体感应自动门控制系统设计的实现主要有电源5V供电.单片机最小系统.红外感应遥控模块,红外一体接收头,按键电路,步进电机驱动电路,指示灯电路组成.. 二.设计功能 1.如 ...

  5. 基于51单片机驱动MPU6050模块(LCD1602显示)

    @TOC 一.简介 MPU-6050集成了3轴MEMS陀螺仪,3轴MEMS加速度计,以及一个可扩展的数字运动处理器DMP,可用IIC接口连接一个第三方的数字传感器.MPU-6050对陀螺仪和加速度计分 ...

  6. (毕业设计资料)基于51单片机红外无线遥控智能家电控制系统设计

    基于51单片机红外遥控定时开关智能家电插座设计 本系统由STC8C52单片机电路+时钟DS1302电路+LCD1602液晶显示电路+按键电路+继电器控制电路+蜂鸣器报警电路+红外传感器电路+电源电路组 ...

  7. 基于51单片机的遥控小车

    基于51单片机的遥控小车(HC-05模块,L298n模块) 保姆级 1.硬件准备 2.部分硬件说明 USB转TTL模块 可以把串口发送的TTL信号转换成USB信号再发送给电脑,电脑就可以接收到单片机发 ...

  8. 【Proteus仿真】51单片机汇编实现DS18B20+LCD1602显示

    [Proteus仿真]51单片机汇编实现DS18B20+LCD1602显示 Proteus仿真 汇编代码(.asm) ;**************************************** ...

  9. 【【51单片机红外遥控小风车】】

    51单片机红外遥控小风车 今天结束了51单片机的学习,明天开始学习stm32 我是学习江科大的视频一步一步完成的 ,他讲的非常好,非常好 特别通俗易懂 学习复刻他的作品我也自己创作了一些 但是现在暂时 ...

最新文章

  1. JavaScript之手写Promise
  2. 【整理】ABAP 7.40新特性介绍(下)
  3. java 类爆炸_Java 封装与类
  4. 决策树会有哪些特性?
  5. 【Elasticsearch】 6 种 能使 es 挂掉的方法
  6. Page.IsPostBack
  7. Debugview调试视图
  8. 批量修改mac系统文件的可读写权限
  9. 人均维护服务器数量,华为FusionCube一体机助力金华职业技术学院构建最佳云平台...
  10. PHP从入门到精通pdf
  11. win10离线安装.NetFrameWork3.5出现0x800F081F解决办法。
  12. sunshine in the rainsunshine in the rain
  13. 中国期货市场监控中心爬虫
  14. 当杭州为人称道的美丽遇见了华为云!
  15. 电脑主板线路连接图解_跳线接法图解 主板开机线接法图解
  16. 一英国公司打造极速家庭宽带:每秒1G
  17. 使用D2D接口绘制图形
  18. 生活 or 办公——怎么能少了 PeakDo 毫米波无线投屏器呢
  19. lisp不是函授型语言_LISP语言
  20. 将iPhone照片导出、iCloud照片备份到电脑的方法

热门文章

  1. idea中如何将包名折叠或者或如何将折叠的包名展开
  2. 如何保持线上安全:你们的个人网络安全指南
  3. 关于 canvas 画圆方法 arc() 方法的理解
  4. css3 实现背景渐变色与背景图片并存效果
  5. SSML语音合成标记语言详解
  6. 10 种流行的 Web 挖掘工具
  7. 《印第安纳之法柜奇兵》影评
  8. android设备启动不起来,android – app不会在设备上启动
  9. 根据函数依赖求最小依赖集
  10. php去掉第一个空格,php怎么去除前面空格