红外遥控总结及程序讲解
时间:10-02
整理:3721RD
点击:
1.以一个9ms低电平,4.5ms的高电平为引导码,后跟32位2进制代码。
2.前16位为用户码及其反码,后16位为操作码及其反码。
3.以脉宽为0.565ms,间隔为0.56ms,周期为1.125ms的组合表示为“0”
4.以脉宽为0.565ms,间隔为1.685ms周期为2.25ms的组合表示为“1”
注:引导码+用户码+用户反码+操作码+操作反码
其中:后四项总共32位
程序思路:
思路一:
主函数:
if( t==34 )
{
/*把所采集的32位数分别分四组每一组8位,
这样很方便的分出用户码、用户反码、操作码、
操作反码,a[0]是用户码,a[1]用户反码,
a[2]是操作码,a[3]是操作反码*/
for(ii=0;ii<4;ii++)
{
for(jj=0;jj<8;jj++)
{
if(aa[dd]<=17)
bb &= 0xfffffffe;
if(aa[dd]>=23)
bb |= 0x00000001;
if(jj<8)
bb=bb<<1;
dd++;
}
tt[ii]=bb;//把32位码分为
bb=0;
}
DigDisplay();
dd=3;//每次循环完之后dd清零防止下一次循环重复
t = 0;
INTF=0;//TMR2与PR2未匹配
INTE=1;//允许外部中断
flag1=0;//标志位清零
TMR2ON = 0;//定时器2关闭
}
中断函数:
/*中断函数*/
void interrupt ISR(void)
{
if(TMR2IE && TMR2IF)//定时器2产生中断
{
TMR2IF = 0;//TMR2与PR2不匹配
num++;//每个周期80us自加1
}
if(INTE && INTF)//外部中断开始
{
PEIE=0;//禁止外设中断开启
t++;//每进1次中断自加1,方便看出几个下降沿
if( t==1 && flag1==0)//当第一次下降沿触发中断就开始计时
{
TMR2ON=1;//定时器使能
}
if( t==2 && 167<num<170 )//是否接受到引导码
{
flag1=1;
}
if( flag1==0 )//过滤连续码
{
num=0;
return;
}
if( flag1==1 && t>2 && t<=34)//成功接受到引导码
{
aa[t]=num;//aa[t]存放每一位的时间,用来判断后面每一位是0还是1
}
num=0;//num清零
INTF=0;
PEIE=1;
}
}
显示函数:
void DigDisplay()
{
switch(tt[2])
{
case(0xA2)://CH-
x=1;break;
case(0x62)://CH
x=2;break;
case(0xE2)://CH+
x=3;break;
case(0x22)://倒退
x=4;break;
case(0x02)://前进
x=5;break;
case(0xC2)://播放
x=6;break;
case(0xE0)://-
x=7;break;
case(0xA8)://+
x=8;break;
case(0x90)://EQ
x=9;break;
case(0x68)://0
x=10;break;
case(0x98)://100+
x=11;break;
case(0xB0)://200+
x=12;break;
case(0x30)://1
x=13;break;
case(0x18)://2
x=14;break;
case(0x7A)://3
x=15;break;
case(0x10)://4
x=16;break;
case(0x38)://5
x=17;break;
case(0x5A)://6
x=18;break;
case(0x42)://7
x=19;break;
case(0x4A)://8
x=20;break;
case(0x52)://9
x=21;break;
}
STB=1;
STB=0;
cmd(0x44);
delay(10);
shiwei=x/10;
gewei=x%10;
cmd(0xC4); //十位
send(table1[shiwei]);
cmd(0xC6); //个位
send(table1[gewei]);
cmd(0xC0);//千
send(0x00);
cmd(0xC2); //百
send(0x00);
cmd(0x8f);
STB=1;
}
程序思路二:
主函数:
void main(void)
{ OSCCON=0x70;//设置时钟为4M
TRISB&=0xf8;//设置RB0,RB1,RB2为输出脚
intr_con(); //总中断初始化
timer1_int();//定时器1初始化
while(1)
{
if(tt == 34)
{
DigDisplay();
//原码判断,显示程序
// INTE=1;//允许外部中断
// flag=0;
tt = 0;
INTF=0;
INTE=1;//允许外部中断
flag=0;
TMR2ON = 0;
}
}
}
中断函数:
void interrupt ISR(void)
{
if(TMR2IE && TMR2IF)//定时器2产生中断
{
TMR2IF = 0;//TMR2与PR2不匹配
num++;
}
if(INTE && INTF)//外部中断开始
{
PEIE = 0;//外设中断清零
tt++; //进一次中断自加一次,能算出进了多少次中断
if(tt == 1 && flag == 0)//第一次下降沿时,tt=1
TMR2ON = 1;//定时器开始计时
if(tt == 2 && num>=160)//第二次下降沿时,如果通过引导码,这继续执行
flag=1;
if(flag == 1 && tt>2 && tt<=34)
{
if(num<=16)//当时间小于1.125毫秒时
aa &= 0xfffffffe;//变量aa最后一位清零
if(num>=26)//如果时间大于2.25毫秒时,程序最后一位置1
aa |= 0x00000001;
if(tt < 33)
aa=aa<<1;
}
if(tt == 34)
{
aa &= 0x0000ffff;//只看操作码,清零前16位
INTE = 0;//不允许外部中断
}
num = 0;
INTF=0;
PEIE = 1;
}
}
显示函数:
void DigDisplay()
{
switch(aa)
{
case(0x0000D12F)://CH-
x=1;break;
case(0x0000B14F)://CH
x=2;break;
case(0x0000F10F)://CH+
x=3;break;
case(0x0000916F)://倒退
x=4;break;
case(0x0000817F)://前进
x=5;break;
case(0x0000E11F)://播放
x=6;break;
case(0x0000F00F)://-
x=7;break;
case(0x0000D42B)://+
x=8;break;
case(0x0000C837)://EQ
x=9;break;
case(0x0000B44B)://0
x=10;break;
case(0x0000CC33)://100+
x=11;break;
case(0x0000D827)://200+
x=12;break;
case(0x00009867)://1
x=13;break;
case(0x00008C73)://2
x=14;break;
case(0x0000BD43)://3
x=15;break;
case(0x00008877)://4
x=16;break;
case(0x00009C63)://5
x=17;break;
case(0x0000AD53)://6
x=18;break;
case(0x0000A15F)://7
x=19;break;
case(0x0000A55B)://8
x=20;break;
case(0x0000A957)://9
x=21;break;
}
STB=1;
STB=0;
cmd(0x44);
delay(10);
shiwei=x/10;
gewei=x%10;
cmd(0xC4); //十位
send(table1[shiwei]);
cmd(0xC6); //个位
send(table1[gewei]);
cmd(0xC0);//千
send(0x00);
cmd(0xC2); //百
send(0x00);
cmd(0x8f);
STB=1;
}
2.前16位为用户码及其反码,后16位为操作码及其反码。
3.以脉宽为0.565ms,间隔为0.56ms,周期为1.125ms的组合表示为“0”
4.以脉宽为0.565ms,间隔为1.685ms周期为2.25ms的组合表示为“1”
注:引导码+用户码+用户反码+操作码+操作反码
其中:后四项总共32位
程序思路:
思路一:
主函数:
if( t==34 )
{
/*把所采集的32位数分别分四组每一组8位,
这样很方便的分出用户码、用户反码、操作码、
操作反码,a[0]是用户码,a[1]用户反码,
a[2]是操作码,a[3]是操作反码*/
for(ii=0;ii<4;ii++)
{
for(jj=0;jj<8;jj++)
{
if(aa[dd]<=17)
bb &= 0xfffffffe;
if(aa[dd]>=23)
bb |= 0x00000001;
if(jj<8)
bb=bb<<1;
dd++;
}
tt[ii]=bb;//把32位码分为
bb=0;
}
DigDisplay();
dd=3;//每次循环完之后dd清零防止下一次循环重复
t = 0;
INTF=0;//TMR2与PR2未匹配
INTE=1;//允许外部中断
flag1=0;//标志位清零
TMR2ON = 0;//定时器2关闭
}
中断函数:
/*中断函数*/
void interrupt ISR(void)
{
if(TMR2IE && TMR2IF)//定时器2产生中断
{
TMR2IF = 0;//TMR2与PR2不匹配
num++;//每个周期80us自加1
}
if(INTE && INTF)//外部中断开始
{
PEIE=0;//禁止外设中断开启
t++;//每进1次中断自加1,方便看出几个下降沿
if( t==1 && flag1==0)//当第一次下降沿触发中断就开始计时
{
TMR2ON=1;//定时器使能
}
if( t==2 && 167<num<170 )//是否接受到引导码
{
flag1=1;
}
if( flag1==0 )//过滤连续码
{
num=0;
return;
}
if( flag1==1 && t>2 && t<=34)//成功接受到引导码
{
aa[t]=num;//aa[t]存放每一位的时间,用来判断后面每一位是0还是1
}
num=0;//num清零
INTF=0;
PEIE=1;
}
}
显示函数:
void DigDisplay()
{
switch(tt[2])
{
case(0xA2)://CH-
x=1;break;
case(0x62)://CH
x=2;break;
case(0xE2)://CH+
x=3;break;
case(0x22)://倒退
x=4;break;
case(0x02)://前进
x=5;break;
case(0xC2)://播放
x=6;break;
case(0xE0)://-
x=7;break;
case(0xA8)://+
x=8;break;
case(0x90)://EQ
x=9;break;
case(0x68)://0
x=10;break;
case(0x98)://100+
x=11;break;
case(0xB0)://200+
x=12;break;
case(0x30)://1
x=13;break;
case(0x18)://2
x=14;break;
case(0x7A)://3
x=15;break;
case(0x10)://4
x=16;break;
case(0x38)://5
x=17;break;
case(0x5A)://6
x=18;break;
case(0x42)://7
x=19;break;
case(0x4A)://8
x=20;break;
case(0x52)://9
x=21;break;
}
STB=1;
STB=0;
cmd(0x44);
delay(10);
shiwei=x/10;
gewei=x%10;
cmd(0xC4); //十位
send(table1[shiwei]);
cmd(0xC6); //个位
send(table1[gewei]);
cmd(0xC0);//千
send(0x00);
cmd(0xC2); //百
send(0x00);
cmd(0x8f);
STB=1;
}
程序思路二:
主函数:
void main(void)
{ OSCCON=0x70;//设置时钟为4M
TRISB&=0xf8;//设置RB0,RB1,RB2为输出脚
intr_con(); //总中断初始化
timer1_int();//定时器1初始化
while(1)
{
if(tt == 34)
{
DigDisplay();
//原码判断,显示程序
// INTE=1;//允许外部中断
// flag=0;
tt = 0;
INTF=0;
INTE=1;//允许外部中断
flag=0;
TMR2ON = 0;
}
}
}
中断函数:
void interrupt ISR(void)
{
if(TMR2IE && TMR2IF)//定时器2产生中断
{
TMR2IF = 0;//TMR2与PR2不匹配
num++;
}
if(INTE && INTF)//外部中断开始
{
PEIE = 0;//外设中断清零
tt++; //进一次中断自加一次,能算出进了多少次中断
if(tt == 1 && flag == 0)//第一次下降沿时,tt=1
TMR2ON = 1;//定时器开始计时
if(tt == 2 && num>=160)//第二次下降沿时,如果通过引导码,这继续执行
flag=1;
if(flag == 1 && tt>2 && tt<=34)
{
if(num<=16)//当时间小于1.125毫秒时
aa &= 0xfffffffe;//变量aa最后一位清零
if(num>=26)//如果时间大于2.25毫秒时,程序最后一位置1
aa |= 0x00000001;
if(tt < 33)
aa=aa<<1;
}
if(tt == 34)
{
aa &= 0x0000ffff;//只看操作码,清零前16位
INTE = 0;//不允许外部中断
}
num = 0;
INTF=0;
PEIE = 1;
}
}
显示函数:
void DigDisplay()
{
switch(aa)
{
case(0x0000D12F)://CH-
x=1;break;
case(0x0000B14F)://CH
x=2;break;
case(0x0000F10F)://CH+
x=3;break;
case(0x0000916F)://倒退
x=4;break;
case(0x0000817F)://前进
x=5;break;
case(0x0000E11F)://播放
x=6;break;
case(0x0000F00F)://-
x=7;break;
case(0x0000D42B)://+
x=8;break;
case(0x0000C837)://EQ
x=9;break;
case(0x0000B44B)://0
x=10;break;
case(0x0000CC33)://100+
x=11;break;
case(0x0000D827)://200+
x=12;break;
case(0x00009867)://1
x=13;break;
case(0x00008C73)://2
x=14;break;
case(0x0000BD43)://3
x=15;break;
case(0x00008877)://4
x=16;break;
case(0x00009C63)://5
x=17;break;
case(0x0000AD53)://6
x=18;break;
case(0x0000A15F)://7
x=19;break;
case(0x0000A55B)://8
x=20;break;
case(0x0000A957)://9
x=21;break;
}
STB=1;
STB=0;
cmd(0x44);
delay(10);
shiwei=x/10;
gewei=x%10;
cmd(0xC4); //十位
send(table1[shiwei]);
cmd(0xC6); //个位
send(table1[gewei]);
cmd(0xC0);//千
send(0x00);
cmd(0xC2); //百
send(0x00);
cmd(0x8f);
STB=1;
}
如果需要PIC原装芯片或者替代芯片的都可以联系我。颜生13430885511(微信同号)/qq2355910801