unsigned char SigInfo[4]//存储红外按键编码,SigInfo[2]为按键值
void Cmd_Require(void)
void INT_Ext0() interrupt 1 //外部中断0
{
u8 i, j
u16 time = 8000
EA = 0
for (i=0 i<10 i++) {
delay0_7ms ()
if (IR_OUT) {
EA = 1
return
}
}
while (!IR_OUT)
delay2_5ms ()
if (!IR_OUT) {
基岩EA = 1
return
搏郑御 }
while (IR_OUT&&time) {
time--
}
time = 8000
for (i=0 i<4 i++) {
for (j=0 j<8 j++) {
SigInfo[i] >>= 1
while (!IR_OUT)
delay0_7ms ()
if (IR_OUT) {
SigInfo[i] |= 0x80
while (IR_OUT&&time) {
time--
}
丛乱 time = 8000
}
}
}
Cmd_Require()
EA = 1
}
void Cmd_Require(void)
{
switch(SigInfo[2]) {
case 0x0c:
//此处代码随意
break
case 0x18:
//...
break
//...
default:
break
}
}
延时没写,因单片机而异的,要精确点才能解码。
#include<reg52.h>#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcden = P2^7
sbit lcdrs = P2^6
sbit lcdwr = P2^5
sbit IR = P3^2
uchar IRCOM[6]//数组,用于存储红外编码
uchar code table1[] = "remote control"
uchar code table2[] = "CODE:"
void delayms(uchar x)// 延时x*0.14ms
{
uchar i
while(x--)
for(i=0i<13i++){}
}
void delay(uchar x) //延时xms
{
uchar i,j
for(i=xi>0i--)
for(j=110j>0j--)
}
/****************************LCD部分***********************************************/
void write_com(uchar com)
{
lcden = 0
lcdrs = 0
lcdwr = 0
P0 = com
delay(5)
lcden = 1
delay(5)
lcden = 0 //别忘了lcden拉低
}
void write_date(uchar date)
{
lcden = 0
lcdrs = 1
lcdwr = 0
P0 = date
delay(5)
lcden = 1
delay(5)
lcden = 0
}
void lcd_init(void)
{
lcden = 0
lcdrs = 0
lcdwr = 0
delay(5)
write_com(0x38)
write_com(0x0c)
write_com(0x06)
write_com(0x01)
}
/*****************main()************************/
void main(void)
{
uchar count=0
IR = 1
lcd_init()
write_com(0x80)
while(table1[count]!='\0')
{
write_date(table1[count])
count++
delay(5)
}
count = 0
write_com(0x80+0x40)
while(table2[count]!='\0')
{
write_date(table2[count])
count++
delay(5)
}
IE = 0x81//开中断
TCON = 0x01//脉冲负边沿触发
while(1)
}
/*********************红外中断**************************/
void IR_time() interrupt 0
{
uchar i,j,TimeNum=0//TimeNum用来计IR高电平次数 从而判断是0还是1
EX0 = 0//关闭中断
delayms(5)
if(1 == IR)
{
EX0 = 1
return
}
while(!IR) //跳祥余孙谨链过9ms前导低电平
delayms(1)
for(i=0i<4i++)
{
for(j=0j<8j++)
{
while(IR) //跳过4.5ms的前导高电平
delayms(1)
while(!IR) //跳毁敬过0.56ms的低电平
delayms(1)
while(IR)
{
TimeNum++//计时高电平时间从而判断读取的是0还是1
delayms(1)
}
if(TimeNum>=30)//按键按下时间过长 跳过
{
EX0 = 1
return
}
IRCOM[i] = IRCOM[i]>>1
if(TimeNum >= 8) //8*0.14ms 这时读取的是1;
{
IRCOM[i] = IRCOM[i]|0x80
}
TimeNum = 0
}
}
if(IRCOM[2]!=~IRCOM[3])//判断八位数据和八位数据反码是否相等
{
EX0 = 1
return
}
IRCOM[4] = IRCOM[2]&0x0f//取低四位
IRCOM[5] = IRCOM[2]>>4 //IRCOM[5]取IRCOM[2]高四位
if(IRCOM[4] >9) //转换成字符
{
IRCOM[4] = IRCOM[4] + 0x37
}
else
IRCOM[4] = IRCOM[4] + 0x30
if(IRCOM[5] >9)
{
IRCOM[5] = IRCOM[5] + 0x37
}
else
IRCOM[5] = IRCOM[5] + 0x30
delay(5)
write_com(0x80 + 0x40 + 5)
write_date(IRCOM[5])
write_date(IRCOM[4])
EX0 = 1//重新开启外部中断
}
红外收发中,IRDATA[2]与IRDATA[3]是取反的关系。也就是说两个数对应各位前者为1后者就为0其余的问题,都是根据红外接收时序来编的程序,以下总结以下红外收发时序供参考,你读懂就可以理解了。
采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的"0";以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的"1“上述"0"和"1"组成的32位二进制码经38kHz的载频进行二次调制以提高发射效率,达到降低电源功耗的目的。然后再通过红外发射二极管产生红外线向空间发射遥拿让者控编码是连续的32位二进制码组,其中前16位为用户识别码,能区别不同的电器设备,防止不同机种遥控码互相干扰。该芯片的用户识别码固定为十六进制01H后16位为8位 *** 作码(功能码)及其反码。
发射代码由一个起始码(9ms),一个结果码(4.5ms),低8位地址码(9ms~18ms),高8位地址码(9ms~18ms),8位数据码(9ms~18ms)和这8位数据的反码(9ms~18ms)组成。
解码的关键是如何识别"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左右均可。为了共用引导部分延时程序,一般用0.9ms延时。
由此可见,有效数据是4字节(32位)。前两个字节可定义用户编码,后两个字节分别是真正的数据及其反码。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)