fj604 34 Posted June 6, 2011 Share Posted June 6, 2011 As promised: a pedestrian crossing simulator - requires a 74HC595 shift register (though I could have done this without it) /* * State Machine demo for MSP430 * Simulates a UK pedestrian crossing with sound * http://en.wikipedia.org/wiki/Pelican_crossing * Requires a 74HC595 shift register and an optional piezo speaker * WDT timer is used to control traffic light phases and beeps * Timer_A0 used as a beep frequency generator */ #include #define TF 23 // Approx. WDT ticks per second // Pin definitions // 74HC595: Data - P1.4, Clock = P1.5, Latch = P1.2 #define PIN_DATA BIT4 #define PIN_CLOCK BIT5 #define PIN_LATCH BIT2 // Pedestrian button on P1.7 #define PIN_BUTTON BIT7 // Piezo speaker on P1.1 #define PIN_SPEAKER BIT1 // LED connections for 74HC595 // T = traffic, P = pedestrian #define T_RED BIT0 #define T_AMBER BIT1 #define T_GREEN BIT2 #define P_RED BIT3 #define P_GREEN BIT4 #define P_WAIT BIT5 #define DEL_P_MIN TF*20 // Minimum time for traffic to stay green #define DEL_T_AMBER TF*2 // Traffic amber phase #define DEL_T_RED TF*2 // Traffic red phase #define DEL_P_GREEN TF*8 // Pedestrian green phase #define DEL_P_GREEN_FLASH TF*4 // Pedestrian green / traffic amber flashing phase #define FREQ 4000 // Beep frequency x 2 #define BEEP_D 3 // Beep duration in ticks #define FLASH_D 10 // Flash duration in ticks #define SMCLK 1000000 // SMCLK frequency static enum { INIT = 0, // Init phase TRAF_GREEN = 1, // Traffic green PED_WAITING = 2, // Pedestrian waiting TRAF_AMBER = 3, // Traffic amber, pedestrian red TRAF_RED = 4, // Traffic red, pedestrian red PED_GREEN = 5, // Traffic red, pedestrian green PED_GREEN_FLASH = 6 // Traffic amber flashing, pedestrian green flashing } state=INIT; unsigned char lights=0, button=0; void main(void) { // Set up timers // WDT used for light phases and timing beeps // Timer_A used for beeps frequency BCSCTL1 = CALBC1_1MHZ; // Set DCO DCOCTL = CALDCO_1MHZ; BCSCTL3 |= LFXT1S_2; // 12khz VLOCLK for ACLK WDTCTL = WDTPW | WDTTMSEL | WDTSSEL | WDTIS1; // Interval timer mode, ACLK, // 12 khz / 512 ~ 23 Hz IE1 |= WDTIE; // Enable WDT interrupt P1SEL |= PIN_SPEAKER; // PIN_SPEAKER to alternative output (CO0) TACCTL0 = OUTMOD_0; // OUT output mode TACCR0 = SMCLK / FREQ; // Set beep frequency TACTL = TASSEL_2 | MC_0; // SMCLK, stop timer // Set up interrupt for button P1OUT &= ~PIN_BUTTON; // Pull button pin down P1REN = PIN_BUTTON; // Enable resistor on button pin P1IES &= ~PIN_BUTTON; // Lo/Hi Edge P1IE |= PIN_BUTTON; // Enable interrupt P1IFG &= ~PIN_BUTTON; // Clear interrupt flag P1DIR |= PIN_DATA | PIN_CLOCK | PIN_LATCH | PIN_SPEAKER; _enable_interrupts(); _low_power_mode_0(); } #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void) { static unsigned int ticks=0, wait=0; unsigned char new_lights = lights; ticks++; if (wait) wait--; switch (state) { case INIT: // First cycle - initialize lights new_lights = T_GREEN | P_RED; // Traffic green, Pedestrian red state = TRAF_GREEN; break; case TRAF_GREEN: if (button) // If button was pressed { button = 0; // Reset button flag new_lights |= P_WAIT; // Pedestrian wait light on state = PED_WAITING; } break; case PED_WAITING: if (wait == 0) // If interval expired { new_lights = T_AMBER | P_RED | P_WAIT; // Traffic amber, Pedestrian red + wait wait = DEL_T_AMBER; // Wait for traffic amber phase state = TRAF_AMBER; } break; case TRAF_AMBER: if (wait == 0) // If interval expired { new_lights = T_RED | P_RED | P_WAIT; wait = DEL_T_RED; state = TRAF_RED; } break; case TRAF_RED: if (wait == 0) { new_lights = T_RED | P_GREEN; wait = DEL_P_GREEN; TACTL |= MC_1; // start timer to sound beeps state = PED_GREEN; } break; case PED_GREEN: if (ticks % BEEP_D == 0) TACCTL0 ^= OUTMOD_4; // Toggle TimerA output mode OUT/Toggle for intermittent beeps if (wait == 0) { wait = DEL_P_GREEN_FLASH; state = PED_GREEN_FLASH; new_lights = T_AMBER | P_GREEN; TACTL &= ~MC_1; // stop timer - disable beeps } break; case PED_GREEN_FLASH: if (ticks % FLASH_D == 0) new_lights ^= T_AMBER | P_GREEN; // Toggle Traffic Amber + Pedestrian Green if (wait == 0) { new_lights = T_GREEN | P_RED; wait = DEL_P_MIN; button = 0; state = TRAF_GREEN; } break; } if (lights != new_lights) // Shift out new lights to 74HC595 { unsigned char b; P1OUT &= ~PIN_LATCH; // latch to low lights = new_lights; for (b=0; b<8; b++) { P1OUT &= ~PIN_CLOCK; // clock to low if (lights & (BIT7 >> ) // if bit is set P1OUT |= PIN_DATA; // data pin to high else P1OUT &= ~PIN_DATA; // data pin to low P1OUT |= PIN_CLOCK; // clock to high } P1OUT |= PIN_LATCH; // latch to high } } // Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { button = 1; P1IFG &= ~PIN_BUTTON; // P1.4 IFG cleared } zeke 1 Quote Link to post Share on other sites
zeke 693 Posted June 6, 2011 Share Posted June 6, 2011 Great work! If you have more examples, please post them up! Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.