You are on page 1of 3

PARKED_1 = 0x11, }

#include "htc.h" PARKED_2 = 0x12, }


PARKED_3 = 0x13,
PARKED_4 = 0x14,
// the push-buttons that request the elevator target void
floor UP_TO_1 = 0x21, main(void)
// we map BUTTON_0=RA4 etc. to keep the UP_TO_2 = 0x22, {
schematics simple.. UP_TO_3 = 0x23,
// UP_TO_4 = 0x24, GIE = 0; // disable interrupts
#define BUTTON_0 RA4 TRISA = 0x1f; // all inputs
#define BUTTON_1 RA3 DOWN_TO_3 = 0x43, TRISB = 0x1f; // RB7..RB5 outputs, RB4..RB0
#define BUTTON_2 RA2 DOWN_TO_2 = 0x42, inputs
#define BUTTON_3 RA1 DOWN_TO_1 = 0x41,
#define BUTTON_4 RA0 DOWN_TO_0 = 0x40, for( ;; ) {
// the sensors that indicate which floor the elevator
car UNKNOWN = 0xff, switch( state ) {
// has reached. Again we map 0-4 1-3 etc. to avoid }; case PARKED_0:
signal if (BUTTON_1 | BUTTON_2 |
// crossing in the schematics. enum motor_state { BUTTON_3 | BUTTON_4) {
// STOP = 0x00, state = UP_TO_1;
#define SENSOR_0 RB4 MOVE_UP = 0xc0, motor = MOVE_UP;
#define SENSOR_1 RB3 MOVE_DOWN = 0x80, }
#define SENSOR_2 RB2 }; else {
#define SENSOR_3 RB1 motor = STOP;
#define SENSOR_4 RB0 }
// global variables for state-machine state and motor break;
// two output ports used to control the elevator motor control
// (on/off) and motor direction (up/ndown). //
unsigned char state = PARKED_0; case PARKED_1:
// if (BUTTON_2 | BUTTON_3 | BUTTON_4) {
#define MOTOR_ON RB6 unsigned char motor = STOP;
state = UP_TO_2;
#define UP_NDOWN RB7 motor = MOVE_UP;
}
// the elevator states: parked means waiting (at floor else if (BUTTON_0) {
< i >), // inidicate an error by lighting the LED on port B.5
// (note that RB5 is also used to reset the SR- state = DOWN_TO_0;
// up_to and down_to imply moving to the motor = MOVE_DOWN;
corresponding floor. flipflops,
// but the short strobes should not be visible on a real }
// We force an encoding that allows you to watch the else {
state LED.
void motor = STOP;
// during the simulation (upper nibble=1/2/4: }
parked/up/down), error(void)
{ break;
// lower nibble=floor index, 0xff=error
// motor = STOP;
for(;;) { case PARKED_2:
enum elevator_state { if (BUTTON_3 | BUTTON_4) {
PARKED_0 = 0x10, RB5 = 1;
state = UP_TO_3;
motor = MOVE_UP; state = UP_TO_2; else {
} motor = MOVE_UP; motor = MOVE_UP;
else if (BUTTON_0 | BUTTON_1) { } }
state = DOWN_TO_1; else if (SENSOR_1) { break;
motor = MOVE_DOWN; state = PARKED_1;
} motor = STOP; case DOWN_TO_3:
else { } if (BUTTON_2 | BUTTON_1 |
motor = STOP; else { BUTTON_0) {
} motor = MOVE_UP; state = DOWN_TO_2;
break; } motor = MOVE_DOWN;
break; }
case PARKED_3: else if (SENSOR_3) {
if (BUTTON_4) { case UP_TO_2: state = PARKED_3;
state = UP_TO_4; if (BUTTON_3 | BUTTON_4) { motor = STOP;
motor = MOVE_UP; state = UP_TO_3; }
} motor = MOVE_UP; else {
else if (BUTTON_0 | BUTTON_1 | } motor = MOVE_DOWN;
BUTTON_2 ) { else if (SENSOR_2) { }
state = DOWN_TO_2; state = PARKED_2; break;
motor = MOVE_DOWN; motor = STOP;
} } case DOWN_TO_2:
else { else { if (BUTTON_1 | BUTTON_0) {
motor = STOP; motor = MOVE_UP; state = DOWN_TO_1;
} } motor = MOVE_DOWN;
break; break; }
else if (SENSOR_2) {
case PARKED_4: case UP_TO_3: state = PARKED_2;
if (BUTTON_0 | BUTTON_1 | BUTTON_2 | if (BUTTON_4) { motor = STOP;
BUTTON_3) { state = UP_TO_4; }
state = DOWN_TO_3; motor = MOVE_UP; else {
motor = MOVE_DOWN; } motor = MOVE_DOWN;
} else if (SENSOR_3) { }
else { state = PARKED_3; break;
motor = STOP; motor = STOP;
} } case DOWN_TO_1:
break; else { if (BUTTON_0) {
motor = MOVE_UP; state = DOWN_TO_0;
} motor = MOVE_DOWN;
case UP_TO_1: break;
if (SENSOR_2 | SENSOR_3 | }
SENSOR_4) { else if (SENSOR_1) {
case UP_TO_4: state = PARKED_1;
error(); if (SENSOR_4) {
} motor = STOP;
state = PARKED_4; }
if (BUTTON_2 | BUTTON_3 | motor = STOP;
BUTTON_4) { else {
}
motor = MOVE_DOWN; // finally, reset the watchdog timer.
} CLRWDT();
break; }

case DOWN_TO_0: }
if (SENSOR_0) {
state = PARKED_0; // we don't use interrupts in this program.
motor = STOP; //
} static void interrupt
else { isr(void)
motor = MOVE_DOWN; {
} if(T0IF) { // timer interrupt
break; error();
}
default: else if(INTF) {
error(); error();
}
} // end switch(state) }

// a variant of the elevator circuit uses


extra SR-flipflops
// to make sure that the (short) pulses
generated by the
// floor-sensors are picked up by this
program loop.
// To reset the flipflops, we generate a
short-pulse on RB5
// now. We can do this here, because we
have just handled
// one iteration of the state-machine
state update.
// The single pulse is too short to make
the error LED
// light up visibly.
RB5 = 1;
RB5 = 0;

// now activate the motor corresponding


to the current
// state. We just need RB7 and RB6, but
the other bits
// are inputs anyway.
PORTB = motor;

You might also like