140 likes | 376 Views
Trafikklys. Programmet er hentet fra Kapittel 1 Embedded C and the Atmel AVR 2. Ed Barnett, Cox and O’Cull Thomson / Delmar Learning. Trafikklys #define. #include <M 32 .h> #include <delay.h> #define EW_RED_LITE PORTB.0 /* definitions to actual outputs */
E N D
Trafikklys Programmet er hentet fra Kapittel 1 Embedded C and the Atmel AVR 2. Ed Barnett, Cox and O’Cull Thomson / Delmar Learning
Trafikklys #define • #include <M32.h> • #include <delay.h> • #define EW_RED_LITE PORTB.0 /* definitions to actual outputs */ • #define EW_YEL_LITE PORTB.1 /* used to control the lights */ • #define EW_GRN_LITE PORTB.2 • #define NS_RED_LITE PORTB.3 • #define NS_YEL_LITE PORTB.4 • #define NS_GRN_LITE PORTB.5 • #define PED_XING_EW PINA.0 /* pedestrian crossing push button */ • #define PED_XING_NS PINA.1 /* pedestrian crossing push button */ • #define FOUR_WAY_STOP PINA.3 /* switch input for 4-Way Stop */
Trafikklys enum • char time_left// time in seconds spent in each state • int current_state; // current state of the lights • char flash_toggle; // toggle used for FLASHER state • // This enumeration creates a simple way to add states to the machine // by name. Enumerations generate an integer value for each name • // automatically, making the code easier to maintain. • enum { EW_MOVING , EW_WARNING , NS_MOVING , NS_WARNING , FLASHER };
Trafikklys main • void main(void) • { • DDRB = 0xFF; // portb all out • DDRA = 0x00; // porta all in • current_state = NS_WARNING; // initialize to a good starting • // state (as safe as possible) • while(1) • { • delay_ms(1000); // 1 second delay.. this time could • // be used for other needed processes • Do_States(); // call the state machine, it knows • // where it is and what to do next • } • }
Trafikklys EW_MOVING • void Do_States(void) • { • switch(current_state) • { • case EW_MOVING: // east-west has the green!! • EW_GRN_LITE = 1; • NS_GRN_LITE = 0; • NS_RED_LITE = 1; // north-south has the red!! • EW_RED_LITE = 0; • EW_YEL_LITE = 0; • NS_YEL_LITE = 0; • if(PED_XING_EW || FOUR_WAY_STOP) • { // pedestrian wishes to cross, or • // a 4-way stop is required • if(time_left > 10) • time_left = 10; // shorten the time • } • if(time_left != 0) // count down the time • { • --time_left; • return; // return to main • } // time expired, so.. • time_left = 5; // give 5 seconds to WARNING • current_state = EW_WARNING; • // time expired, move • break; // to the next state
Trafikklys EW-WARNING • case EW_WARNING: • EW_GRN_LITE = 0; • NS_GRN_LITE = 0; • NS_RED_LITE = 1; // north-south has the red.. • EW_RED_LITE = 0; • EW_YEL_LITE = 1; // and east-west has the yellow • NS_YEL_LITE = 0; • if(time_left != 0) // count down the time • { • --time_left; • return; // return to main • } // time expired, so.. • if(FOUR_WAY_STOP) // if 4-way requested then start • current_state = FLASHER; // the flasher • else • { // otherwise.. • time_left = 30; // give 30 seconds to MOVING • current_state = NS_MOVING; • } // time expired, move • break; // to the next state
Lyskryss NS_MOVING • case NS_MOVING: • EW_GRN_LITE = 0; • NS_GRN_LITE = 1; • NS_RED_LITE = 0; // north-south has the green!! • EW_RED_LITE = 1; // east-west has the red!! • EW_YEL_LITE = 0; • NS_YEL_LITE = 0; • if(PED_XING_NS || FOUR_WAY_STOP) • { // if a pedestrian wishes to cross, or • // a 4-way stop is required.. • if(time_left > 10) • time_left = 10; // shorten the time • } • if(time_left != 0) // count down the time • { • --time_left; • return; // return to main • } // time expired, so.. • time_left = 5; // give 5 seconds to WARNING • current_state = NS_WARNING; // time expired, move • break; // to the next state
Lyskryss NS_WARNING • case NS_WARNING: • EW_GRN_LITE = 0; • NS_GRN_LITE = 0; • NS_RED_LITE = 0; // north-south has the yellow.. • EW_RED_LITE = 1; • EW_YEL_LITE = 0; // and east-west has the red.. • NS_YEL_LITE = 1; • if(time_left != 0) // count down the time • { • --time_left; • return; // return to main • } // time expired, so.. • if(FOUR_WAY_STOP) // if 4-way requested then start • current_state = FLASHER; // the flasher • else • { // otherwise.. • time_left = 30; // give 30 seconds to MOVING • current_state = EW_MOVING; • } // time expired, move • break; // to the next state
Lyskryss FLASHER • case FLASHER: • EW_GRN_LITE = 0; // all yellow and • NS_GRN_LITE = 0; // green lites off • EW_YEL_LITE = 0; • NS_YEL_LITE = 0; • flash_toggle ^= 1; // toggle LSB.. • if(flash_toggle & 1) • { • NS_RED_LITE = 1; // blink red lights • EW_RED_LITE = 0; • } • else • { • NS_RED_LITE = 0; // alternately • EW_RED_LITE = 1; • } • if(!FOUR_WAY_STOP) // if no longer a 4-way stop • current_state = EW_WARNING; • break; // then return to normal • default: • current_state = NS_WARNING; • break; // set any unknown state to a good one!! • } • }
Lyskryss tilstander Tilstandene er: EW_MOVING øst-vest trafikk EW_WARNING ØV gult NS rødt NS_MOVING nord-syd trafikk NS_WARNING ØV Rødt; NS gult FLASHING Blinker avvekslende rødt i begge retninger
Lyskryss input data • PED_XING_EW fotgjenger ønsker å krysse EW gaten • -- her skal det reageres hvis trafikk går i EW retning • PED_XING_NS fotgjenger ønsker å krysse NS gaten • Her skal det reageres hvis trafikk går i NS retning • FOUR_WAY_STOP for rødblink
Lyskryss tider • Time_left =30 vanlig tid • Time_left telles ned • I main ventes det 1 sekund før tilstandsmaskinen kalles. • Hvis en fotgjenger kommer og tiden er mer enn 10 settes den ned til 10 Ved overgang til WARNING settes Time_left til 5