We began our design by making a state transition diagram for the control logic. We specified the six
operating states and the transitions between them. We used a branch table to implement the state machine. The functionality of each state is specified in the high-level design section. We also created jump routines that go to code segments which specify the state transitions.
In order to save our operating states and user configurations (in case of power loss), we used the EEPROM read/write capabilities of the AT90S4414. We created an EERead and EEWrite subroutine to handle read/write operations to the EEPROM. The desired EEPROM address is written to a register named EEaddr. For a write operation, the desired information is placed in a register named EEdwr. Then the program jumps to the EEWrite subroutine. Once inside the subroutine, the address is loaded, the master write-enable bit is set, and then the write-enable is set. After the operation is completed, the write-enable flag is reset by hardware. We poll this bit in order to preserve write atomicity. In the case of the read operation, we poll the write-enable flag, load the address, and set the read-enable bit. This takes only one cycle. Once the read is completed, the data is stored in a register named EEdrd. The current state is written to the EEPROM on each state transition. In addition, the EEPROM is written with the user configurations upon exiting the program mode. Every time the system is reset, the EEPROM is read and the state and user configuration are loaded.
We used Timer 0 and Timer 1 to control time-dependent operations. Timer 0 is used to control the blink rate of the status LED when in the armed state. TIMSK is set up to enable Timer 0 and Timer 1 overflow interrupts. Within the t0ovfl interrupt routine, we saved the status register and decrement the count variable. On every interrupt, we reset the TCNT0 to 6 and restore the status register. The count variable is used to count the number of interrupts. Once the count reaches 0, we complement the LED register with an EOR instruction. The new LED pattern is output to PORT A and the count variable is reloaded. We used a prescaler value of 5, which equals the clock divided by 1024. This gives us an approximate on/off blink rate of twice per second.
Timer 1 is used as a duration timer. Similar to Timer 0, we use a count variable called count30 to count the number of interrupts. On every interrupt, we decrement the count30 variable and reload TCNT1. When count30 reaches 0, we clear the T bit in the status register and turn off Timer 1. Using a prescaler of 5 (clk/1024) and count30 values 2 and 4, we can acheive (approximately) 30 second and 60 second intervals, respectively. We use this to control the auto-arming feature and siren duration.
In order to change the user setting, we created an RS232 interface. This interface is essentially the same as the interface from the lab 4 demo program. In order to access the RS232 interface, the system must be in the program state. This is accomplished by putting the system in valet state (button 2) and then pressing the program button (button 3). The program polls for a 'p' from the RS232 port. Once an initial 'p' is acknowledged, a menu string (stored in FLASH) is sent to the PC's terminal program. The menu consists of three user-definable settings -- siren duration (30/60 seconds), auto-arming (enable/disable), and chirp silencing (enable/disable). In order to quit and save, the user presses 'p' and closes the connection. Each setting is toggled by pressing '1','2', or '3'. The new setting is displayed on the terminal after each keyboard press. After exiting, the values are written to the EEPROM and the system returns to valet state.
We used a state machine to implement a push button debounce routine. Our debounce routine is very similar to the debounce used in lab 3, with some modifications. We used this routine in each state to poll for push button presses.
We needed to develop hardware to control a 12V siren through a port pin. The siren specifications required a 12VDC source capable of 600 mA. The port pin is at most 5VDC and 20 mA. Since the functionality of the siren in our system is such that it only operates when a security breach is encountered (or a chirp signal is needed), we needed to implement some sort of switching mechanism. We used a 12VDC relay to switch the siren on and off. This particular relay required a 12VDC turn on signal capable of driving 0.5 A. In order provide the necessary turn-on voltage to the relay, we used an op-amp circuit with the output of the op-amp (LM358) wired the the base of an NPN power transistor (TIP31C). The emitter is wired to a 12VDC external power supply and the collecter is wired to the turn-on pin of the relay. The op-amp circuit is a positive gain amplifier. The noninverting input is connected to the port pin (PORT C4) and the inverting input is connected to voltage divider circuit. With this configuration, we were able to achieve an output voltage of 10.5VDC. This is enough voltage to turn on the transistor, provides a 12VDC signal with sufficient current to drive the relay. The schematics are located in the appendix.
In order to simulate security breaches (such as opening doors, etc) we used a 4 button module connected to sensor inputs (PORT C 0..3). The relevent PORT C pins are set to input and pulled high. The push button module is connected to each of the 4 port pins and the common pin on the button module is connected to ground. When a button is pressed it pulls the input down to 0. In the program, the pins are polled. Upon reading a logic 0 on the pins, the state transitions to the active mode, which activates the siren.The schematics are located in the appendix.