采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制
的"0";以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的"1,上述"0"和
"1"组成的32位二进制码经38kHz的载频进行二次调制以提高发射效率,达到降低电源功耗的
目的。然后再通过红外发射二极管产生红外线向空间发射,遥控编码是连续的32位二进制码
组,其中前16位为用户识别码,能区别不同的电器设备,防止不同机种遥控码互相干扰。该
芯片的用户识别码固定为十六进制01H后16位为8位 *** 作散隐码(功能码)及其反码。
当一个键按下超过36ms,振荡器使芯片激活,将发射一组108ms的编码脉冲,这108ms发射代码
由冲亮厅一个起始码(9ms),一个结果码(4.5ms),低8位地址码(9ms~18ms),高8位地址码
(9ms~18ms),8位数据码(9ms~18ms)和这8位数据的反码(9ms~18ms)组成。如果键按下超
过108ms仍未松开,接下来发射的代码(连发代码)将仅由起始码(9ms)和结束码(2.5ms)
组成。
解码的关键是如何识别"0"和"键核1",接收端而言,"0"是0.56ms的高+0.56ms的低。"1"是1.68ms
的高+0.56ms的低。所以可以根据高电平的宽度区别"0"和"1"。当高电平出现时开始延时,
0.56ms以后,若读到的电平为低,说明该位为"0",反之则为"1",为了可靠起见,延时必须
比0.56ms长些,但又不能超过1.12ms,否则如果该位为"0",读到的已是下一位的高电平,因此
取(1.12ms+0.56ms)/2=0.84ms最为可靠,一般取0.84ms左右均可。
其实如果你是用单片机来解码或编码发送的话,我卖码锋可以提供电路图及程序(发送和接收)(c):
发送程序:
/*********************************************************
采用6221编码方式
晶振:12M
红外发送时模握,数据低位在前,高位在后
*********************************************************/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define nop() _nop_()
uchar bdata tt
uchar x
sbit OP=tt^1 //红外发射管的亮灭
unsigned int count //延时计数器
unsigned int endcount //终止延时计数
unsigned char flag //红外发送标志
uchar iraddr1 //十六位地址的第一个字节
uchar iraddr2 //十六位地址的第二个字节
sbit yaokong = P3^2
void SendIRdata(char p_irdata)
void delay()
void main(void)
{
count = 0
flag = 0
OP = 0
yaokong = 0
EA = 1
TMOD = 0x11
ET0 = 1
TH0 = 0xFF
TL0 = 0xE6 //设定时值0为38K 也就是每隔26us中断一次
TR0 = 1
iraddr1=0x03
iraddr2=0xfc
do
{
for(x=125x<0x--)
SendIRdata(0x0c)
}while(1)
}
//定时器0中断处理
void timeint(void) interrupt 1
{
TH0=0xFF
TL0=0xE6 //设定时值为38K 也就是每隔26us中断一次
count++
if (flag==1)
{
OP=~OP
}
else
{
OP = 0
}
yaokong = OP
}
void SendIRdata(char p_irdata)
{
int i
char irdata=p_irdata
endcount=223
flag=1
count=0
do
{
}while(count<endcount)
endcount=117
flag=0
count=0
do
{
}while(count<endcount)
irdata=iraddr1
for(i=0i<8i++)
{
endcount=10
flag=1
count=0
do{}while(count<endcount)
if(irdata-(irdata/2)*2)
{
endcount=41
}
else
{
endcount=15
}
flag=0
count=0
do{}while(count<endcount)
irdata=irdata>>1
}
irdata=iraddr2
for(i=0i<8i++)
{
endcount=10
flag=1
count=0
do{}while(count<endcount)
if(irdata-(irdata/2)*2)
{
endcount=41
}
else
{
endcount=15
}
flag=0
count=0
do{}while(count<endcount)
irdata=irdata>>1
}
irdata=p_irdata
for(i=0i<8i++)
{
endcount=10
flag=1
count=0
do{}while(count<endcount)
if(irdata-(irdata/2)*2)
{
endcount=41
}
else
{
endcount=15
}
flag=0
count=0
do{}while(count<中晌endcount)
irdata=irdata>>1
}
irdata=~p_irdata
for(i=0i<8i++)
{
endcount=10
flag=1
count=0
do{}while(count<endcount)
if(irdata-(irdata/2)*2)
{
endcount=41
}
else
{
endcount=15
}
flag=0
count=0
do{}while(count<endcount)
irdata=irdata>>1
}
endcount=10
flag=1
count=0
do{}while(count<endcount)
flag=0
}
void delay()
{
int i,j
for(i=0i<400i++)
{
for(j=0j<100j++)
{
}
}
}
红外遥控程序#include "SPCE061A.H"
#define LED_SEG 0x00ff //IOB0~IOB7
#define LED_DIG 0x3f00 //IOB8~IOB13
unsigned int Time=0,Code[40]={0},CodeNum=0//计数器,32位码,码字计数
//extern unsigned int Time,CodeNum,Code[40]
unsigned int Star_Flag,First_IRQ
//====================================================================================
//函数名称:unsigned getkey(void)
//函数功能:获得红外遥控器键值
//入口参数:无
//出口参数:无
//说明:适用于32位码字红外接收头及宏科万能遥控器
//====================================================================================
unsigned getkey(void)
{
unsigned int j=0
unsigned int DateCode,key=0
if(Code[0]==5) //判断头部是否是5;防止误接收
{ for(j=9j<=14j++)
{
*P_Watchdog_Clear = 0x01
if(Code[j]==1&&Code[j+1]==1&&Code[j+2]==1&&Code[j+3]==1&&Code[j+4]==1&&Code[j+5]==1&&Code[j+6]==0&&Code[j+7]==1)
{ //判断用户识别码是不是1111 1101
for(DateCode=0DateCode<8DateCode++)//若是,则开始接收八位数据码
{
Code[j+8+DateCode]<<=8
key|=Code[j+8+DateCode]
key>>=1 //将八位二进制数倒序转成16进制
}
break
}
}
Code[0]=0//将头部清零
return key//返回键值
}
else return(0)
}
//====================================================================
//函数名称:void IO_Init()
//函数功能:IO口初始化,主要是设置IOB2口,用于外中断
//入口参数:无
//出口参数:无
//====================================================================
void IO_Init()
{
*P_IOB_Attrib&=0xfffb //IOB2端口上拉电阻输入 外中断
*P_IOB_Dir&=0xfffb
*P_TimerA_Ctrl=C_SourceA_32768Hz+C_SourceB_1//TimerA:32768Hz
*P_TimerA_Data=0xfffe
*P_INT_Ctrl=C_IRQ3_EXT1|C_IRQ1_TMA// 外中断1,时基中断,定时中断
__asm("INT IRQ")
}
//做档=====================================================================
//函数并厅名称:
//函数功能绝胡隐:中断函数
//入口参数:无
//出口参数:无
//=====================================================================
void IRQ3(void) __attribute__ ((ISR))
void IRQ3(void)
{
if(*P_INT_Ctrl&C_IRQ3_EXT2)
{ //IRQ3_Ext1
*P_INT_Clear=C_IRQ3_EXT2
}
else if(*P_INT_Ctrl&C_IRQ3_EXT1)
{//外中断1用于判断脉冲个数
if(!First_IRQ) {Time=0First_IRQ=1}//第一次外中断来时设置
else
{
if(Time>180&&Time<240)//判断起始码
{Star_Flag=1CodeNum=0Code[0]=5CodeNum=1Time=0}//起始码来时设置
if(Star_Flag)//开始接收
{
if((Time>=10)&&(Time<25))Code[CodeNum]=0//计数值设置
else if((Time>25)&&(Time<40))Code[CodeNum]=1
CodeNum++//码字计数器加1
Time=0//计数值清零,以对下一个脉冲宽度进行计时
if(CodeNum>40) {CodeNum=0Star_Flag=0First_IRQ=0}//脉冲个数判断,共32个,此处设为40,是为防止漏接收
}
}
*P_INT_Clear=C_IRQ3_EXT1
}
else
{
*P_INT_Clear=C_IRQ3_KEY//IRQ3_KeyWakeUp
}
}
void IRQ1(void) __attribute__ ((ISR))
void IRQ1(void)
{ Time++//计数以获得脉冲宽度
*P_INT_Clear=C_IRQ1_TMA//clear INT flag
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)