#include <AT89X52.h>
sbit door_light=P2^5; // 门灯
sbit up_light=P2^6; // 上行显示灯
sbit down_light=P2^7; // 下行显示灯
sbit LED_D=P2^0; // 接 LED数码管
sbit LED_C=P2^1;
sbit LED_B=P2^2;
sbit LED_A=P2^3;
unsigned int direct; // 全局变量 direct.floor.currentfloor
unsigned int floor;
unsigned int currentfloor;
// 电机驱动函数定义
sbit MA=P1^0;
sbit MB=P1^1;
sbit MC=P1^2;
sbit MD=P1^3;
static unsigned int count; //计数
static int step_index; //步进索引数,值为0-7
static bit turn; //步进电机转动方向
static int speedlevel; //步进电机转速参数,数值越大速度越慢,最小值为1,速度最快
static int spcount; //步进电机转速参数计数
unsigned int c=150; // 定时器时间常数 T=c*16+24 us
void delay(unsigned int N)
{
int i;
for(i=0;i<N;i++);
}
void system_init(void )
{
up_light=1;
down_light=1;
door_light=1;
P0=0xff;
currentfloor=floor=direct=0;
step_index = 0;
spcount = 0;
MA=MB=MC=MD=1;
TMOD = 0x11; //设定时器0和1为16位模式1
ET0 = 1; //定时器0中断允许
TR0=0; //定时器0计数停止
TH0 = (65536-c)/256;
TL0 = (65536-c)%256;
turn = 1;
IT0=1; //选择INT0为脉冲触发方式
IT1=1; //选择INT1为脉冲触发方式
EX0=1; //外部中断0允许
EX1=1; //外部中断1允许
EA=1; //系统中断允许
speedlevel=1;
}
void led(unsigned int n)
{
switch(n)
{
case 0:LED_D=0;LED_C=0;LED_B=0;LED_A=1;break;
case 1:LED_D=0;LED_C=0;LED_B=1;LED_A=0;break;
case 2:LED_D=0;LED_C=0;LED_B=1;LED_A=1;break;
case 3:LED_D=0;LED_C=1;LED_B=0;LED_A=0;break;
}
}
void gorun() //步进电机驱动主函数
{
switch(step_index)
{
case 0: //A
MA = 0;
MB = 1;
MC = 1;
MD = 1;
break;
case 1: //AB
MA = 0;
MB = 0;
MC = 1;
MD = 1;
break;
case 2: //B
MA = 1;
MB = 0;
MC = 1;
MD = 1;
break;
case 3: //BC
MA = 1;
MB = 0;
MC = 0;
MD = 1;
break;
case 4: //C
MA = 1;
MB = 1;
MC = 0;
MD = 1;
break;
case 5: //CD
MA = 1;
MB = 1;
MC = 0;
MD = 0;
break;
case 6: //D
MA = 1;
MB = 1;
MC = 1;
MD = 0;
break;
case 7: //DA
MA = 0;
MB = 1;
MC = 1;
MD = 0;
break;
}
if(turn==0)
{
step_index++;
if(step_index>7)
step_index=0;
}
if(turn==1)
{
step_index--;
if(step_index<0)
step_index=7;
}
}
void INT0_interrupt() interrupt 0 // 红外线中断
{
if(direct==0)
currentfloor=currentfloor;
if(direct==1)
currentfloor=currentfloor+1;
if(direct==2)
currentfloor=currentfloor-1;
led(currentfloor);
if(direct!=0)//由while改过来的
{
if(currentfloor==floor)
{
ET0=EX0=0; // 关调用电梯的中断
TR0=0; // 定时器0计时停止,便于不调用gorun
// up_light=1;
// down_light=1;
door_light=0; // 门灯亮
delay(65535);
delay(65535);
delay(65535);
door_light=1;
ET0=EX0=1;
TR0=1;
}
// TR0 = 1; //开始计数
speedlevel = 1;
}
}
void timer0_int(void) interrupt 1 //定时器0中断处理
{
TH0 = (65536-c)/256;
TL0 = (65536-c)%256;
count++;
spcount--;
/* if(currentfloor==floor||direct==0)
{
TR0 = 0; // 关计数器计数,便于不调用gorun
MA=MB=MC=MD=1;
return;
}*/
if(direct==0)
{
up_light=1;
down_light=1;
}
if(direct==1)
{
turn=0;
up_light=0;
down_light=1;
}
if(direct==2)
{
turn=1;
up_light=1;
down_light=0;
}
if(spcount<=0)
{
spcount = speedlevel;
gorun();
}
}
void INT1_interrupt() interrupt 2 // 读乙单片机发来的中断
{
unsigned char direct_floor,x,y; //高四位 direct ,低四位 floor
P0=0xff;
direct_floor=P0;
x=direct_floor&0xf0;
y=direct_floor&0x0f;
switch(x)
{
case 0x00:direct=0;break;
case 0x10:direct=1;break;
case 0x20:direct=2;break;
}
switch(y)
{
case 0x00:floor=0;break;
case 0x01:floor=1;break;
case 0x02:floor=2;break;
case 0x03:floor=3;break;
}
}
void main(void)
{
system_init();
direct=floor=1;
TR0=1;
}