📄 elevator.c
字号:
//Andrew Costello (aoc6)
//Dylan Hughes (dah64)
//ECE 476 Final Project
//4/30/2007
#include <Mega32.h>
#include <stdio.h> // sprintf
#include <stdlib.h> // malloc
#include <delay.h>
#include <Math.h>
#define begin {
#define end }
#define floorsize 38
#define pause 75
#define trivial 0 //one elevator does everything
#define simple 1 //all elevators chase each other
#define normal 2 //optimal elevator operation
#define sabbath 3 //one or all elevators dedicated to going up/down, stopping on all floors
#define floors 4
int mode = normal;
typedef struct
{
int floor;//current floor
int traveldir;//current direction of travel -1 = down, 1 = up;
char turnaround;//floor where the elevator should switch directions
int count;//used for interrupt to determine how far to send elevator
char motorstate;//state of step motor
char button[floors];//buttons in elevator that have been pressed
char uprequests[floors];//requests from people outside the elevator to go up
char oldbutton[floors];
char downrequests[floors];//requests from people outside the elevator to go down
int paused;//number of interrupts to pause elevator for
char on;//whether elevator should move 1 stepper cycle
char id;//elevator #
} Elevator;
typedef Elevator *elevator_t;//elevator_t is a pointer to type Elevator
void algorithm1(elevator_t);
void addRequests(void);
void oneStep(elevator_t);
void algorithm2(void);
void algorithm3(elevator_t);
void poll2(void);
elevator_t elevator1, elevator2, elevator3;
char button[floors+floors]; //hidden outside button state
char button2[floors+floors]; //displayed outside button state
char old[floors+floors];
int waiting = 0;
int time = 0;
int ready1 = 0;
int ready2 = 0;
int serialFlag = 0;
char buffer[10];
int bufferindex = 0;
interrupt [TIM0_COMP] void timer0_compare(void)
{
time = (time + 1)%50;
if(UCSRA.7)
serialFlag = 1;
if(mode != sabbath)
poll2();
if(time)
{
return;
}
if (waiting)
{
if(elevator1->on)
{
elevator1->motorstate = (elevator1->motorstate + elevator1->traveldir+4)%4;
if(elevator1->motorstate ==0)
PORTA = 0x0a;
else if(elevator1->motorstate==1)
PORTA = 0x06;
else if(elevator1->motorstate==2)
PORTA = 0x05;
else
PORTA = 0x09;
elevator1->count++;
}
elevator1->on = 0;
if(elevator2->on)
{
elevator2->motorstate = (elevator2->motorstate + elevator2->traveldir+4)%4;
if(elevator2->motorstate ==0)
PORTB = 0x0a;
else if(elevator2->motorstate==1)
PORTB = 0x06;
else if(elevator2->motorstate==2)
PORTB = 0x05;
else
PORTB = 0x09;
elevator2->count++;
}
elevator2->on = 0;
if(elevator3->on)
{
elevator3->motorstate = (elevator3->motorstate + elevator3->traveldir+4)%4;
if(elevator3->motorstate ==0)
PORTC = 0x0a;
else if(elevator3->motorstate==1)
PORTC = 0x06;
else if(elevator3->motorstate==2)
PORTC = 0x05;
else
PORTC = 0x09;
elevator3->count++;
}
elevator3->on = 0;
waiting = 0;
}
}
//poll the buttons
void poll()
{
if(~PINA & 0x10)//Internal elevator buttons
elevator1->button[0] = 1;
if(~PINA & 0x20)
elevator1->button[1] = 1;
if(~PINA & 0x40)
elevator1->button[2] = 1;
if(~PINA & 0x80)
elevator1->button[3] = 1;
if(~PINB & 0x10)//Internal elevator buttons
elevator2->button[0] = 1;
if(~PINB & 0x20)
elevator2->button[1] = 1;
if(~PINB & 0x40)
elevator2->button[2] = 1;
if(~PINB & 0x80)
elevator2->button[3] = 1;
if(~PINC & 0x10)//Internal elevator buttons
elevator3->button[0] = 1;
if(~PINC & 0x20)
elevator3->button[1] = 1;
if(~PINC & 0x40)
elevator3->button[2] = 1;
if(~PINC & 0x80)
elevator3->button[3] = 1;
if(~PIND & 0x04 && !button2[1]){//Floor 0 up button
button[1] = 1;
button2[1] = 1;
}
if(~PIND & 0x08 && !button2[2]){//Floor 1 down button
button[2] = 1;
button2[2] = 1;
}
if(~PIND & 0x10 && !button2[3]){//Floor 1 up button
button[3] = 1;
button2[3] = 1;
}
if(~PIND & 0x20 && !button2[4]){//Floor 2 down button
button[4] = 1;
button2[4] = 1;
}
if(~PIND & 0x40 && !button2[5]){//Floor 2 up button
button[5] = 1;
button2[5] = 1;
}
if(~PIND & 0x80 && !button2[6]){//Floor 3 down button
button[6] = 1;
button2[6] = 1;
}
}
void initialize(void);
void sendbuttons(elevator_t elevator)
{
int i;
for (i=0;i<floors;i++)
{
if(elevator->button[i] != elevator->oldbutton[i])
{
printf("inb%i%02i%i\r\n",elevator->id,i,elevator->button[i]);
elevator->oldbutton[i] = elevator->button[i];
}
}
}
void main(void)
{
int i;
initialize();
while(1)
{
if(mode != sabbath)
poll();//poll the buttons
for (i=1;i<floors + floors-1;i++)
{
if(button2[i]!=old[i])
printf("outb%02i%i\r\n",i,button2[i]);
old[i] = button2[i];
}
sendbuttons(elevator1);
sendbuttons(elevator2);
sendbuttons(elevator3);
addRequests();//add requests to elevators
oneStep(elevator1);//control elevators
oneStep(elevator2);
oneStep(elevator3);
waiting = 1;
while(waiting){}
}
}
//**********************************************************
//Set it all up
void initialize(void)
{
int i;
//set up the ports
DDRA=0x0f; // lower 4 bits of PORT A are output, upper 4 are input
DDRB=0x0f; // lower 4 bits of PORT B are output, upper 4 are input
DDRC=0x0f; // lower 4 bits of PORT C are output, upper 4 are input
DDRD=0x03; // PORT D is an input
PORTA = 0x0a; //turn on stepper motor
PORTB = 0x0a; //turn on stepper motor
PORTC = 0x0a; //turn on stepper motor
UCSRB = 0x18;
UBRRL = 103;
printf("init\r\n");
elevator1 = (elevator_t)malloc(sizeof(Elevator));
elevator2 = (elevator_t)malloc(sizeof(Elevator));
elevator3 = (elevator_t)malloc(sizeof(Elevator));
elevator1->floor = 0;
elevator1->traveldir = 1;
elevator1->turnaround = -1;
elevator1->count = 0;
elevator1->motorstate = 0;
elevator1->on = 0;
elevator1->paused = 0;
elevator1->id = 1;
for(i = 0; i<floors; i++)
{
elevator1->button[i] = 0;
elevator1->uprequests[i] = 0;
elevator1->downrequests[i] = 0;
elevator1->oldbutton[i] = 0;
elevator2->button[i] = 0;
elevator2->uprequests[i] = 0;
elevator2->downrequests[i] = 0;
elevator2->oldbutton[i] = 0;
elevator3->button[i] = 0;
elevator3->uprequests[i] = 0;
elevator3->downrequests[i] = 0;
elevator3->oldbutton[i] = 0;
}
elevator2->floor = 0;
elevator2->traveldir = 1;
elevator2->turnaround = -1;
elevator2->count = 0;
elevator2->motorstate = 0;
elevator2->on = 0;
elevator2->paused = 0;
elevator2->id = 2;
elevator3->floor = 0;
elevator3->traveldir = 1;
elevator3->turnaround = -1;
elevator3->count = 0;
elevator3->motorstate = 0;
elevator3->on = 0;
elevator3->paused = 0;
elevator3->id = 3;
for(i = 0; i<floors+floors;i++)
{
button[i] = 0;
button2[i] = 0;
old[i] = 0;
}
//turn on interrupt 0 every 30ms? (controls elevator speed)
TIMSK=2; //turn on timer 0 cmp match ISR
OCR0 = 250; //set the compare re to 250 time ticks
//prescalar to 64 and turn on clear-on-match
TCCR0=0b00001011;
//crank up the ISRs
#asm
sei
#endasm
}
//decides where the elevator should turn around
int checkdirection(elevator_t elevator)
{
int i;
int flag = 0;
for(i=elevator->floor;i<=floors-1 && i>=0;i = i + elevator->traveldir) //scan for requests in direction of travel
{
//there are pick up requests to go the same way in the direction of travel
if((elevator->traveldir == 1 && elevator->uprequests[i]) || (elevator->traveldir == -1 && elevator->downrequests[i]))
{
//don't change direction, set turnaround floor to top/bottom floor
if(elevator->traveldir == 1)
{
elevator->turnaround = floors-1;
}
else
{
elevator->turnaround = 0;
}
flag = 1;
//elevator->on = 1;
return 1;
}
//no pick up requests to go the same way, but drop off reqests in the direction of travel or pick up requests to go opposite way
else if((elevator->traveldir == 1 && elevator->downrequests[i]) || (elevator->traveldir == -1 && elevator->uprequests[i]) || (elevator->button[i]))
{
//don't change direction yet, set the turnaround floor ((CHECK THIS LOGIC))
if(elevator->button[i])
elevator->turnaround = i; //highest floor with a drop off request
if(elevator->traveldir == 1 && elevator->downrequests[i])
elevator->turnaround = i; //highest floor that wants to go down
else if(elevator->traveldir == -1 && elevator->uprequests[i])
elevator->turnaround = i; //lowest floor that wants to go up
flag = 1;
if(elevator->floor != elevator->turnaround) //don't move if you need to turn on this floor
{
//elevator->on = 1;
return 1;
}
}
}
//no more requests at all in direction of travel, check for other requests
if(!flag)
{
for(i=elevator->floor-elevator->traveldir; i<=floors-1 && i>=0; i = i - elevator->traveldir)
{
if(elevator->button[i] || elevator->uprequests[i] || elevator->downrequests[i]) //request on a floor above/below
{
elevator->turnaround = elevator->floor; //turn around now!
return 0;
}
}
//don't change direction if we get out of that loop
if(elevator->traveldir == 1)
{
elevator->turnaround = floors-1;
}
else
{
elevator->turnaround = 0;
}
}
return 0;
}
//Function looks though current button requests and determines where to send elevators
//Each elevator follows SCAN algorithm on requests it is given
//Ideally, function resets button variables when it assigns requests to elevators.
//This function is responsible to only send elevator to floor if heading in correct direction
//(in terms of picking up passengers, dropping them off doesn't matter)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -