⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elevator.c

📁 The goal of our final project was to design an efficient elevator simulator that can accept input fr
💻 C
📖 第 1 页 / 共 2 页
字号:
//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 + -