⑴ 单片机 红外解码
红外线遥控是目前使用最广泛的一种通信和遥控手段。由于红外线遥控装置具有体积小、功耗低、功能强、
成本低等特点,因而,继彩电、录像机之后,在录音机、音响设备、空凋机以及玩具等其它小型电器装置上也纷
纷采用红外线遥控。工业设备中,在高压、辐射、有毒气体、粉尘等环境下,采用红外线遥控不仅完全可靠而且
能有效地隔离电气干扰。
1 红外遥控系统
通用红外遥控系统由发射和接收两大部分组成。应用编/解码专用集成电路芯片来进行控制操作,如图1 所示。
发射部分包括键盘矩阵、编码调制、LED 红外发送器;接收部分包括光、电转换放大器、解调、解码电路。
遥控发射器及其编码
遥控发射器专用芯片很多,根据编码格式可以分成两大类,这里我们以运用比较广泛,解码比较容易的一类
来加以说明,现以日本NEC 的uPD6121G 组成发射电路为例说明编码原理(一般家庭用的DVD、VCD、音响都使用
这种编码方式)。当发射器按键按下后,即有遥控码发出,所按的键不同遥控编码也不同。这种遥控码具有以下
特征:
采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms 的组合表示二进制的“0”;以脉
宽为0.565ms、间隔1.685ms、周期为2.25ms 的组合表示二进制的“1”.
上述“0”和“1”组成的32 位二进制码经38kHz 的载频进行二次调制以提高发射效率,达到降低电源功耗的
目的。然后再通过红外发射二极管产生红外线向空间发射
UPD6121G 产生的遥控编码是连续的32 位二进制码组,其中前16 位为用户识别码,能区别不同的电器设备,
防止不同机种遥控码互相干扰。该芯片的用户识别码固定为十六进制01H;后16 位为8 位操作码(功能码)及其
反码。UPD6121G 最多额128 种不同组合的编码。
遥控器在按键按下后,周期性地发出同一种32 位二进制码,周期约为108ms。一组码本身的持续时间随它包
含的二进制“0”和“1”的个数不同而不同,大约在45~63ms 之间.
2 遥控发射器及其编码
遥控发射器专用芯片很多,根据编码格式可以分成两大类,这里我们以运用比较广泛,解码比较容易的一类
来加以说明,现以日本NEC 的uPD6121G 组成发射电路为例说明编码原理(一般家庭用的DVD、VCD、音响都使用
这种编码方式)。当发射器按键按下后,即有遥控码发出,所按的键不同遥控编码也不同。这种遥控码具有以下
特征:
采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms 的组合表示二进制的“0”;以脉
宽为0.565ms、间隔1.685ms、周期为2.25ms 的组合表示二进制的“1”
上述“0”和“1”组成的32 位二进制码经38kHz 的载频进行二次调制以提高发射效率,达到降低电源功耗的
目的。然后再通过红外发射二极管产生红外线向空间发射。
UPD6121G 产生的遥控编码是连续的32 位二进制码组,其中前16 位为用户识别码,能区别不同的电器设备,
防止不同机种遥控码互相干扰。该芯片的用户识别码固定为十六进制01H;后16 位为8 位操作码(功能码)及其
反码。UPD6121G 最多额128 种不同组合的编码。
遥控器在按键按下后,周期性地发出同一种32 位二进制码,周期约为108ms。一组码本身的持续时间随它包
含的二进制“0”和“1”的个数不同而不同,大约在45~63ms 之间。
遥控信号接收
接收电路可以使用一种集红外线接收和放大于一体的一体化红外线接收器,不需要任何外接元件,就能完成
从红外线接收到输出与TTL 电平信号兼容的所有工作,而体积和普通的塑封三极管大小一样,它适合于各种红外
线遥控和红外线数据传输。
接收器对外只有3 个引脚:Out、GND、Vcc 与单片机接口非常方便
① 脉冲信号输出接,直接接单片机的IO 口。
② GND 接系统的地线(0V);
③ Vcc 接系统的电源正极(+5V);
⑵ c51单片机红外NEC编码解码!
这个程序太简单了,我之前写过红外发射程序的,接收程序也很简单,你这个项目我2个小时都能帮你解决,但是89C52单片机发射38K不准需要把晶振加大,提高单片机的运行速度。
你的项目只要主机A发射红外协议后面加一个地址,单片机B接收的时候全部进入接收状态,判接收的地址是否符合对于单片机B的地址,如果地址符合,那就先回应一个数据例如:55FF55,主机接收到55FF55后后面开始接收数据,把接收到的数据直接写入单片机内EEPRM里面!
⑶ 单片机控制红外遥控编码解码中定时器和外部中断的作用是什么红外遥控编码解码的大致步骤是什么
同时使用上定时器 跟 外中断 的红外程序,只有解码程序。而且该方式,只能解析 使用不同时间长度代表数据“0”、“1” 的波形(如数据‘1’的时间长度 2倍于数据‘0’的时间)。
解析原理:外部中断接 红外输入,当有 红外信号的时候,该引脚会有波形输入(N多下降沿),触发外部中断,通过记录 每2次中断的时间间隔,可以判断此段时间对应的数据(0/1)。一般“数据”长度为32位数据
注意点:
①初次产生外中断的时候,并无 时间记录,不需要进行时间判断;
②第二次中断与第一次中断 之间 的时间,是 红外的引导码,该时间一般多倍于数据时间(一般为ms级时间);
③第三次中断与第二次中断的时间,即为 第一个数据 的时间;
④第34次中断与第33次中断的时间间隔,即为 第32个数据的时间;
⑤后面 可能存在 停止位,是否存在,由遥控器决定;不过,一般都直接忽略该位,除非该位是由自己制作的遥控器 发出 的校验位;
⑥后面 可能存在 连发码,是否存在,由遥控器决定;
另外:一般红外数据的每个字节都是LSB在前,MSB在后的( 低位先发,高位后发)
软件要处理以下情况:
①干扰的处理,有些红外接收头不仅仅对38KHz频率光有反应,可能对人体红外、日光灯红外一样有反应,那就存在干扰。如果它只产生一次干扰,就会使系统卡在引导码接收阶段;
②引导码时间过短、过长 的处理;
③接收数据位数不足的处理;
④完成32位数据接收后,处理接收烂尾:后面不会有中断(如果需接收停止位、连发码,就增加对应数据长度),需要停止计时。
⑤进行数据校对,一般第一字节跟第二字节互为反码,第三字节跟第四字节互为反码,而且第一字节 代表 一个地址、一个密码,只有地址、密码正确,才能算合法的操作。
⑷ 单片机红外解码程序问题,完全不能理解
“我并非一点基础也没有”
很遗憾,从你提的这三个问题来看,你的基础比0只多出一点点。
(1)Tc是个16位整型。这是16位整型的基本算法。Tc保存的是抓出的脉宽。
(2)引导码就是指定宽度的脉冲,数据码是短一些的脉冲——所以才会那么大费周章地抓脉宽判断是引导码还是用户码。接收是否反相要查你所用接收头的手册,有可能跟你的程序是相反的。
(3)m不是字节序号而是位序号。注意前面的/8。
加油啊
⑸ 遥控器红外用单片机解码问题。
那不可能肯定是你解码,数据转换问题,你把读出来的编码转化成10进制就不会出现这样的问题了,没有看到你的程序是什么样的,一般你这样的情况是16进制出问题。
不如键码
0x05;
键码
0xE5;
这两个编码就会一样,因为没有计算高8位,低8位相同,这样就会出现你所说的那种问题。
⑹ 单片机红外解码
过后就不不能明白你明白你们,
⑺ 单片机的红外遥控的原理
1、发送端由单片机和红外发光二极管组成。
单片机控制红外发光二极管发射38KHz左右的红外光,这个红外光就可能起到传递信号的作用。你可以在你的程序中规定发射红外线时表示二进制的一个位‘1’无红外线时表示二进制的‘0’。这样你就可以发出一系列由‘1’和‘0’所级成的信号。
2、接收端是由红外接收二极管和单片机组成。
前面我们让发射端发出信号,现在接收头就开始收信号。
⑻ 单片机红外解码
红外解码程序!
/*-----------------------------------------------
名称:遥控器红外解码液晶显示
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<stdio.h>
#include<intrins.h>
#define TURE 1
#define FALSE 0
sbit IR=P3^2; //红外接口标志
sbit RS = P2^4;//Pin4
sbit RW = P2^5;//Pin5
sbit E = P2^6;//Pin6
#define Data P0//数据端口
unsigned int hour,minute,second,count;
char code Tab[16]="0123456789ABCDEF";
char data TimeNum[]=" ";
char data Test1[]=" ";
/******************************************************************/
/* 变量声明 */
/******************************************************************/
unsigned char irtime;//红外用全局变量
bit irpro_ok,irok;
unsigned char IRcord[4]; //处理后的红外码,分别是 客户码,客户码,数据码,数据码反码
unsigned char irdata[33]; //33个高低电平的时间数据
/******************************************************************/
/* 函数声明 */
/******************************************************************/
void Ir_work(void);
void Ircordpro(void);
void ShowString (unsigned char line,char *ptr);
/******************************************************************/
/* 定时器0中断服务函数 */
/******************************************************************/
void tim0_isr (void) interrupt 1 using 1//定时器0中断服务函数
{
irtime++; //用于计数2个下降沿之间的时间
}
/******************************************************************/
/* 外部中断0函数 */
/******************************************************************/
void ex0_isr (void) interrupt 0 using 0//外部中断0服务函数
{
static unsigned char i; //接收红外信号处理
static bit startflag; //是否开始处理标志位
if(startflag)
{
if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
i=0;
irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
else
{irtime=0;startflag=1;}
}
/******************************************************************/
/* 定时器0初始化 */
/******************************************************************/
void TIM0init(void)//定时器0初始化
{
TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
TH0=0x00; //重载值
TL0=0x00; //初始化值
ET0=1; //开中断
TR0=1;
}
/******************************************************************/
/* 外部中断初始化 */
/******************************************************************/
void EX0init(void)
{
IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1; //使能外部中断
EA = 1; //开总中断
}
/******************************************************************/
/* 红外键值处理 */
/******************************************************************/
void Ir_work(void) //红外键值散转程序
{
TimeNum[5] = Tab[IRcord[0]/16]; //处理客户码并显示
TimeNum[6] = Tab[IRcord[0]%16];
TimeNum[8] = Tab[IRcord[1]/16]; //处理客户码并显示
TimeNum[9] = Tab[IRcord[1]%16];
TimeNum[11] = Tab[IRcord[2]/16]; //处理数据码并显示
TimeNum[12] = Tab[IRcord[2]%16];
TimeNum[14] = Tab[IRcord[3]/16]; //处理数据反码并显示
TimeNum[15] = Tab[IRcord[3]%16];
ShowString(1,TimeNum);//显示处理过后的码值
irpro_ok=0; //处理完成后清楚标志位
}
/******************************************************************/
/* 红外解码函数处理 */
/******************************************************************/
void Ircordpro(void)//红外码值处理函数
{
unsigned char i, j, k;
unsigned char cord,value;
k=1;
for(i=0;i<4;i++) //处理4个字节
{
for(j=1;j<=8;j++) //处理1个字节8位
{
cord=irdata[k];
if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
{
value=value|0x80;
}
else
{
value=value;
}
if(j<8)
{
value=value>>1;
}
k++;
}
IRcord[i]=value;
value=0;
} irpro_ok=1;//处理完毕标志位置1
}
/******************************************************************/
/* 微秒延时函数 */
/******************************************************************/
void DelayUs(unsigned char us)//delay us
{
unsigned char uscnt;
uscnt=us>>1;/* Crystal frequency in 12MHz*/
while(--uscnt);
}
/******************************************************************/
/* 毫秒函数声明 */
/******************************************************************/
void DelayMs(unsigned char ms)//delay Ms
{
while(--ms)
{
DelayUs(250);
DelayUs(250);
DelayUs(250);
DelayUs(250);
}
}
/******************************************************************/
/* 写入命令函数 */
/******************************************************************/
void WriteCommand(unsigned char c)
{
DelayMs(5);//操作前短暂延时,保证信号稳定
E=0;
RS=0;
RW=0;
_nop_();
E=1;
Data=c;
E=0;
}
/******************************************************************/
/* 写入数据函数 */
/******************************************************************/
void WriteData(unsigned char c)
{
DelayMs(5); //操作前短暂延时,保证信号稳定
E=0;
RS=1;
RW=0;
_nop_();
E=1;
Data=c;
E=0;
RS=0;
}
/******************************************************************/
/* 写入字节函数 */
/******************************************************************/
void ShowChar(unsigned char pos,unsigned char c)
{
unsigned char p;
if (pos>=0x10)
p=pos+0xb0; //是第二行则命令代码高4位为0xc
else
p=pos+0x80; //是第二行则命令代码高4位为0x8
WriteCommand (p);//写命令
WriteData (c); //写数据
}
/******************************************************************/
/* 写入字符串函数 */
/******************************************************************/
void ShowString (unsigned char line,char *ptr)
{
unsigned char l,i;
l=line<<4;
for (i=0;i<16;i++)
ShowChar (l++,*(ptr+i));//循环显示16个字符
}
/******************************************************************/
/* 初始化函数 */
/******************************************************************/
void InitLcd()
{
DelayMs(15);
WriteCommand(0x38); //display mode
WriteCommand(0x38); //display mode
WriteCommand(0x38); //display mode
WriteCommand(0x06); //显示光标移动位置
WriteCommand(0x0c); //显示开及光标设置
WriteCommand(0x01); //显示清屏
}
/******************************************************************/
/* 主函数 */
/******************************************************************/
void main(void)
{
EX0init(); //初始化外部中断
TIM0init();//初始化定时器
InitLcd(); //初始化液晶
DelayMs(15);
sprintf(Test1," haixiang MCU "); //显示第一行固定信息
ShowString(0,Test1);
sprintf(TimeNum,"Code ");//显示第二行固定信息
ShowString(1,TimeNum);
while(1)//主循环
{
if(irok) //如果接收好了进行红外处理
{
Ircordpro();
irok=0;
}
if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
{
Ir_work();
}
}
}
⑼ 关于51单片机红外解码程序,哪位大侠帮我看下
我以前做的一个项目,红外遥控开关,解码部分的code,供参考
6121码,外部中断0,at89s52
void int0() interrupt 0 //外部中断1服务函数,红外解码程序
{
static uchar wei; //定义静态变量
static uchar pp; //定义静态变量
if(tt<56&&tt>50) {d2=0; tt=0;pp=0;wei=0;}//起始信号符合,将d2标记为0,各变量清零
if(tt>11)tt=0;
if(d2==0&&tt>=4)
{
buf[pp]>>=1;
if(tt>5) buf[pp]|=0x80; //如果时间大于780us ,则视为收到数据1
wei++;
if(wei==8)
{
pp++;
wei=0;
if(pp==4) { pp=0; d2=1;} //接收满4个字节,标志位清除
} //在 d2为0期间进入中断8次,说明已经收到一个字节数据,字节号加1
}
tt=0;//每次进入中断都清零
}
void timer1() interrupt 3 //红外解码计时
{
tt++;
}