求高手详细解释下红外遥控程序
时间:10-02
整理:3721RD
点击:
求高手详细解释下红外遥控程序 主要是 “外部中断0中断处理” “红外码值处理” 这两个函数不懂,可否解释下每个语句的意思
/*-----------------------------------------------
名称:红外遥控器键值解码数码管显示
编写:shanxiaodan
日期:2011.5
修改:无
内容:按遥控器上的按键会在数码管上对应显示键值
数据口P0 。P2_0为低位。P2_1为高位。
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
sbit IR=P3^2; //红外接口标志
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0替换
#define wei P2
/*------------------------------------------------
全局变量声明
------------------------------------------------*/
unsigned char code suma[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};// 显示段码值0~F
unsigned char irtime;//红外用全局变量
unsigned char a,b,m,n;
bit irpro_ok,irok;
unsigned char IRcord[4];
unsigned char irdata[33];
/*------------------------------------------------
函数声明
------------------------------------------------*/
void Ir_work(void);
void Ircordpro(void);
void Delay(unsigned int t);
/*------------------------------------------------
定时器0中断处理
------------------------------------------------*/
void tim0_isr (void) interrupt 1 using 1
{
irtime++; //用于计数2个下降沿之间的时间
}
/*------------------------------------------------
外部中断0中断处理
------------------------------------------------*/
void EX0_ISR (void) interrupt 0 //外部中断0服务函数
{
static unsigned char i; //接收红外信号处理
static bit startflag; //是否开始处理标志位
if(startflag)
{
if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
i=0;
irdata=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;
}
/*------------------------------------------------
外部中断0初始化
------------------------------------------------*/
void EX0init(void)
{
IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1; //使能外部中断
EA = 1; //开总中断
}
/*------------------------------------------------
键值处理
------------------------------------------------*/
void zuanhuan(void) //a--b
{
switch(a)
{
case 0x00:b=suma[0]; break;
case 0x01:b=suma[1]; break;
case 0x02:b=suma[2]; break;
case 0x03:b=suma[3]; break;
case 0x04:b=suma[4]; break;
case 0x05:b=suma[5]; break;
case 0x06:b=suma[6]; break;
case 0x07:b=suma[7]; break;
case 0x08:b=suma[8]; break;
case 0x09:b=suma[9]; break;
case 0x0a:b=suma[10]; break;
case 0x0b:b=suma[11]; break;
case 0x0c:b=suma[12]; break;
case 0x0d:b=suma[13]; break;
case 0x0e:b=suma[14]; break;
case 0x0f:b=suma[15]; break;
default:break;
}
}
void Ir_work(void)//红外键值散转程序
{
m=((IRcord[2])&(0xf0))>>4; //高四位
//DataPort=~m;
n=((IRcord[2])&(0x0f)); //低四位
a=n; //低四位转换
zuanhuan();
DataPort=b;
wei = 0xfe;
Delay(100);
a=m; //高四位转换
zuanhuan();
DataPort=b;
wei = 0xfd;
Delay(100);
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|=0x80;
if(j<8)
{
value>>=1;
}
k++;
}
IRcord=value;
value=0;
}
irpro_ok=1;//处理完毕标志位置1
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main(void)
{
EX0init(); //初始化外部中断
TIM0init();//初始化定时器
DataPort=0x00; //取位码 第一位数码管选通,即二进制1111 1110
while(1)//主循环
{
if(irok) //如果接收好了进行红外处理
{
Ircordpro();
irok=0;
}
//if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
{
Ir_work();
}
}
}
void Delay(unsigned int t)
{
while(--t);
}
/*-----------------------------------------------
名称:红外遥控器键值解码数码管显示
编写:shanxiaodan
日期:2011.5
修改:无
内容:按遥控器上的按键会在数码管上对应显示键值
数据口P0 。P2_0为低位。P2_1为高位。
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
sbit IR=P3^2; //红外接口标志
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0替换
#define wei P2
/*------------------------------------------------
全局变量声明
------------------------------------------------*/
unsigned char code suma[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};// 显示段码值0~F
unsigned char irtime;//红外用全局变量
unsigned char a,b,m,n;
bit irpro_ok,irok;
unsigned char IRcord[4];
unsigned char irdata[33];
/*------------------------------------------------
函数声明
------------------------------------------------*/
void Ir_work(void);
void Ircordpro(void);
void Delay(unsigned int t);
/*------------------------------------------------
定时器0中断处理
------------------------------------------------*/
void tim0_isr (void) interrupt 1 using 1
{
irtime++; //用于计数2个下降沿之间的时间
}
/*------------------------------------------------
外部中断0中断处理
------------------------------------------------*/
void EX0_ISR (void) interrupt 0 //外部中断0服务函数
{
static unsigned char i; //接收红外信号处理
static bit startflag; //是否开始处理标志位
if(startflag)
{
if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
i=0;
irdata=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;
}
/*------------------------------------------------
外部中断0初始化
------------------------------------------------*/
void EX0init(void)
{
IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1; //使能外部中断
EA = 1; //开总中断
}
/*------------------------------------------------
键值处理
------------------------------------------------*/
void zuanhuan(void) //a--b
{
switch(a)
{
case 0x00:b=suma[0]; break;
case 0x01:b=suma[1]; break;
case 0x02:b=suma[2]; break;
case 0x03:b=suma[3]; break;
case 0x04:b=suma[4]; break;
case 0x05:b=suma[5]; break;
case 0x06:b=suma[6]; break;
case 0x07:b=suma[7]; break;
case 0x08:b=suma[8]; break;
case 0x09:b=suma[9]; break;
case 0x0a:b=suma[10]; break;
case 0x0b:b=suma[11]; break;
case 0x0c:b=suma[12]; break;
case 0x0d:b=suma[13]; break;
case 0x0e:b=suma[14]; break;
case 0x0f:b=suma[15]; break;
default:break;
}
}
void Ir_work(void)//红外键值散转程序
{
m=((IRcord[2])&(0xf0))>>4; //高四位
//DataPort=~m;
n=((IRcord[2])&(0x0f)); //低四位
a=n; //低四位转换
zuanhuan();
DataPort=b;
wei = 0xfe;
Delay(100);
a=m; //高四位转换
zuanhuan();
DataPort=b;
wei = 0xfd;
Delay(100);
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|=0x80;
if(j<8)
{
value>>=1;
}
k++;
}
IRcord=value;
value=0;
}
irpro_ok=1;//处理完毕标志位置1
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main(void)
{
EX0init(); //初始化外部中断
TIM0init();//初始化定时器
DataPort=0x00; //取位码 第一位数码管选通,即二进制1111 1110
while(1)//主循环
{
if(irok) //如果接收好了进行红外处理
{
Ircordpro();
irok=0;
}
//if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
{
Ir_work();
}
}
}
void Delay(unsigned int t)
{
while(--t);
}
帮你顶下~~~~~~~~~~我也在做红外~~~~~~~~不会~~~~~~
我也在做红外的,遇到好多麻烦的事啊
我也是做这个的,可惜我也不会~~~
学习下
正在学习 。
首先要知道,遥控器接收的原理
第一种:持续9ms高电平,然后持续4.5ms低电平,表示header;
第二种:持续4.5ms高电平,然后持续4.5ms低电平,表示header.
大部分的电视厂家都用这两种方式,有的用一,有的用二,如三星、NEC、松下、海尔、海信等。
这样必须先检测header,然后,持续560us的低电平为固定间隔,如三星规定持续560us高电平为0,持续1.12ms高电平为1.
这样必须使用定时器来固定计算单位,然后在INT0中计数,就可以通过两次下降沿之间的时间间隔来判断是header?还是逻辑1?还是逻辑0?然后把连续的8个bit连在一起判断这个码值是什么。
原理都差不多,可能对于header的时间,逻辑1和逻辑0的时间以及红外码的值等等每个厂家会有不同,这就需要你自己去了解清楚了后从单片机程序上去做调整了。
本人做过三星、NEC、松下、海尔等几个厂家的解码,其实程序基本差不多,只是时序稍作改动而已。
学习<<<<嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻
3、63怎么确定的?