找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4417|回复: 2
打印 上一主题 下一主题
收起左侧

51单片机红外线解码程序

[复制链接]
跳转到指定楼层
楼主
ID:68618 发表于 2014-11-11 18:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/****************************************************************************************
*                                          小玩意                                                       *
*   意义:第一次大量用指针写程序                                                          *                     
*  作者:大海  ~0~                                                                                *
*                                                                                                            *
*****************************************************************************************/
#include <reg51.h>
#include <intrins.h>
typedef unsigned   char uchar;
typedef unsigned   int uint;
#define delayNOP();  {_nop_();_nop_();_nop_();_nop_();};
#define LEDNF(x)    LED1=x&0x01;LED2=(x>>1)&0x01;LED3=(x>>2)&0x01;LED4=(x>>3)&0x01;    //通过宏简单控制
#define ON          ENA=0; ENB=0
#define OFF    ENA=1; ENB=1;
#define NOLE       IN1=0; IN2=0; IN3=0; IN4=0;
struct Good
{
uchar goodx;
uchar goody;
};
void delay(uchar x);  //x*0.14MS
void delay1(uint ms);
void beep();
void LEDRW();
void LEDSRW(uchar,uchar);
void loop(uchar x,uchar y,uchar (*n)[20]);
void too();
void init();
void Jm(uchar);
sbit IRIN = P3^2;         //红外接收器数据线
sbit BEEP = P3^7;         //蜂鸣器驱动线
sbit L1   = P2^0;    //数码管选通
sbit L2   = P2^1;
sbit L3   = P2^2;
sbit L4   = P2^3;
sbit LED1 = P2^4;     //p2口led
sbit LED2 = P2^5;
sbit LED3 = P2^6;
sbit LED4 = P2^7;
sbit ENA  = P3^7;     //too控制
sbit IN1  = P1^7;
sbit IN2  = P1^6;
sbit IN3  = P1^5;
sbit IN4  = P1^4;
sbit ENB  = P1^3;
uchar i;      //时钟
uchar x,y;
uchar *unx,*uny;
uchar LED[10]={0x40,0xf9,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
uchar IRCOM[7];
uchar shuju[20][2]={{9,17},{9,18},{9,19},{9,16},{9,17},{9,18},{9,19},{9,16}};     //动作数据存储
uchar (*p)[2];
struct Good nooxy;      //结构体用作数据传递
struct Good *xy;
/*******************************************************************/
main()
{
init();   
    while(1)
{
  LEDSRW(*unx,*uny);
}
} //end main
/**********************************************************/
void init()
{
    IRIN=1;                    //I/O口初始化
    BEEP=1;
    delay1(10);                 //延时
EA=1;              
EX0=1;
ET0=1;        //允许总中断中断,使能 INT0 外部中断
TH0=(65536-50000)/256;
TL0=(65536-50000)%25;  //装初值,定时器50ms溢出
TCON = 0x01;               //触发方式为脉冲负边沿触发
p=shuju;
unx=&x;
uny=&y;
xy=&nooxy;
}
/************************************************************/
void IR_IN() interrupt 0 using 0
{
  static uchar _i,a;
  unsigned char j,k,N=0;
     EX0 = 0;   
  delay(15);
  if (IRIN==1)
     { EX0 =1;
    return;
   }
                           //确认IR信号出现
  while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。
    {delay(1);}
for (j=0;j<4;j++)         //收集四组数据
{
  for (k=0;k<8;k++)        //每组数据有8位
  {
   while (IRIN)            //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
     {delay(1);}
    while (!IRIN)          //等 IR 变为高电平
     {delay(1);}
     while (IRIN)           //计算IR高电平时长
      {
    delay(1);
    N++;           
    if (N>=30)
  {
  EX0=1;
  return;}                  //0.14ms计数过长自动离开。
      }                        //高电平计数完毕               
     IRCOM[j]=IRCOM[j] >> 1;                  //数据最高位补“0”
     if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}  //数据最高位补“1”
     N=0;
   }//end for k
}//end for j
     if (IRCOM[2]!=~IRCOM[3])
    { EX0=1;
      return; }
  if(IRCOM[2]!=28&&IRCOM[2]!=11)
  {
   if(_i==0)
   {
   loop(*unx,*uny,shuju);
    (*uny==1)?(*uny=0):(*uny=1);
    if(*uny==0)
     (*unx>=19)?(*unx=0):(++*unx);
   ON;
    TR0=0;
  }
  else
  {
   NOLE;
   TR0=0;
   if(IRCOM[2]==18) //前
   {
    IN1=1;
    IN2=0;
    IN3=1;
    IN4=0;   
   }
   if(IRCOM[2]==19)   //后
   {
    IN1=0;
    IN2=1;
    IN3=0;
    IN4=1;   
   }
   if(IRCOM[2]==16)  //左
   {
    IN1=0;
    IN2=1;
    IN3=0;
    IN4=0;   
   }
   if(IRCOM[2]==17)    //右
   {
    IN1=0;
    IN2=0;
    IN3=1;
    IN4=0;
   }
   if(IRCOM[2]==15)
   {
       NOLE;
   }
  }
  }
  else if(IRCOM[2]==28)
  {  
   if(*unx!=0&&uny!=0)
   {
    xy->goodx=*unx;
   xy->goody=*uny;
   }
  *uny=0;
  *unx=0;
  OFF;
  TR0=1;
  }
  else
  {
  _i=~_i;
  }
     beep();
     EX0 = 1;
  for(a=500;a>0;a--)
  LEDRW();
}
/**********************************************************/
void IT_IN() interrupt 1
{
static uchar num;
if(num==100)
{
  num=0;
  i++;
  too();
  LED1=~LED1;
}
else
num++;
}           
/**********************************************************/
void beep()
{
  unsigned char i;
  for (i=0;i<100;i++)
   {
    delay(4);
    BEEP=!BEEP;                 //BEEP取反
   }
  BEEP=1;                      //关闭蜂鸣器
}
/**********************************************************/
void LEDRW()
{
P0=LED[(IRCOM[2]/1000)];   //计算红外的码值并在二极管上显示
L4=0;
   delayNOP();
L4=1;
P0=LED[((IRCOM[2]%1000)/100)];
L3=0;
    delayNOP();
L3=1;
  P0=LED[(((IRCOM[2]%1000)%100)/10)];
L2=0;
delayNOP();
L2=1;
P0=LED[(((IRCOM[2]%1000)%100)%10)];
L1=0;
    delayNOP();
L1=1;
}
/*********************************************************/
void LEDSRW(char x,uchar y)
{
P0=LED[y];   //显示当前数据
L4=0;
   delayNOP();
L4=1;
/* P0=LED[];
L3=0;
    delayNOP();
L3=1;   */
  P0=LED[x/10];
L2=0;
delayNOP();
L2=1;
P0=LED[x%10];
L1=0;
    delayNOP();
L1=1;
}
/**********************************************************/
void loop(uchar x,uchar y,uchar (*n)[2])
{
*(*(n+x)+y)=IRCOM[2];
}
/**********************************************************/
void too()       //行走控制
{
static uchar n;
if(i==*(*(p+n)+1))
{
n++;
i=0;
if(n>=xy->goodx)
{
  n=0;
  beep();
}
}
Jm(n);
}
/**********************************************************/
void Jm(uchar n)
{
if(*(*(p+n)+0)==18) //前
{
  IN1=1;
  IN2=0;
  IN3=1;
  IN4=0;   
}
if(*(*(p+n)+0)==19)   //后
{
  IN1=0;
  IN2=1;
  IN3=0;
  IN4=1;   
}
if(*(*(p+n)+0)==16)  //左
{
  IN1=0;
  IN2=1;
  IN3=0;
  IN4=0;   
}
if(*(*(p+n)+0)==17)    //右
{
  IN1=0;
  IN2=0;
  IN3=1;
  IN4=0;
}
}
/**********************************************************/
/**********************************************************/
void delay(unsigned char x)    //x*0.14MS
{
  unsigned char i;
   while(x--)
  {
    for (i = 0; i<13; i++) {}
  }
}
   
/**********************************************************/
void delay1(int ms)
{
  unsigned char y;
   while(ms--)
  {
    for(y = 0; y<250; y++)
    {
      _nop_();
      _nop_();
      _nop_();
      _nop_();
    }
  }
}
/**************************************************************/

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:66287 发表于 2015-6-2 10:30 | 只看该作者
应该是解TC9012的程序,很有新意!
回复

使用道具 举报

板凳
ID:47634 发表于 2016-1-5 08:39 | 只看该作者
很好很好,学习了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表