/****************************************************************************************
* 小玩意 *
* 意义:第一次大量用指针写程序 *
* 作者:大海 ~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_();
}
}
}
/**************************************************************/
|