正点原子的ALIENTEK遥控器
用户码00ff
16进制键值码表
45 46 47
44 40 43
07 15 09
16 19 0d
0c 18 5e
08 1c 5a
42 ☻ 4a
红外接收管 通用型即可
---------------------------------------------------------------------------
下面是类似的波形图,这个是网上找的,图片较大,缩小后看上去有些模糊,不过没关系,数据手册上一般都有
遥控器在发射红外信号之前,我们的mcu已经开启了定时器
在定时器中断函数中的全局变量irTimeCounts++ 一直在自加
irTimeCounts多长时间加一次? 或者说多长时间进入一次定时器中断函数呢?
在方式2时,t=256*12/11059200 约为277.78us
============================================================
1.对于1.125ms的时间,timer0会中断1.125/t=4.05次 也就是要5次,算上各种误差,(顶多5次,至少4次)
2.对于2.25ms 的时间,timer0会中断 2.25/t=8.1次, 也就是要9次,算上各种误差,(顶多9次,至少8次)
对于这里的次数,比N次小一点,就是N次,比N次大一点,就是N+1次,因为不会有半次,
误差给它正负0.4次足够了,给了误差后再算次数,直接舍入就行
那么我们就检测irTimeCounts的值,
如果小于6或7,那么接收到的数据为0
如果大于6或7,那么接收到的数据为1
从计算结果来看,我觉得0.56,1.125,2.25这些值的出现是比较合理的,
能有效避免由于器件误差和环境造成的数据误判,而且计算也方便
#include "my51.h" #include "ir.h" #include "smg.h" void main() { timer0Init(); //定时器0初始化 int0Init(); //外部中断0初始化 while(1) { if(irTimeCountsArrProcess()) //如果成功接收并解析完成一帧数据 { //就让蜂鸣器响一下 beep=0; //蜂鸣器开启 led4=~led4; //4号灯反转一下 } displaySMG(irCodeByteDataProcessForSmg());//显示 beep=1; //蜂鸣器关闭 //由于displaySMG()函数执行时间较短,故蜂鸣器响声时间也较短,听到滴了一下 } }
#ifndef _51IR_H_ #define _51IR_H_ #include "my51.h" extern u8 data smgWela[7]; //数码管显示的数据 extern void int0Init(); //外部中断0初始化 extern void timer0Init(); //定时器0初始化 extern bool irTimeCountsArrProcess(); //成功解析一帧中断数据返回TRUE extern u8* irCodeByteDataProcessForSmg();//将遥控器码值处理成数码管可显示数据 #endif
#include "ir.h" u8 irTimeCounts=0; //定时器0在方式2下8位自动重装时的中断计数值 u8 irTimeCountsArr[32]={0}; //存放红外接收数据时的中断次数记录值, u8 bitNum=0; //标志当前接收的是第几个比特位 u8 irReceFlag=0; //红外接收一帧数据未完成标志,为1时完成 u8 irCodeByteData[4]={0}; //保存接收到的4个字节的有效数据 u8 irTimeCountsArrProcessOk=0;//对接收到的33位数据处理未完成标志,1完成 void int0Init(); //外部中断0初始化 void timer0Init(); //定时器0初始化 bool irTimeCountsArrProcess(); //解析中断次数,即解码 u8* irCodeByteDataProcessForSmg();//将遥控器码值处理成数码管可显示数据 u8* irCodeByteDataProcessForSmg() //将解码的4字节数据处理成数码管可显示的数据 { if(irTimeCountsArrProcessOk) //检测一帧数据是否解析完成 { //这里的用户码只显示低八位,因为高八位反正都是00(手上2个遥控器都是00) //然后还显示遥控键值及其反码,我们的数码管只有6位,只显示3字节数据 if(irCodeByteData[2]+irCodeByteData[3]!=0xff)//校验数据的完整性 { //最后一个字节是键码的反码 led6=0; //调试代码 } else { smgWela[0]=irCodeByteData[1] >> 4 ; //取高4位 smgWela[1]=irCodeByteData[1] & 0x0f; //取低4位 smgWela[2]=irCodeByteData[2] >> 4 ; smgWela[3]=irCodeByteData[2] & 0x0f; smgWela[4]=irCodeByteData[3] >> 4 ; smgWela[5]=irCodeByteData[3] & 0x0f; smgWela[6]=0xff; //小数点全不显 } irTimeCountsArrProcessOk=0;//标志清零,下一次有未解析的数据时才会再解析 } return smgWela; } bool irTimeCountsArrProcess() //对接收到的32位的中断次数数据进行解析 { u8 i,j,k,value=0; if(irReceFlag) //检测是否已经接收到新的4字节的红外通信数据 { for(j=0;j<4;j++) //有4个字节 { for(i=0;i<8;i++) //对每个字节的8位数据处理 { value>>=1; if(irTimeCountsArr[k++]>6) //这里我们用6或7都是可以的 { value|=0x80; //大于6的话该位数据是1 } } irCodeByteData[j]=value;//保存该字节,也就是遥控器的键码 } irReceFlag=0; //接收标志清零,这样就会等到下次收到数据后才会再解析 irTimeCountsArrProcessOk=1; //中断数据解析完毕标志置1 return TRUE; //解析完成 } return FALSE; //未进行解析,该返回值主要是为了方便外部文件调用时判断的 } void int0() interrupt 0//外部中断0 { if(irTimeCounts>30) //9ms的话中断32.4次,30这个取值差不多就可以了,不用太精确 { //这里9ms引导码需要timer0中断irTimeCounts=9*11059.2/(256*12)=32.4次 bitNum =0; irTimeCounts=0;//为接收第0位数据做准备 return; //丢弃引导码,反正不是有效数据0或1的都丢弃,直接返回 } irTimeCountsArr[bitNum]=irTimeCounts; //将中断次数数据存储起来 irTimeCounts=0; //存好了就立即清零,这样不会影响下一位数据的接收 bitNum++; //继续下一位 if(32==bitNum) //32位数据已经接收完成(0~31已经存储) { bitNum=0; //清零,这里不清也可以,反正引导时也会清 irReceFlag=1; //接收完成标志 } } void timer0() interrupt 1 //定时器0中断函数 { irTimeCounts++; //注:该值最大为255 } void timer0Init() //定时器0初始化 { //配置工作方式寄存器,且不影响定时器1的状态 TMOD &= 0xf0; //保留定时器1的配置,并清除定时器0的配置 TMOD |= 0X02; //使用定时器0的工作方式2 TH0=0X00; TL0=0X00; //工作方式2是8位自动重装 ET0=1; //打开定时器 EA=1; //打开总中断 TR0=1; //启动定时器0 } void int0Init() //外部中断0初始化 { IT0=1; //配置外部中断0的触发方式为 跳变延触发 EX0=1; //打开外部中断0 EA=1; //打开总中断 }
#ifndef _51SMG_H_ #define _51SMG_H_ #include "my51.h" sbit dula =P2^6; //段选锁存器控制 控制笔段 sbit wela =P2^7; //位选锁存器控制 控制位置 extern u8 data smgWela[7]; //第一位到第六位,最后一个是小数点位置控制 #define dark 0x11//0x11是第17号元素,0x00是低电平,数码管不亮,即table[17] #define dotDark 0xff //小数点全暗 void displaySMG(u8* pWela); //数码管显示函数,参数是数组指针 #endif
#include "smg.h" #include "my51.h" static u8 code table[]= { //0~F外加小数点和空输出的数码管编码 0x3f , 0x06 , 0x5b , 0x4f , // 0 1 2 3 0x66 , 0x6d , 0x7d , 0x07 , // 4 5 6 7 0x7f , 0x6f , 0x77 , 0x7c , // 8 9 A B 0x39 , 0x5e , 0x79 , 0x71 , // C D E F 0x80 , 0x00 , 0x40 // . 暗 负号 暗即不显示是第17索引号 }; //负号为第18索引号元素 /* 由于此表只能一次显示一个小数点,故已注释掉,仅供查询 例如想要第一个和第六个数码管小数点同时点亮, 则执行 pWela->dot = 0xfe & 0xdf 即可 u8 code dotTable[]={ //小数点位置,某一位置0时,小数点亮 0xff , //那么全暗就是0xff 0xfe , 0xfd , 0xfb , //1 2 3 0xf7 , 0xef , 0xdf //4 5 6 };*/ u8 data smgWela[7]={0,0,0,0,0,0,0}; //第一位到第六位,最后一个是小数点位置控制 //P0口的数码管位选控制锁存器只用了低6位,我们保留高2位的数据,留作它用 void displaySMG(u8* pWela) { u8 i=0; //控制6位数码管显示函数,不显示的位用参数dark u8 preState=P0|0x3f; //保存高2位状态,其中最高位是ADC0804的片选信号 wela=0;dula=0;_nop_();//先锁定数据,防止吴亮及位选锁存器高2位数据被改变 P0=0; //由于数码管是共阴极的,阳极送低电平,灯不亮 dula=1;_nop_(); dula=0; //段选数据清空并锁定 P0=preState; //共阴极数码管是阴极置高不亮,低6位置1,高2位保留 wela=1;_nop_(); //注:wela和dula上电默认为1 wela=0; //位选锁定,初始保留高2位的数据,低6位置高不亮 for(i=0;i<6;i++) //显示6位数码管 { P0=table[pWela[i]]|(((1<<i) & pWela[6])?0x00:0x80); dula=1;_nop_(); //送段数据,叠加小数点的显示,0x00点亮小数点 dula=0; P0=preState&~(1<<i); //不影响高2位数据,低6位是数码管位选,低电平有效 wela=1; _nop_(); //送位选号 wela=0; delayms(1); //稍作延时,让灯管亮起来 { //消除叠影及误亮,阴极置1不亮,低6位置1,高2位保留并锁定 P0=preState; wela=1; _nop_(); wela=0; } } }
相关推荐
本人开发的,稳定可靠的单片机红外遥控器解码程序 C51编写. 注释详细,移植方便,任何问题欢迎交流。
设计要求:基于51单片机的红外遥控器设计 功能指标 ① 利用单片机和红外学习模块进行设计; ② 选取合适的液晶显示屏显示; ③ 红外遥控范围能在4——6米; ④ 能对相应电器的遥控器进行学习,从而实现操控相应电器。
单片机解码红外遥控器 单片机解码红外遥控器
解码最常见的NEC遥控器,资源占用较少,实际测试功能正常
使得红外发光二极管发射出一定频率的红外线,当接收控制系统接收到该红外光后,由单片机内定时/计数器得到该红外光的频率,然后将该频率送往CPU,由CPU对该信号进行反编码,识别出控制信号,控制LED灯亮,蜂鸣器发声...
51单片机-红外遥控.pdf 常用红外遥控编码资料集+ircode.pdf 单片机处理红外遥控信号.pdf 单片机发送并接收红外遥控信号的方法.pdf 单片机红外发射(原理与设计程序).pdf 单片机学习实例--红外遥控实验学习.pdf 红外...
C51单片机 项目1-单片机红外接收解码程序设计 (仿真文件+程序包)C51单片机 项目1-单片机红外接收解码程序设计 (仿真文件+程序包)C51单片机 项目1-单片机红外接收解码程序设计 (仿真文件+程序包)C51单片机 项目...
上讲介绍并应用了单片机动态扫描驱动数码管,并给出了实例。这一讲将重点介绍单片机如何通过捕获来实现对红外遥控器解码。通过该讲,读者可以掌握红外遥控器的编码原理以及如何通过单片机对遥控器进行解码。
用51单片机对普通加点遥控器进行解码,得到遥控器的按键数值。可方便进行红外遥控系统的开发。
51单片机HAL库1.0.5,参考例程:基于原有程序,增加了红外遥控功能,红外遥控程序是基于定时器2输入捕获模式实现。
用51单片机接收红外遥控并解码,然后在红外LED灯转发刚收到的遥控码,并把数据保存到AT24C256中储存,下载解压即可用keil打开,编译0错误0警告,代码全部上备注,方便查阅,方便移植
含红外线发射程序和红外线接收程序,仿真中使用两个51单片机,一个用于红外线发射(模拟遥控器),一个用于红外线接收并执行对应操作,风扇有定时,模式,调速三个功能,定时范围是1-8小时。模式有3种:自然风,睡眠...
红外遥控器解码,51单片机接受遥控器发送的信号,然后解码,将将结果显示在数码管。只有3个函数,初始化,解码和显示,使用定时器0精确计时,由于单片机随时接收遥控器信息,所以使用外部中断0,并接单片机引脚3.2.
51单片机解码红外遥控器原理,详细介绍了红外的遥控规范
作品概况:作品采用ATC89S52芯片作为主控芯片,遥控器采用TV68万能遥控器,红外接收采用1838红外一体接收,六个独立按键作为功能按键,波形显示利用太阳人液晶12864,为了使设计更人性化,我们还设计了蜂鸣器,用来...
基于51单片机的红外发射接收装置,能够控制led灯工作状态,内附完整版图和源码
51单片机做的433和315模块解码软件
51单片机的21键红外遥控解码参考程序(在数码管上显示相应数字)
本文主要介绍了51单片机红外接收解码程序,下面一起来看看
提出一种基于 AT89C51 的学习型红外遥控器的设计方案,该设计的控制器,可存放十六个遥控代码,采用九键分四区域控制,每一区域对应 一种家庭电器的四种主要功能。(附带pcb原理图及源程序等)