⑴ 红外线遥控器解码C语言程序代码 SM0038接受头
//////////////////////////////////////
//晶振频率为6MHz  一个机器周期2us   //
//实现按键地址码、指令码的数码管显示//
//2010-06-01              //
//////////////////////////////////////
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit la=P2^6;
sbit wela=P2^7;
bit overflag,dataover;//开始接收数据,数据处理完毕
uchar timedata;//定时器0溢出次数
uchar chubus[33];//33Byte数据 timedata组成的数组
uchar jieguos[4];//地址码,地址反码,数据码,数据反码;
void initial()//初始化
{
 IT0=1;EX0=1;//负边沿触发
 
  TMOD=0x01;ET0=1;TR0=1;//模式1,十六位定时器
 TH0=0xff;TL0=0x06;//0.5ms溢出
 EA=1; //开总中断
}
void time0() interrupt 1//定时器0中断
{TH0=0xff;TL0=0x06;
 timedata++;
}
void ex0() interrupt 0//外部中断0,接收数据
{
 static bit startflag;//开始接收
 static uchar i;
 
  if(startflag)
 {
  if(timedata<32&&timedata>=16) i=0;
  chubus[i]=timedata;
  timedata=0;
  i++;
  if(i==33){overflag=1;i=0;}
    
 } 
 else
 {
  startflag=1;
  timedata=0;
 }
}
void chulidata()
{
 uchar chubu;//初步数据
 uchar jieguo;//结果数据
 uchar x,y,z=1;
 for(x=0;x<4;x++)//处理四组数据
 {
  for(y=1;y<=8;y++)//处理一组数据8Byte
    {
   chubu=chubus[z];
   jieguo=jieguo>>1; 
   if(chubu>3) jieguo=jieguo|0x80;//大于1.5mS为1
   z++;
  }
 jieguos[x]=jieguo;
 jieguo=0;
 }
 dataover=1;
 
}
void delay(uint z)
{
 uint x ,y;
 for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}
