用单片机解码红外遥控器
遥控器使用方便,功能多.目前已广泛应用在电视机、VCD、DVD、空调等各种家用电器中,且价格便宜,市场上非常容易买到。如果能将遥控器上许多的按键解码出来.用作单片机系统的输入.则解决了常规矩阵键盘线路板过大、布线复杂、占用I/O口过多的弊病。而且通过使用遥控器,操作时可实现人与设备的分离,从而更加方便使用。下面以TC9012编码芯片的遥控器为例。谈谈如何用常用的51系统单片机进行遥控的解码。
通用红外遥控系统由发射和接收两大部分组成,应用编/解码专用集成电路芯片来进行控制操作,如图所示。发射部分包括键盘矩阵、编码调制、LED红外发送器;接收部分包括光、电转换放大器、解调、解码电路。
一、编码格式
1、0和1的编码
当发射器按键按下后,即有遥控码发出,所按的键不同遥控编码也不同。这种遥控码具有以下特征:采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”,其波形如图所示。
遥控器发射的信号由一串0和1的二进制代码组成.不同的芯片对0和1的编码有所不同。通常有曼彻斯特编码和脉冲宽度编码。TC9012的0和1采用PWM方法编码,即脉冲宽度调制,其0码和1码如图所示(以遥控接收输出的波形为例)。0码由0.56ms低电平和0。56ms高电平组合而成,脉冲宽度为1.12ms.1码由0.56ms低电平和1.69ms高电平组合而成,脉冲宽度为2.25ms。在编写解码程序时.通过判断脉冲的宽度,即可得到0或1。
UPD6121G产生的遥控编码是连续的32位二进制码组,其中前16位为用户识别码,能区别不同的电器设备,防止不同机种遥控码互相干扰,如我们可以同时使用电视机、机顶盒、功放等遥控器,但它们不会产生误触发。该芯片的用户识别码固定为十六进制01H;后16位为8位操作码(功能码)及其反码。UPD6121G最多额128种不同组合的编码。遥控器在按键按下后,周期性地发出同一种32位二进制码,周期约为108ms。一组码本身的持续时间随它包含的二进制“0”和“1”的个数不同而不同,大约在45~63ms之间。
2、按键的编码
当我们按下遥控器的按键时,遥控器将发出如图2的一串二进制代码,我们称它为一帧数据。根据各部分的功能。可将它们分为5部分,分别为引导码、用户识别码、用户识别码反码、数据码、数据反码。遥控器发射代码时.均是低位在前,高位在后。由图3分析可以得到.引导码高电平为4.5ms,低电平为4.5ms,当接收到此码时,表示一帧数据的开始。单片机可以准备接收下面的数据。用户识别码由8位二进制组成,共256种.图中地址码重发了一次,主要是加强遥控器的可靠性.如果两次地址码不相同,则说明本帧数据有错,应丢弃。不同的设备可以拥有不同的用户识别码.因此。同种编码的遥控器只要设置地址码不同,也不会相互干扰。图中的地址码为十六进制的0EH(注意低位在前)。在同一个遥控器中,所有按键发出的地址码都是相同的,数据码为8位,可编码256种状态,代表实际所按下的键。数据反码是数据码的各位求反,通过比较数据码与数据反码,可判断接收到的数据是否正确。如果数据码与数据反码之间的关系不满足相反的关系.则本次遥控接收有误,数据应丢弃。在同一个遥控器上.所有按键的数据码均不相同。在图3中,数据码为十六进制的0CH,数据反码为十六进制的0F3H(注意低位在前),两者之和应为0FFH。
二、单片机遥控接收电路
红外遥控接收可采用较早的红外接收二极管加专用的红外处理电路的方法。如CXA20106,此种方法电路复杂,现在一般不采用。较好的接收方法是用一体化红外接收头,它将红外接收二极管、放大、解调、整形等电路做在一起,只有三个引脚。分别是+5V电源、地、信号输出。常用的一体化接收头的外形及引脚见红外接收头的信号输出接单片机的INTO或INTl脚。典型电路如图5所示。图中增加了一只PNP型三极管对输出信号进行放大。
三、遥控信号的解码算法及程序编制
平时,遥控器无键按下。红外发射二极管不发出信号,遥控接收头输出信号1,有键按下时,0和1编码的高电平经遥控头倒相后会输出信号0.由于与单片机的中断脚相连,将会引起单片机中断(单片机预先设定为下降沿产生中断)。单片机在中断时使用定时器0或定时器1开始计时.到下一个脉冲到来时,即再次产生中断时,先将计时值取出。清零计时值后再开始计时.通过判断每次中断与上一次中断之间的时间间隔。便可知接收到的是引导码还是0和1。如果计时值为9ms。接收到的是引导码,如果计时值等于1.12ms,接收到的是编码0。如果计时值等于2.25ms.接收到的是编码1。在判断时间时,应考虑一定的误差值。因为不同的遥控器由于晶振参数等原因,发射及接收到的时间也会有很小的误差。
即我们通常所说的解码,单片机得知发过来的是什么信号,然后再做出相应的判断与控制,如我们按电视机遥控器的频道按钮,则单片机会控制更换电视频道,如按的是遥控器音量键,则单片机会控制增减音量。而解码的关键是如何识别“0”和“1”,从位的定义我们可以发现“0”、“1”均以0.56ms的低电平开始,不同的是高电平的宽度不同,“0”为0.56ms,“1”为1.68ms,所以必须根据高电平的宽度区别“0”和“1”。如果从0.56ms低电平过后,开始延时,0.56ms以后,若读到的电平为低,说明该位为“0”,反之则为“1”,为了可靠起见,延时必须比0.56ms长些,但又不能超过1.12ms,否则如果该位为“0”,读到的已是下一位的高电平,因此取(1.12ms+0.56ms)/2=0.84ms最为可靠,一般取0.84ms左右均可。根据码的格式,应该等待9ms的起始码和4.5ms的结果码完成后才能读码。
以接收TC9012遥控器编码为例,解码方法如下:
(1)设外部中断0(或者1)为下降沿中断,定时器0(或者1)为16位计时器,初始值均为O。
(2)第一次进入遥控中断后,开始计时。
(3)从第二次进入遥控中断起,先停止计时,并将计时值保存后,再重新计时。如果计时值等于前导码的时间,设立前导码标志。准备接收下面的一帧遥控数据,如果计时值不等于前导码的时间,但前面已接收到前导码,则判断是遥控数据的0还是1。
(4)继续接收下面的地址码、数据码、数据反码。
(5)当接收到32位数据时,说明一帧数据接收完毕。此时可停止定时器的计时,并判断本次接收是否有效.如果两次地址码相同且等于本系统的地址,数据码与数据反码之和等于0FFH,则接收的本帧数据码有效。否则丢弃本次接收到的数据。
(6)接收完毕,初始化本次接收的数据,准备下一次遥控接收。
基于红外通信的单片机综合编程控制技术实现遥控密码锁功能
一、设计的目的及意义
1.1、设计的现状及背景
在日常的生活和工作中, 住宅与部门的安全防范、单位的文件档案、财务报表以及一些个人资料的保存多以加锁的办法来解决。若使用传统的机械式钥匙开锁,人们常需携带多把钥匙, 使用极不方便, 且钥匙丢失后安全性即大打折扣。随着科学技术的不断发展,人们对日常生活中的安全保险器件的要求越来越高。为满足人们对锁的使用要求,增加其安全性,用密码代替钥匙的密码锁应运而生。密码锁具有安全性高、成本低、功耗低、易操作等优点。
在安全技术防范领域,具有防盗报警功能的电子密码锁逐渐代替传统的机械式密码锁,克服了机械式密码锁密码量少、安全性能差的缺点,使密码锁无论在技术上还是在性能上都大大提高一步。随着大规模集成电路技术的发展,特别是单片机的问世,出现了带微处理器的智能密码锁,它除具有电子密码锁的功能外,还引入了智能化管理、专家分析系统等功能,从而使密码锁具有很高的安全性、可靠性,应用日益广泛。
随着人们对安全的重视和科技的发展,许多电子智能锁(指纹识别、IC卡辨认)已在国内外相继面世。但是这些产品的特点是针对特定的指纹和有效卡,只能适用于保密要求的箱、柜、门等。而且指纹识识别器若在公共场所使用存在容易机械损坏,IC卡还存在容易丢失、损坏等特点。加上其成本较高,一定程度上限制了这类产品的普及和推广。鉴于目前的技术水平与市场的接收程度,电子密码锁是这类电子防盗产品的主流。红外遥控是单工的红外通信方式,本设计的红外遥控采用以通信方式为基础的红外遥控,而且本设计也使用了红外通信技术,故着重分析红外通信的基本原理。
红外通信是利用红外技术实现两点间的近距离保密通信和信息转发。它一般由红外发射和接收系统两部分组成。发射系统对一个红外辐射源进行调制后发射红外信号,而接收系统用光学装置和红外探测器进行接收,就构成红外通信系统。但是接触式密码锁系统都相应的存在着不同的缺点。例如:接触式密码锁系统成本较低,体积小,卡片本身无须电源,但使用不太方便,而且有接触磨损。相比之下,红外遥控密码锁系统的成本与接触式密码锁系统相当,而且可以进行近距离遥控,使用十分方便。而且它已经与 PC 机的数据库相结合,可以组成一套酒店房间的门禁管理系统。 由于红外遥控具有许多优点, 例如红外线发射装置采用红外发光二极管遥控发射器易于小型化且价格低廉; 采用数字信号编码和二次调制方式,不仅可以实现多路信息的控制,增加遥控功能,提高信号传输的抗干扰性,减少误动作,而且功率消耗低;红外线不会向室外泄露,不会产生信号串扰;反应速度快、传输效率高、工作稳定可靠等。工业设备中,在高压、辐射、有毒气体、粉尘等环境下,采用红外线遥控不仅完全可靠而且能有效地隔离电气干扰。所以红外线遥控是目前使用最广泛的一种通信和遥控手段。
1.2、设计的目的
在科技高速发展的今天,非接触式控制越来越受大家欢迎,利用红外遥控,方便又安全。另外,红外线不会产生信号干扰,反应速度迅速、工作稳定度高等特点。而在工业制造中,在高压、辐射、腐蚀等恶劣环境下,采用红外遥控能够很好地隔离这些干扰。在本次设计中,为了更加方便操作,除了采用矩阵键盘对密码锁进行控制外,还可以用遥控器进行控制,以达到双控的目的。可以加深自己对所学专业的认识,关联知识,增强自己的动手能力,积累实践经验,为以后的工作打好基础。
1.3、设计的意义
随着科技的发展,人们生活的节奏也越来越快,随之人们对方便,快捷的要求也随之不断增高。遥控器的出现,在一定程度上满足了人们这个要求。遥控器是由高产的发明家Robert Adler在五十年代发明的[1]。而红外遥控是20世纪70年代才开始发展起来的一种远程控制技术,其原理是利用红外线来传递控制信号,实现对控制对象的远距离控制,具体来讲,就是有发射器发出红外线指令信号,有接收器接收下来并对信号进行处理,最后实现对控制对象的各种功能的远程控制。
红外遥控具有独立性、物理特性与可见光相似性、无穿透障碍物的能力及较强的隐蔽性等特点。随着红外遥控技术的开发和迅速发展,很多电器都应用了红外遥控,在日常的生活和工作中, 住宅与部门的安全防范、单位的文件档案、财务报表以及一些个人资料的保存多以加锁的办法来解决。若使用传统的机械式钥匙开锁,人们常需携带多把钥匙, 使用极不方便, 且钥匙丢失后安全性即大打折扣。随着科学技术的不断发展,人们对日常生活中的安全保险器件的要求越来越高。为满足人们对锁的使用要求,增加其安全性,用密码代替钥匙的密码锁应运而生。密码锁具有安全性高、成本低、功耗低、易操作等优点。 在安全技术防范领域,具有防盗报警功能的电子密码锁逐渐代替传统的机械式密码锁,克服了机械式密码锁密码量少、安全性能差的缺点,使密码锁无论在技术上还是在性能上都大大提高一步。随着大规模集成电路技术的发展,特别是单片机的问世,出现了带微处理器的智能密码锁,它除具有电子密码锁的功能外,还引入了智能化管理、专家分析系统等功能,从而使密码锁具有很高的安全性、可靠性,应用日益广泛。
二、主要器件介绍
系统主要有STC89C52RC单片机最小系统和LCD1602液晶显示、数据存储芯片24C02、红外发射接收模块等组成。
2.1、主控器件
本设计是STC89C52RC单片机为控制核心,矩阵键盘输入,红外遥控输入基于红外通信的单片机控制技术综合实现所有功能。系统框图如下图:
单片机是STC公司最新推出的一种新型51内核的单片机。片内含有Flash程序存储器、SRAM、UART、SPI、PWM等模块。封装图如下图:
2.1.1、主要特性
1. 增强型8051单片机,6时钟/机器周期和12时钟/机器周期可以任意选择,指令代码完全兼容传统8051.
2. 工作电压:5.5V~3.3V(5V单片机)/3.8V~2.0V(3V单片机)
3. 工作频率范围:0~40MHz,相当于普通8051的0~80MHz,实际工作频率可达48MHz
4. 用户应用程序空间为8K字节 5. 片上集成512字节RAM
6. 通用I/O口(32个),复位后为:P1/P2/P3/P4是准双向口/弱上拉,
P0口是漏极开路输出,作为总线扩展用时,不用加上拉电阻,作为I/O口用时,需加上拉电阻。
7. ISP(在系统可编程)/IAP(在应用可编程),无需专用编程器,无需专用仿真器,可通过串口(RxD/P3.0,TxD/P3.1)直接下载用户程序,数秒即可完成一片
8. 具有EEPROM功能
9. 具有看门狗功能
10. 共3个16位定时器/计数器。即定时器T0、T1、T2
11. 外部中断4路,下降沿中断或低电平触发电路,Power Down模式可由外部中断低电平触发中断方式唤醒
12. 通用异步串行口(UART),还可用定时器软件实现多个UART
13. 工作温度范围:-40~+85℃(工业级)/0~75℃(商业级)
2.1.2、引脚功能
VCC(40引脚):电源电压
VSS(20引脚):接地
P0端口(P0.0~P0.7,39~32引脚):P0口是一个漏极开路的8位双向I/O口。作为输出端口,每个引脚能驱动8个TTL负载,对端口P0写入“1”时,可以作为高阻抗输入。在访问外部程序和数据存储器时,P0口也可以提供低8位地址和8位数据的复用总线。此时,P0口内部上拉电阻有效。在Flash ROM编程时,P0端口接收指令字节;而在校验程序时,则输出指令字节。验证时要求外接上拉电阻。
P1端口(P1.0~P1.7,1~8引脚):P1口是一个带内部上拉电阻的8位双向I/O口。P1的输出缓冲器可驱动(吸收或者输出电流方式)4个TTL输入。对端口写入1时,通过内部的上拉电阻把端口拉到高电位,这是可用作输入口。P1口作输入口使用时,因为有内部上拉电阻,那些被外部拉低的引脚会输出一个电流。
P2端口(P2.0~P2.7,21~28引脚):P2口是一个带内部上拉电阻的8位双向I/O端口。P2的输出缓冲器可以驱动(吸收或输出电流方式)4个TTL输入。对端口写入1时,通过内部的上拉电阻把端口拉到高电平,这时可用作输入口。P2作为输入口使用时,因为有内部的上拉电阻,那些被外部信号拉低的引脚会输出一个电流
P3口引脚复用功能 引脚号 复用功能
P3.0 RXD(串行输入口)
P3.1 TXD(串行输出口)
P3.2 (外部中断0)
P3.3 (外部中断1)
P3.4 T0(定时器0的外部输入)
P3.5 T1(定时器1的外部输入)
P3.6 (外部数据存储器写选通)
P3.7 (外部数据存储器读选通)
RST(9引脚):复位输入。当输入连续两个机器周期以上高电平时为有效,用来完成单片机单片机的复位初始化操作。看门狗计时完成后,RST引脚输出96个晶振周期的高电平。特殊寄存器AUXR(地址8EH)上的DISRTO位可以使此功能无效。DISRTO默认状态下,复位高电平有效。
ALE/(30引脚):地址锁存控制信号(ALE)是访问外部程序存储器时,锁存低8位地址的输出脉冲。在Flash编程时,此引脚()也用作编程输入脉冲。 在一般情况下,ALE以晶振六分之一的固定频率输出脉冲,可用来作为外部定时器或时钟使用。然而,特别强调,在每次访问外部数据存储器时,ALE脉冲将会跳过。如果需要,通过将地址位8EH的SFR的第0位置“1”,ALE操作将无效。这一位置“1”,ALE仅在执行MOVX或MOV指令时有效。否则,ALE将被微弱拉高。这个ALE使能标志位(地址位8EH的SFR的第0位)的设置对微控制器处于外部执行模式下无效。
VPP(31引脚):访问外部程序存储器控制信号。为使能从0000H到FFFFH的外部程序存储器读取指令,必须接GND。注意加密方式1时,将内部锁定位RESET。为了执行内部程序指令,应该接VCC。在Flash编程期间,也接收12伏VPP电压。
XTAL1(19引脚):振荡器反相放大器和内部时钟发生电路的输入端。
XTAL2(18引脚):振荡器反相放大器的输入端。
2.1.3、串口通信
一条信息的各位数据被逐位顺序传送的通信方式成为串行通信。根据信息的传送方向,串行通信可以可以进一步划分为单工、半双工和全双工 3 种。信息只能单方向传送为单工;信息能双向传送但不能同时双向传送为半双工;信息能够同时双向传送则成为全双工。 8051 系列单片机有一个全双工串行口, 全双工的串行通信只需要一根输出线和输入线。
串行通信又有异步通信和同步通信这两种方式。异步通信用起始位“0”表示字符的开始,然后从低位到高位逐位传送数据,最后用停止位“1”表示字符结束。一个字符又称作一帧信息,一帧信息包括 1 位起始位、8 位数据位、1 位停止位,若数据位增加到第 9 位, 在 8051 系列单片机中, 第九位数据可以用作奇偶校验位, 也可以用作地址/数据帧标志。
8051 系列单片机串行 I/O 接口的工作原理就是: 当要发送数据时, 单片机自动将 SBUF 内的 8 位并行数据转换为一定格式的串行数据, 从 TXD 引脚按规定的波特率来输出; 当要接收数据时, 要监视 RXD 引脚,一旦出现起始位“0” ,按规定的波特率将外围设备送来的一定格式的串行数据转换成 8 位并行数据,等待用户读取 SBUF 寄存器,若不及时读取,SBUF 中的数据有可能被刷新。8051 系列单片机上有通用异步接收/发送器用于串行通信,发送时数据由 TXD 引脚输出,接收时数据从 RXD 引脚输入。有两个缓冲器(Serial Buffer) ,一个作发送缓冲器,另外一个作为接收缓冲器。UART 是可编程的全双工的串行口。
SBUF是可以直接寻址的专用寄存器。物理上,它对应着两个寄存器,即一个发送寄存器一个接收寄存器,CPU写SBUF就是修改发送寄存器;读SBUF就是读接收寄存器。接收器是双缓冲的,以避免在接收下一帧数据之前,CPU未能及时的响应接收器的中断,没有把上一帧的数据读走而产生两帧数据重叠的问题。对于发送器,为了保持最大的传输速率,一般不需要双缓冲,因为发送时CPU是主动的,不会产生重叠问题。
SCON是一个逐位定义的8位寄存器,用于控制串行通信的方式选择、接收和发送,指示串口的状态,SCON即可以字节寻址也可以位寻址,字节地址98H,地址位为98H~9FH。它的各个位定义如下:
SM2在工作方式2和3中是多机通信的使能位。在工作方式0中,SM2必须为0。在工作方式1中,若SM2=1且没有接收到有效的停止位,则接收中断标志位RI不会被激活。在工作方式2和3中若SM2=1且接收到的第9位数据(RB8)为0,则接收中断标志RB8不会被激活,若接收到的第9位数据(RB8)为1,则RI置位。此功能可用于多处理机通信。
REN为允许串行接收位,由软件置位或清除。置位时允许串行接收,清除时禁止串行接收。
TB8是工作方式2和3要发送的第9位数据。在许多通信协议中该位是奇偶位,可以按需要由软件置位或清除。在多处理机通信中,该位用于表示是地址帧还是数据帧。
RB8是工作方式2和3中接收到的第9位数据(例如是奇偶位或者地址/数据标识位),在工作方式1中若SM2=0,则RB8是已接收的停止位。在工作方式0中RB8不使用。
TI 为发送中断标志位,由硬件置位,软件清除。工作方式0中在发送第8位末尾由硬件置位;在其他工作方式时,在发送停止位开始时由硬件置位。TI=1时,申请中断。CPU响应中断后,发送下一帧数据。在任何工作方式中都必须由软件清除TI。
RI为接收中断标志位,由硬件置位,软件清除。工作方式0中在接收第8位末尾由硬件置位;在其他工作方式时,在接收停止位的中间由硬件置位。RI=1时,申请中断,要求CPU取走数据。但在工作方式1中,SM2=1且未接收到有效的停止位时,不会对RI置位。
在任何工作方式中都必须由软件清除RI。
系统复位时,SCON的所有位都被清除。
(1) 工作方式0
SM0=0且SM1=0时,串口选择工作方式0,实质这是一种同步移位寄存器模式。其数据传输的波特率固定为Fosc/12,数据由RXD引脚输入或输出,同步时钟由TXD引脚输出。接收/发送的是8位数据,传输是低位在前,帧格式如下:
…….. D0 D1 D2 D3 D4 D5 D6 D7 …….
(2)工作方式1
当SM0=0且SM1=1时,串口选择工作方式1,其数据传输的波特率由定时/计数器T1、T2的溢出速率决定,可通过程序设定。当T2CON寄存器中的RCLK和TCLK置位时,用T2作为发送和接收波特率发生器,而RCLK=TCLK=0时,用T1作为波特率发生器,两者还可以交叉使用,即发送和接收采用不同的波特率。数据由TXD引脚发送,由RXD引脚接收。发送或接收一帧的数据为10位,即1位起始位(0)、8位数据位(低位在先)和1位停止位(1)。帧格式如下:
起始位0 D0 D1 D2 D3 D4 D5 D6 D7 停止位1
类似于工作方式0,当执行任一条SBUF指令时,就启动串行数据的发送。在执行写入SBUF的指令时,也将“1”写入发送移位寄存器的第9位,并通知发送控制器有发送请求。实际上,发送过程始于内部的16分频计数器下次满度翻转(全“1”变全“0”)后的那几个机器周期的开始。所以,每位的发送过程与16分频计数器同步,而不是与“写SBUF”同步。
(3)方式 2 和方式 3
这两种方式都是 11 位异步接收/发送方式。他们的操作过程都是完全一样
的,所不同的是波特率而已。方式 3 波特率同方式 1(定时器 1 作为波特率时钟发生器) 。
方式 2 和方式 3 的发送起始于任何一条 SBUF 数据装载指令。当第 9 位数据(TB8)输出之后,TI 将被置位(TI=1) 。
方式 2 和方式 3 的接收数据前提条件也是 REN 被编程为 1。 在第 9 位数据接收到后, 如果下列条件同时满足,即 RI=0 且 SM2=0 或者接收到的第 9 位为 1,则将已接受的数据装入 SBUF 缓冲器和 RB8,并将RI 置位(RI=1)否则接收数据无效。
8051 串行口的不同寻常的特征是包括第 9 位方式。它允许把在串行口通信增加的第 9 位用于标志特殊字节的接收。用这种方式,一个单片机可以和大量的其他单片机对话而不打扰不寻址的单片机,这种多机通信方式必须工作在严格的主从方式,由软件进行分析。
2.2 、LCD1602的原理
2.2.1 LCD1602的概述
液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示。LCD1602是有32个5x7点阵组成的行字符型显示屏。其操作方法如下:读写时序操作
读状态RS=L,R/W=H,E=H输出D0—D7
写指令RS=L,R/W=L,D0—D7指令码,E=高脉冲
读数据RS=H,R/W=H,E=H输出D0—D7数据
写数据RS=H,R/W=L,D0—D7数据,E=高脉冲
2.2.2LCD1602的操作时序
写操作时序图
2.2.3 LCD1602的基本命令
1、RAM地址映射图
2、指令码
1602液晶模块内部的控制器共有11条控制指令,如表10-14所示:
指令1:清显示,指令码01H,光标复位到地址00H位置。指令2:光标复位,光标返回到地址00H。
指令3:光标和显示模式设置I/D:光标移动方向,高电平右移,低电平左移S:屏幕上所有文字是否左移或者右移。高电平表示有效,低电平则无效。
指令4:显示开关控制。D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示C:控制光标的开与关,高电平表示有光标,低电平表示无光标B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。
指令5:光标或显示移位S/C:高电平时移动显示的文字,低电平时移动光标。
指令6:功能设置命令DL:高电平时为4位总线,低电平时为8位总线N:低电平时为单行显示,高电平时双行显示F:低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。指令7:字符发生器RAM地址设置。
指令8:DDRAM地址设置。
指令9:读忙信号和光标地址BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。
指令10:写数据。
指令11:读数据。
2.3、红外一体化接收头
2.3.1红外一体化接收头的概述
红外遥控信号是一连串的二进制脉冲码。为了使其在无线传输过程中免受其他红外信号的干扰,通常都是先将其调制在特定的载波频率上,然后再经红外发射二极管发射出去,而红外线接收装置则要滤除其他杂波,只接收该特定频率的信号并将其还原成二进制脉冲码,也就是解调.
目前,对于这种进行了调制的红外遥控信号,通常是采用一体化红外线接收头进行调解.一体化红外线接收头将低噪音放大器,限幅器,带通滤波器,解调器,,以及整形驱动电路等集成在一起.一体化红外线接收头体积小,灵敏度高,外接元件少,抗干扰能力强,使用十分方便。
红外信号收发系统的典型电路如图1所示,红外接收电路通常被厂家集成在一个元件中,成为一体化红外接收头。 内部电路包括红外监测二极管,放大器,限幅器,带通滤波器,积分电路,比较器等。红外监测二极管监测到红外信号,然后把信号送到放大器和限幅器,限幅器把脉冲幅度控制在一定的水平,而不论红外发射器和接收器的距离远近。交流 信号进入带通滤波器,带通滤波器可以通过30khz到60khz的负载波,通过解调电路和积分电路进入比较器,比较器输出 高低电平,还原出发射端的信号波形。注意输出的高低电平和发射端是反相的,这样的目的是为了提高接收的灵敏度。
红外接收头的种类很多,引脚定义也不相同,一般都有三个引脚,包括供电脚,接地和信号输出脚。根据发射端调制 载波的不同应选用相应解调频率的接收头。
红外接收头内部放大器的增益很大,很容易引起干扰,因此在接收头的供电脚上须加上滤波电容,一般在22uf以上。 有的厂家建议在供电脚和电源之间接入330欧电阻,进一步降低电源干扰。
2.3.2红外一体化接收头的应用
红外遥控是以调制的方式发射数据,就是把数据和一定频率的载波进行“与”操作,这样既可以提高发射效率又可以降低电源 功耗。
调制载波频率一般在30khz到60khz之间,大多数使用的是38kHz,占空比1/3的方波,如图2所示,这是由发射端所使用的 455kHz晶振决定的。在发射端要对晶振进行整数分频,分频系数一般取12,所以455kHz÷12≈37.9 kHz≈38kHz。
单片机可以准备接收下面的数据。地址码由8位二进制组成,共256种.图中地址码重发了一次。主要是加强发射机的可靠性.如果两次地址码不相同.则说明本帧数据有错.应丢弃。不同的设备可以拥有不同的地址码.因此。同种编码的发射机只要设置地址码不同,也不会相互干扰。在同一个发射机中.所有按键发出的地址码都是相同的。数据码为8位,可编码256种状态,代表实际所按下的键。数据反码是数据码的各位求反,通过比较数据码与数据反码.可判断接收到的数据是否正确。如果数据码与数据反码之间的关系不满足相反的关系.则本次遥控接收有误.数据应丢弃。在同一个发射机上,所有按键的数据码均不相同。
数据格式包括了引导码、用户码、数据码和数据码反码,编码总占32位。数据反码是数据码反相后的编码,编码时可用于对数据的纠错。注意:第二段的用户码也可以在遥控应用电路中被设置成第一段用户码的反码。
用户码或数据码中的每一个位可以是位‘1’,也可以是位‘0’。区分‘0’和‘1’是利用脉冲的时间间隔来区分,这种编码方式称为脉冲位置调制方式,英文简写PPM。
以接收TC9012遥控器编码为例,解码方法如下:
设外部中断为下降沿中断,定时器0(或者1)为16位计时器.初始值均为0
(2)第一次进入遥控中断后,开始计时。
(3)从第二次进入遥控中断起,先停止计时。并将计时值保存后,再重新计时。如果计时值等于前导码的时间,设立前导码标志。准备接收下面的一帧遥控数据,如果计时值不等于前导码的时间,但前面已接收到前导码,则判断是遥控数据的0还是1。
(4)继续接收下面的地址码、数据码、数据反码。
(5)当接收到32位数据时,说明一帧数据接收完毕。此时可停止定时器的计时,并判断本次接收是否有效.如果两次地址码相同且等于本系统的地址,数据码与数据反码之和等于0FFH,则接收的本帧数据码有效。否则丢弃本次接收到的数据。
(6)接收完毕,初始化本次接收的数据,准备下一次遥控接收。
三、程序设计
红外遥控锁系统主要由单片机通过红外通信控制,当其完成红外信号,读取数据,,其数据的传输根据协议的内容,发生错误时,有单片机发出警报,超出一定次数就把键盘锁死报警。红外遥控锁系统程序需要完成以下的功能:
1、矩阵键盘,可以设置密码开锁及密码重置;
3、遥控器输入密码开锁及密码重置;
5、密码输入输入信息或密码输入错误报警及键盘锁死;
6、用1602液晶显示功能状态。
矩阵键盘设置程序流程图如下:
四、过程分享
PCB图
原理图
程序代码:
//(智能存钱管) //晶振12Mkz
//功能:该系统具有存钱取钱功能,存钱时需要输入密码 密码为000000
//密码可修改 万能密码为:131420 改密码可初始化密码为:000000 密码与存钱数有掉电保存功能
#include<reg52.h> //头文件
#include<intrins.h>
#define uchar unsigned char //宏定义
#define uint unsigned int
#define LCD1602_dat P0
uchar irbyte[4];
uchar irtime,irflag,bitnum,irdateok;
uchar irdate[33];
sbit LCD1602_rs=P1^0;
sbit LCD1602_rw=P1^1;
sbit LCD1602_e=P1^2;
sbit led=P2^0;
sbit beep=P2^7;
sbit Scl=P3^5;//24C02串行时钟
sbit Sda=P3^4;//24C02串行数据
uchar ptem,mm[6],mm_n1[6],mm_n2[6],n,j;
uchar step,ms,time,cw;
uchar zt[2];
bit cq,beep1,beep2;
void mDelay(uint t) //延时
{
uchar i;
while(t--)
{
for(i=0;i<125;i++)
{;}
}
}
void Nop(void) //空操作
{
_nop_();
_nop_();
_nop_();
_nop_();
}
/*起始条件*/
void Start(void)
{
Sda=1;
Scl=1;
Nop();
Sda=0;
Nop();
}
/*停止条件*/
void Stop(void)
{
Sda=0;
Scl=1;
Nop();
Sda=1;
Nop();
}
/*应答位*/
void Ack(void)
{
Sda=0;
Nop();
Scl=1;
Nop();
Scl=0;
}
/*反向应答位*/
void NoAck(void)
{
Sda=1;
Nop();
Scl=1;
Nop();
Scl=0;
}
/*发送数据子程序,Data为要求发送的数据*/
void Send(uchar Data)
{
uchar BitCounter=8;
uchar temp;
do
{
temp=Data;
Scl=0;
Nop();
if((temp&0x80)==0x80)
Sda=1;
else
Sda=0;
Scl=1;
temp=Data<<1;
Data=temp;
BitCounter--;
}
while(BitCounter);
Scl=0;
}
/*读一字节的数据,并返回该字节值*/
uchar Read(void)
{
uchar temp=0;
uchar temp1=0;
uchar BitCounter=8;
Sda=1;
do{
Scl=0;
Nop();
Scl=1;
Nop();
if(Sda)
temp=temp|0x01;
else
temp=temp&0xfe;
if(BitCounter-1)
{
temp1=temp<<1;
temp=temp1;
}
BitCounter--;
}
while(BitCounter);
return(temp);
}
void WrToROM(uchar Data[],uchar Address,uchar Num)
{
uchar i;
uchar *PData;
PData=Data;
for(i=0;i<Num;i++)
{
Start();
Send(0xa0);
Ack();
Send(Address+i);
Ack();
Send(*(PData+i));
Ack();
Stop();
mDelay(20);
}
}
void RdFromROM(uchar Data[],uchar Address,uchar Num)
{
uchar i;
uchar *PData;
PData=Data;
for(i=0;i<Num;i++)
{
Start();
Send(0xa0);
Ack();
Send(Address+i);
Ack();
Start();
Send(0xa1);
Ack();
*(PData+i)=Read();
Scl=0;
NoAck();
Stop();
}
}
void delay(uint T) //延时函数
{
while(T--);
}
void qing() // 清楚数据
{
uint i;
for(i=0;i<33;i++)
{
irdate[i]=0;
}
}
void deal_with() //解码处理部分
{
uchar i,j,k,temp;
k=1;
for(j=0;j<4;j++)
{
for(i=0;i<8;i++)
{
temp=temp>>1;
if(irdate[k]>7)
{
temp=temp|0x80;
}
k++;
}
irbyte[j]=temp;
}
}
void LCD1602_write(uchar order,dat) //1602 一个字节 处理
{
LCD1602_e=0;
LCD1602_rs=order;
LCD1602_dat=dat;
LCD1602_rw=0;
LCD1602_e=1;
delay(1);
LCD1602_e=0;
}
void LCD1602_writebyte(uchar *prointer) //1602 字符串 处理
{
while(*prointer!='\0')
{
LCD1602_write(1,*prointer);
prointer++;
}
}
void LCD1602_cls() //1602 初始化
{
LCD1602_write(0,0x01); //1602 清屏 指令
delay(1500);
LCD1602_write(0,0x38); // 功能设置 8位、5*7点阵
delay(1500);
LCD1602_write(0,0x0c); //设置 光标 不显示开关、不显示光标、字符不闪烁
LCD1602_write(0,0x06);
LCD1602_write(0,0xd0);
delay(1500);
}
uchar key_fs() //矩阵按键返回按码
{
uchar fs=255;
P1=0x0f;
if(P1!=0x0f)
{
delay(800);
P1=0x0f;
if(P1!=0x0f)
{
ptem=P1;
P1=0xf0;
ptem=ptem|P1;
switch (ptem)
{
case 0xe7:
fs=1;
break;
case 0xd7:
fs=2;
break;
case 0xb7:
fs=3;
break;
case 0x77:
fs=10;
break;
case 0xeb:
fs=4;
break;
case 0xdb:
fs=5;
break;
case 0xbb:
fs=6;
break;
case 0x7b:
fs=11;
break;
case 0xed:
fs=7;
break;
case 0xdd:
fs=8;
break;
case 0xbd:
fs=9;
break;
case 0x7d:
fs=12;
break;
case 0xee:
fs=13;
break;
case 0xde:
fs=0;
break;
case 0xbe:
fs=14;
break;
case 0x7e:
fs=15;
break;
}
P1=0x0f;
while(P1!=0x0f)
{
P1=0x0f;
}
}
}
return(fs);
}
void show() //显示程序
{
LCD1602_write(0,0x80);
LCD1602_writebyte("===Coded Lock===");
}
unsigned char coding_1(unsigned char m)
{
unsigned char k;
switch(m)
{
case (0x0c): k=1;break;
case (0x18): k=2;break;
case (0x5e): k=3;break;
case (0x08): k=4;break;
case (0x1c): k=5;break;
case (0x5a): k=6;break;
case (0x42): k=7;break;
case (0x52): k=8;break;
case (0x4a): k=9;break;
case (0x09): k=13;break;
case (0x16): k=0;break;
case (0x19): k=14;break;
case (0x0d): k=15;break;
case (0x07): k=12;break;
}
return(k);
}
void key() //按键键码处理程序
{
uchar fz=255,i;
if(irbyte[2]!=0)
{
fz=coding_1(irbyte[2]);
do
{
qing();
deal_with();
}while(irbyte[2]!=0);
}else
{
fz=key_fs();
}
if(fz!=255)
{
beep2=1;beep=0;
delay(10000);
beep2=0;beep=1;
}
if(step==0)
{
if(fz<10&&cq==0&&n<6)
{
if(n==0)
{
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc0);
LCD1602_writebyte("Pass:");
}
mm_n1[n]=fz;
n++;
LCD1602_write(0,0xc5);
for(i=0;i<n;i++)
{
LCD1602_writebyte("*");
}
}
}else if(step==1|step==2)
{
if(fz<10&&n<6)
{
mm_n1[n]=fz;
n++;
LCD1602_write(0,0xc9);
for(i=0;i<n;i++)
{
LCD1602_writebyte("*");
}
}
}else if(step==3)
{
if(fz<10&&n<6)
{
mm_n2[n]=fz;
n++;
LCD1602_write(0,0xc6);
for(i=0;i<n;i++)
{
LCD1602_writebyte("*");
}
}
}
switch(fz)
{
case 11:
break;
case 12:
if(n!=0)
{
n--;
if(step==0)
{
mm_n1[n+1]=0xff;
LCD1602_write(0,0xc5);
for(i=0;i<n;i++)
{
LCD1602_writebyte("*");
}
for(i=0;i<6-n;i++)
{
LCD1602_writebyte(" ");
}
}else if(step==1|step==2)
{
mm_n1[n+1]=0xff;
LCD1602_write(0,0xc9);
for(i=0;i<n;i++)
{
LCD1602_writebyte("*");
}
for(i=0;i<6-n;i++)
{
LCD1602_writebyte(" ");
}
}else if(step==3)
{
mm_n2[n+1]=0xff;
LCD1602_write(0,0xc6);
for(i=0;i<n;i++)
{
LCD1602_writebyte("*");
}
for(i=0;i<6-n;i++)
{
LCD1602_writebyte(" ");
}
}
}
break;
case 13:
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc0);
LCD1602_writebyte("Password");
step=0;
cq=0;
n=0;
led=0;
zt[0]='N';
zt[1]='O';
WrToROM(zt,10,2);
break;
case 14:
if(step==0)
{
if(n==6)
{
n=0;
for(i=0;i<6;i++)
{
if(mm[i]!=mm_n1[i])
{
break;
}
}
if(i==6)
{
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc5);
LCD1602_writebyte("Open");
led=1;
zt[0]='O';
zt[1]='K';
WrToROM(zt,10,2);
cq=1;
cw=0;
}else if(mm_n1[0]==1&&mm_n1[1]==3&&mm_n1[2]==1&&mm_n1[3]==4&&mm_n1[4]==2&&mm_n1[5]==0)
{
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc3);
LCD1602_writebyte("Pass init");
for(j=0;j<6;j++)
{
mm[j]=0;
}
cw=0;
WrToROM(mm,0,6);
}else
{
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc5);
LCD1602_writebyte("Error");
time=3;
cw++;
if(cw>2)
{
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc2);
LCD1602_writebyte("Locked state");
while(1)
{
beep1=1;
cw=3;
time=5;
}
}
}
}else
{
n=0;
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc5);
LCD1602_writebyte("Error");
time=3;
cw++;
if(cw>2)
{
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc2);
LCD1602_writebyte("Locked state");
while(1)
{
beep1=1;
cw=3;
time=5;
}
}
}
}else if(step==1)
{
if(n==6)
{
n=0;
for(i=0;i<6;i++)
{
if(mm[i]!=mm_n1[i])
{
break;
}
}
if(i==6)
{
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc0);
LCD1602_writebyte("New pass:");
step=2;
}else
{
step=0;
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc5);
LCD1602_writebyte("Error");
}
}else
{
step=0;
n=0;
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc5);
LCD1602_writebyte("Error");
}
}else if(step==2)
{
if(n==6)
{
n=0;
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc0);
LCD1602_writebyte("Again:");
step=3;
}else
{
step=0;
n=0;
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc5);
LCD1602_writebyte("Error");
}
}else
{
step=0;
if(n==6)
{
n=0;
for(i=0;i<6;i++)
{
if(mm_n1[i]!=mm_n2[i])
{
break;
}
}
if(i==6)
{
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc4);
LCD1602_writebyte("Pass OK");
for(i=0;i<6;i++)
{
mm[i]=mm_n1[i];
}
WrToROM(mm,0,6);
}else
{
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc5);
LCD1602_writebyte("Error");
}
}else
{
n=0;
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc5);
LCD1602_writebyte("Error");
}
}
break;
case 15:
step=1;
n=0;
LCD1602_write(0,0xc0);
LCD1602_writebyte(" ");
LCD1602_write(0,0xc0);
LCD1602_writebyte("Old pass:");
break;
}
}
void main() //主程序
{
TMOD=0x12;
TH0=0;
TL0=0;
TH1=0x3c;
TL1=0xb0;
EA=1;
ET0=1;
ET1=1;
TR0=1;
TR1=1;
EX0=1;
IT0=1;
LCD1602_cls();
RdFromROM(zt,10,2);
if(zt[0]=='O'&&zt[1]=='K')
{
led=1;
}else
{
led=0;
}
show();
LCD1602_write(0,0xc0);
LCD1602_writebyte("Password");
RdFromROM(mm,0,6);
while(1)
{
if(irdateok==1) //解码完成处理
{
irdateok=0;
deal_with();
}
key();
}
}
void time3_interrupt()interrupt 3
{
TH1=0x3c;
TL1=0xb0;
ms++;
if(ms%3==0)
{
if(beep2==0)
{
if(beep1==1)
{
beep=!beep;
}else
{
beep=1;
}
}
}
if(ms>19)
{
ms=0;
if(time!=0)
{
time--;
beep1=1;
}
else beep1=0;
}
}
//==================================定时器0中断函数,用于数码管扫描显示====================================
void time0_interrupt()interrupt 1
{
irtime++;
}
void int0() interrupt 0 //遥控器解码
{
if(irflag==1)
{
if(irtime>32)
{
bitnum=0;
}
irdate[bitnum]=irtime;
irtime=0;
bitnum++;
if(bitnum==33)
{
bitnum=0;
irdateok=1;
}
}
else
{
irflag=1;
irtime=0;
}
}
相关问答
51 单片机红外遥控 最简单编程法?红外遥控最简单的编程法是使用51单片机的定时器功能和外部中断功能来实现红外接收和解码。首先需要配置定时器和外部中断的相关寄存器,然后编写中断服务程序来...
红外遥控 开关设计制作方法是什么?-设计本有问必答2,在灯具的接线端,靠近灯的位置(一定要在靠近的灯位置,其他位置没用),连接一个电容和灯具并联。备注:零火线串联技术的遥控开关,可能不能控制15W...
能否用 单片机 控制发射 红外 信号来控制空调?空调遥控器本来就是用单片机控制发射红外信号来遥控控制空调的!控制原理如下:本文介绍一种利用红外线发射装置作为工业控制计算机输入键盘的接口原理和实现...
目前在学 单片机 ,已经学会做流水灯了,怎么做 红外遥控 灯?用单片机制作遥控灯的方法还是比较多的,可以用无线电遥控灯、可以用蓝牙技术控制灯、还可以用无线发射模块nRF24L01实现无线射频遥控遥控灯。当然我们根据题目的...
智能循迹 红外遥控 车方案怎么做?这样的方案应该不少,现在做的比较成熟的方案应该是英唐众创的。智能循迹部分是基于红外反射式光电传感器的寻迹原理,采用STC89C52单片机为核心控制单元,控制...
如何把串口信号生成一个按键? 单片机 不知道该怎么把 红外 信号...单片机不知道该怎么把红外信号转化成电脑按键。请大神细细道来,送分多谢笔记本电脑大神讨论回答(3)将我做的一个项目的相关程序段摘录出来,提供给你一个...
自动循迹 红外 检测障碍物有 遥控 器吗?自动循迹红外检测障碍物有遥控器,本经验介绍了一种采用STC89C52、L298N和TCRT5000设计的智能循迹和红外遥控的智能遥控车。智能循迹采用红外传感器检测路面信...
vs18388 红外 接收头和 单片机 之间采用什么协议进行通信?红外接收头和单片机之间采用了红外传输协议进行通信,这样就也可以利用红外特性进行快速通讯红外接收头和单片机之间采用了红外传输协议进行通信,这样就也可以...
单片机 怎样与手机通讯?1.串口对串口(不过一般普通用户不太容易连接到手机的串口)2.蓝牙:单片机+蓝牙模块-》手机蓝牙模块-》手机上应用程序3.红外:单片机+红外模块-》手机红外模块...
android手机和 单片机 如何实现相互通讯?1.串口对串口(不过一般普通用户不太容易连接到手机的串口)2.蓝牙:单片机+蓝牙模块-》手机蓝牙模块-》手机上应用程序3.红外:单片机+红外模块-》手机红外模块...