void display()
{
  uchar gao,gao1;
 uchar di,di1;
 uchar code table[]={
 0x3f,0x06,0x5b,0x4f,
 0x66,0x6d,0x7d,0x07,
 0x7f,0x6f,0x77,0x7c,
 0x39,0x5e,0x79,0x71};
 gao1=table[jieguos[0]/16];
 di1=table[jieguos[0]%16];
 gao=table[jieguos[2]/16];
 di=table[jieguos[2]%16];
  la=1;
  P0=gao1;
  la=0;
  P0=0xff; 
  wela=1;
  P0=0x7e;
  wela=0;
  delay(2);
la=1;
  P0=di1;
  la=0; 
  P0=0xff;
  wela=1;
  P0=0xfd;
  wela=0;
  delay(2);//地址码
  la=1;
  P0=gao;
  la=0;
  P0=0xff; 
  wela=1;
  P0=0x77;
  wela=0;
  delay(2);
la=1;
  P0=di;
  la=0; 
  P0=0xff;
  wela=1;
  P0=0x6f;
  wela=0;
  delay(2);//指令码
} 
void main()
{
  initial();//初始化
 while(1)
 {
  
  if(overflag)//数据接收完毕
  {
   chulidata();//处理数据,完成标志dataover
   overflag=0; 
  } 
  if(dataover)
  {
   display();//数码管显示
   }
  }
}
⑵ 基于51单片机红外遥控代码(C语言)
以下文件是51单片机实现遥控解码,通过数码管显示键码的程序,P0口驱动数码管段选,p2.6和p2.7为数码管位选,接收头连到P3.2口。此程序以通过验证,可以直接编译使用,另外还有一个继电器和蜂鸣器的控制,不用可以屏蔽掉。
;********************************************************************************
;*  描述:                                                                       *
;*           遥控键值读取器                                                *
;*         数码管显示, P0口为数码管的数据口                                     *
;*                                                                              *
;********************************************************************************
;遥控键值解码-数码管显示                *
;********************************************************************************/
#include <reg51.h>
#include <intrins.h>
void IR_SHOW();
void delay(unsigned char x);//x*0.14MS
void delay1(unsigned char ms);
void beep();
sbit IRIN = P3^2;
sbit BEEP = P3^7;
sbit RELAY= P1^3;
sbit GEWEI= P2^7;
sbit SHIWEI= P2^6;
unsigned char IRCOM[8];
unsigned char code table[16] = 
                    {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
main()
{
 IE = 0x81;    //允许总中断中断,使能 INT0 外部中断
 TCON = 0x1;   //触发方式为脉冲负边沿触发
 delay(1);
         IRIN=1;
      BEEP=1;
   RELAY=1;
   for(;;)
   {
    IR_SHOW();
   }
} //end main
void IR_IN() interrupt 0 using 0
{
 unsigned char i,j,k,N=0;
  EA = 0;
I1:
  for (i=0;i<4;i++)
   {
    if (IRIN==0) break;
 if (i==3) {EA =1;return;}
   }
  delay(20);
    if (IRIN==1) goto I1;  //确认IR信号出现
  while (!IRIN)            //等 IR 变为高电平
    {delay(1);}
 for (j=0;j<4;j++)
 { 
  for (k=0;k<8;k++)
  {
   while (IRIN)            //等 IR 变为低电平
     {delay(1);}
    while (!IRIN)          //等 IR 变为高电平
     {delay(1);}
     while (IRIN)           //计算IR高电平时长
      {
    delay(1);
    N++;           
    if (N>=30) {EA=1;return;}
   }
     IRCOM[j]=IRCOM[j] >> 1;
     if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}
     N=0;
  }//end for k
 }//end for j
   
   if (IRCOM[2]!=~IRCOM[3]) {EA=1;return;}
   IRCOM[5]=IRCOM[2] & 0x0F;
   IRCOM[6]=IRCOM[2] & 0xF0;
   IRCOM[6]=IRCOM[6] >> 4;
   beep();
   EA = 1;
  
}
void IR_SHOW()
 {
  P0 = table[IRCOM[5]];      
  GEWEI = 0;
  SHIWEI = 1;
  delay1(4);
  P0 = table[IRCOM[6]];      
  SHIWEI = 0;
  GEWEI = 1;
  delay1(4);
 }
void beep()
{
  unsigned char i;
  for (i=0;i<100;i++)
   {
   delay(5);
   BEEP=!BEEP;
   } 
  BEEP=1;
}
void delay(unsigned char x)//x*0.14MS
{
 unsigned char i;
  while(x--)
 {
  for (i = 0; i<13; i++) {}
 }
}
void delay1(unsigned char ms)
{
 unsigned char i;
  while(ms--)
 {
  for(i = 0; i<120; i++)
  {
   _nop_();
   _nop_();
   _nop_();
   _nop_();
  }
 }
}
⑶ 高分请教高人,红外遥控解码程序C语言,要求每一行都解释为什么什么作用。非常感谢!!先给100分,好再加
#include <reg52.h>   //特殊寄存器头文件  
#define c(x) (x*110592/120000) //是晶振值,为计数器计一下所需要的微秒数,120000为12M,110592为11.0592M
sbit Ir_Pin=P3^3;   //位声明,把P3.3/外部中断1的状态读到Ir_Pin中
unsigned char code Led_Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,
0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};      //共阳极数码显示码0-F.
unsigned char code Led_Sel[]={0xe,0xd,0xb,0x7};     //位选编码
unsigned char Led_Buf[4];     //显示缓冲区
char Led_Index;              //位选信号定义        
unsigned char Ir_Buf[4];     //用于保存解码结果
//==============================================================
//数码管扫描
timer0() interrupt 1 using 1  //定时器中断零程序
{
TH0=(65536-1000)/256; 
TL0=(65536-1000)%256;        //定时器0设定约1000us中断一次,用于数码管扫描
P0=0xff;                     //数码管初始显示零
P2=Led_Sel[Led_Index];       //位选
P0=Led_Tab[Led_Buf[Led_Index]];   //段选
if(++Led_Index>3) Led_Index=0;    //四个扫描完了,到第一个数码管
}
//==============================================================
unsigned int Ir_Get_Low()    //脉冲为低电平的时间
{
TL1=0;
TH1=0;                    //为定时器1赋初值
TR1=1;                   //开启定时器1
while(!Ir_Pin && (TH1&0x80)==0);  //判断,如果P3.3口为低电平则执行TR1=0               
TR1=0;                //关闭定时器1          
return TH1*256+TL1;         //返回TH1*256+TL1的值
}
//=============================================================
unsigned int Ir_Get_High()    //脉冲高电平时间
{
TL1=0;
TH1=0;                      //为定时器1赋初值
TR1=1;                      //开启定时器1
while(Ir_Pin && (TH1&0x80)==0);    //判断,如果P3.3口为低电平则执行TR1=0
TR1=0;                     //关闭定时器1
return TH1*256+TL1;               //返回TH1*256+TL1的值
}
//==============================================================
main()
{
unsigned int temp;
char i,j;
Led_Index=1;
TMOD=0x11;
TL0=(65536-1000)%256;
TH0=(65536-1000)/256;    //定时器0设定约1000us中断一次,用于数码管扫描
EA=1;                    //开总中断
ET0=1;                   //定时计数器0的开放控制位
TR0=1;                   //定时器0的运行控制位
Led_Buf[0]=0;
Led_Buf[1]=0;
Led_Buf[2]=0;
Led_Buf[3]=0;            //显示区设成0
do{
restart:
while(Ir_Pin);                  //判断P3.3口
temp=Ir_Get_Low();              //取脉冲为低电平的时间 
if(temp<c(8500) || temp>c(9500)) continue;   //引导脉冲低电平9000
temp=Ir_Get_High();             //取脉冲高电平时间
if(temp<c(4000) || temp>c(5000)) continue;    //引导脉冲高电平4500
for(i=0;i<4;i++)                //4个字节
    for(j=0;j<8;j++)            //每个字节8位
    {
 temp=Ir_Get_Low();
 if(temp<c(200) || temp>c(800)) goto restart;  //根据编码格式,低电平小于0.2ms大于0.8ms视为无效电平,重新检测
 temp=Ir_Get_High();
 if(temp<c(200) || temp>c(2000)) goto restart; //根据编码格式,低电平小于0.2ms大于2ms视为无效电平,重新检测
 Ir_Buf[i]>>=1;                            //把Ir_Buf[i]右移一位,然后赋值给Ir_Buf[i]
 if(temp>c(1120)) Ir_Buf[i]|=0x80;         //根据编码格式,如果电平大于1.12ms,则把0x80赋值给Ir_Buf[i]
} 
Led_Buf[0]=Ir_Buf[2]&0xf;
Led_Buf[1]=(Ir_Buf[2]/16)&0xf;
Led_Buf[2]=Ir_Buf[3]&0xf;
Led_Buf[3]=(Ir_Buf[3]/16)&0xf; //显示结果
}while(1);
}
⑷ 红外遥控器同一个键控制一个I/O口,第一次开,第二次关,比如P0^1开启关闭C语言代码高手请进。
第一,收到你要的按键后,是取反某个位,而不是赋值。如P10=~P10;(建议取个名字)
第二,为了避免一次按键,多次触发,对按键值操作后,需要进行清除处理;(即赋值成无效的按键值),如 IrValue[2]=0xff;(如果没有按键是 0xff的话)
第三,最正确的做法是,收到遥控后,额外提供一个标志位(如 IR_UpdateFlag),程序识别标志位后,进行按键选择,处理完按键后,清除标志位。这样可以避免程序重复、多余执行按键选择(虽然是无效的按键,但那也是选择),可以提高系统执行效率!
