Full Version : Bae & Lim Car Alarm System (AVR ASM)
avr >>AUTOMOTIVE >>Bae & Lim Car Alarm System (AVR ASM)


Admin5- 04-22-2006
Clifford Systems JI1000 Car Alarm System
By Ji Bae and Cliff Lim for EE476, Spring '99


Introduction
The design philosophy behind the JI1000 is a simple, yet powerful microcontroller based mobile security system. At the heart of the JI1000 is the Atmel AT90S4414 8-bit RISC microcontroller. We used the 4414 for this design because a microcontroller is well-suited for a security system. The basic control functions for our system include monitoring inputs (such as sensors, push buttons, etc) and controlling output signals (such as sirens, lights, LEDs, etc). These functions are easily implementable in an embedded processor.
Our design involves a combination of hardware and software. The control functions were programmed in assembly language and downloaded into the FLASH memory on the microcontroller. The hardware consisted of circuitry to run the siren and to simulate the sensors which trigger the alarm. In addition, we designed hardware to provide the necessary power and voltage levels to all the components.

Features
Our design has the following features:

4 Button Input System
Disarm/Arm, Remote Valet, Panic, Program

Remote Controlled Valet Mode
A press of a button will put your JI1000 system in valet mode to allow vehicle servicing or attendant parking. The system audibly confirms remote valet mode exit or entry with a distinct 4 siren chirp signal.

Full-Time Remote Panic with Automatic Door Locking and Unlocking
If you feel threatened, with just a single press, you can remotely activate the siren, flash lights and unlock your vehicle's power door locks for quick entry into your car without fumbling with your keys. If you are driving the vehicle and press the panic button, the siren will sound, the lights will flash and the doors will automatically lock to shield you from the assailant.

Chirp Silencing
Whenever you remotely arm or disarm, the siren "chirps" and the parking lights flash to confirm system status. Whenever you wish, you may silence the chirps via an RS232 interface.

Remote Door Locking/Unlocking
A press of a button on the remote simultaneously arms your JI1000 system and locks your vehicle's power locks. Another press disarms and unlocks the doors.

Deluxe Entry in Valet Mode
Use your remote control to lock and unlock the car doors even while the system is in valet mode.

High-Output Siren
A loud (110 dB) yet compact siren designed exclusively by Radio Shack. For extra visual attention, it includes a built in strobe light.

User-Selectable Siren Duration
You may set the siren wail for either 30 or 60 seconds via RS232 interface.

Enhanced User-Selectable AutoArming
Your JI1000 system will actually arm itself "passively" if you forget to arm it. This feature may qualify you for an insurance discount that could pay for the system (consult your insurance company).

AutoArming Enable/Disable
You may disable or re-enable AutoArming via RS232 interface.

Prior Intrusion Attempt Alert
When you return to your vehicle and disarm your JI1000 system with the remote control, a special chirp and light sequence will audibly and visually alert you from a distance if an intrusion attempt was foiled while you were away.

High-Luminescence LED Status Indicator
Bright red LED adds visual deterrence and identifies system status: armed, disarmed and valet mode.

Multiple Sensor Inputs
Up to 4 inputs to monitor sensors or triggers.

SmartPowerUp
When power to the system is disconnected, the system's EEPROM always remembers the last state (armed, disarmed or valet mode) and returns to that state when power is restored. So if a thief disconnects the power and then restores it in an attempt to start the car, the system will re-arm and instantly sound the siren while immobilizing the vehicle.

User Programmable Interface with RS232 Connection
This allows you to connect your JI1000 system to a PC and configure all user settings such as chirp silencing, siren duration, and auto-arming. This feature includes a user-friendly menu. All user settings are retained in the EEPROM.

High Level Design

The control logic for our design is implemented within a state machine. The state diagram is available in the appendix. We based our states and state transitions on the specifications of actual alarm systems. We implemented features from various products based on usefulness and feasibility.

The state machine consists of six states:
Arm -- Lock doors, blink status LED, monitor all inputs.
Disarm -- Unlock doors, turn off status LED.
Valet -- Turn on status LED, disable auto-arming.
Panic -- Turn on siren, toggle locks.
Active -- Turn on siren for siren duration.
Program -- Turn off LEDs, open RS232 communication.

We assign the ports in the following manner:
Port A -- control LEDs.
Port B -- push buttons.
Port C -- sensor/trigger and siren output.
Port D -- RS232 interface.

Program/Hardware Design

Program Design

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.

Hardware Design

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.

Results

Our project designs were met successfully. The functionality of our system met or exceeded our expectations. The main issue in our product is reliability and usability. We thoroughly tested each state and the state transistions against our specifications. The RS232 interface was tested using hyperterm. We tested the EEPROM by powering down and checking the EEPROM setting on power up. During the EEPROM testing, we discovered that the EEPROM was not 100% reliable. We concluded that this is due the strict power stability requirements of the EEPROM and the lack of brown-out protection on the evaluation board. While testing the reset, the EEPROM functioned correctly and we did not experience any problems. Therefore, we attribute our observed difficulties to the irregularities in the power supply when powering down the board. In all other cases, our testing proved that our design goals were met.

Conclusion

In conclusion, we are fully satisfied with the operation and design of our system. However, if we had more resources, we would have liked to implement an RF TX/RX interface to control our system instead of the 4 hard-wired pushbuttons. This would have given us a more realistic remote-control capability of real-world systems. In addition, we would have liked to implement more advanced user configurable features such as False Alarm Control and Testing, pager notification, anti-code grabbing and scanning technologies, and anti-car jacking measures. Fortunately, our design can be easily modified to accomodate advanced features without significant hardware or software changes. This allows the JI1000 to evolve and change with the user's need.

Link: http://instruct1.cit.cornell.edu/courses/e...jects/s1999/ji/

CODE

;;***************************************
;;* Ji Bae & Clifford Lim
;;* Monday Afternoon Lab
;;* Final Project
;;* Hi-Tek Car Alarm
;;* Port A - LED outputs
;;* Port D - RS232 interface
;;* Port C - Inputs from Triggers and Sensors and Siren Output
;;* Port B - Inputs from Push Buttons
;;***************************************

;.include "c:\users\ji&cliff\4414def.inc"
.include "c:\avrtools\appnotes\4414def.inc"
.device AT90S4414


.def EEdrd =r0;EEprom read data
.def count30 =r1;30 second count
.def savSREG =r2;save the status register
.def reload =r3;reload for timer 1
.def sensmem =r15;trigger memory
.def temp =r16;temporary register
.def uconfig =r17;user config options from EEprom
.def TXbusy =r18;transmit busy flag
.def RXchar =r19;a received character
.def TXflash =r20;text to be sent is in flash if <>0
.def state =r21;state of the alarm
.def LED =r22;LED pattern
.def count =r23;counter for interrupts
.def sensors =r24;input triggers/sensors
.def  press =r25;press register
.def dbstate =r26;debounce state register
.def lock =r27;register flag which simulates lock -- temporary
.def wreg =r28;working register
.def EEdwr =r29;data for write to EEprom
.def EEaddr =r31;address for EEprom r/w

.equ baud96 =25;9600 baud constant for 4Mhz crystal
.equ go ='p' ;0x67 ascii 'p'
.equ one ='1'
.equ two ='2'
.equ three ='3'
.equ stop ='s';0x73 ascii 's'
.equ azero ='0';0x30 ascii '0'
.equ button3 =0xf7;button 3 pressed -- program button
.equ button2 =0xfb;button 2 pressed -- panic button
.equ button1 =0xfd;button 1 pressed -- valet button
.equ  button0 =0xfe;button 0 pressed -- arm/disarm button

.equ arm = 0;states for alarm operation
.equ disarm = 1
.equ panic = 2
.equ valet = 3
.equ active  = 4
.equ program = 5

.equ st0 = 0;states for push button debouncing
.equ  st1 = 1
.equ  st2 = 2
.equ  st3 = 3

.equ sec1 = 2;30 second duration
.equ sec2 = 4;60 second duration

;masks for user config eeprom settings
.equ sdur = 0x01;siren duration
.equ aarm = 0x02;auto arm/lock
.equ chirp = 0x04;quiet chirp

.cseg
.org $0000
rjmp  RESET;reset entry vector
reti  
reti
reti
reti
reti
rjmp t1ovfl;Timer 1 overflow - used for timing
rjmp t0ovfl;Timer 0 overflow - used for LED
reti
rjmp RXdone;UART receive done
rjmp TXempty;UART buffer empty
rjmp  TXdone;UART transmit done
reti

;define fixed strings to be tranmitted from flash- zero terminated
text1: .db "Program mode",0x0d, 0x0a, 0x00
crlf: .db 0x0d, 0x0a, 0x00 ;carrage return/line feed
menu1: .db "1) Siren Duration 30/60",0x0d, 0x0a, 0x00
menu2: .db "2) Auto Arm/Lock toggle",0x0d, 0x0a, 0x00
menu3: .db "3) Quiet Chirp",0x0d, 0x0a, 0x00
menu4: .db "p) Quit",0x0d, 0x0a, 0x00
menu5: .db "Make your choice (1,2,3,p):  ",0x0d, 0x0a, 0x00
resp1: .db "*** Siren duration = 30",0x0d, 0x0a, 0x00
resp2: .db "*** Siren duration = 60",0x0d, 0x0a, 0x00
resp3: .db "*** Enabled",0x0d, 0x0a, 0x00
resp4: .db "*** Disabled",0x0d, 0x0a, 0x00
resp5: .db "*** Quit",0x0d, 0x0a, 0x00

RESET: ldi temp, LOW(RAMEND);setup stack pointer
out  SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp;initial conditions
clr TXbusy ;start out not busy on TX
ldi RXchar, stop;start out stoped

;setup UART -- enable TXempty & RXdone int, and RX, TX pins
ldi  temp, 0b10111000
out  UCR, temp

;set baud rate to 9600
ldi temp, baud96
out UBRR, temp

;intialize text pointer BEFORE turning on interrupts
;because RESET causes the TX empty flag to be SET
ldi ZL, LOW(crlf<<1);do shift to convert word-addr to byte
ldi  ZH, HIGH(crlf<<1)

;turn on Timer 0 and Timer 1 overflow interrupts
ldi temp, 0b10000010
out TIMSK, temp

;setup timer stuff
clr temp  ;turn off timer 0
out TCCR0, temp
ldi count, 4 ;setup LED blink rate
clr temp
out TCCR1B, temp ;turn off timer 1
set   ;set T bit

;setup ports
ser temp  ;set Port A all output
out DDRA, temp
out PORTA, temp ;all LED off initially
clr   temp
out DDRB,temp ;Set Port B all input - push buttons
ser temp
out PORTB,temp ;set Port B to pullups

ldi temp, 0xf0 ;set upper byte to output, lower byte to input
out DDRC, temp ;set Port C
ldi temp,0x0F
out PORTC, temp

ser temp  ;set Port D to all output
out DDRD, temp
out PORTD, temp ;set Port D to High

clr sensmem

ldi EEaddr,0x02  
rcall EERead
mov state, EEdrd ;load last state stored in EEPROM
ldi dbstate, st0 ;initialize keyboard debounce

ldi EEaddr,0x01  
rcall EERead
mov uconfig, EEdrd ;load user config from EEprom

ldi temp, sdur ;setup siren duration
and temp, uconfig
cpi temp, sdur ;determine specified duration
breq siren60
ldi temp,sec1 ;30 second duration
rjmp rel
siren60:ldi temp,sec2 ;60 second duration
rel: mov reload, temp
mov  count30,reload

sei

main: cpi state, arm ;main program is a state machine
breq a  ;armed state
cpi state, disarm
breq dbrch  ;disarm state
cpi state, active
breq actbrch  ;active state
cpi state, panic
breq pbrch  ;panic state
cpi state, valet
breq vbrch  ;valet state
cpi state, program
breq prbrch  ;program state
error: com state  ;error state
out  PORTA,state
rjmp main

;rjmps because branches out of reach
prbrch: rjmp prog
dbrch: rjmp d
pbrch: rjmp p
actbrch:rjmp act
vbrch: rjmp v

;armed state
a: ser temp  
out PORTA,temp;clear all LED's
ldi temp, 5 ;turn on timer 0 clk/1024
out TCCR0, temp;blink LED
cbi PORTA,0 ;lock doors
guard: rcall stenter ;poll for button press
cpi press, button0
breq to_d
       cpi press, button1
breq  to_v
cpi press, button2
breq to_p

in sensors,PINC;check for trigger
andi sensors,0x0F
cpi sensors, 0x0F
breq guard  
   
ldi state, active;go active if triggered
mov sensmem,sensors;store event
com sensmem ;reorder sensmem
ldi temp,0x0F
and sensmem, temp;only look at lower byte

ldi EEaddr,0x02;save state in EEprom
mov EEdwr,state
rcall EEWrite
set  ;set T bit for timing purposes
rjmp main ;go to main prog

to_v: ldi state, valet;load valet state
ldi EEaddr,0x02
mov EEdwr,state
rcall EEWrite ;save state in EEprom
clr temp ;reset Timer 1/Turn Off
out TCCR1B,temp
out TCNT1H,temp
out TCNT1L,temp
rcall SChirp ;siren chirp
rcall WChirp ;delay between chirps
rcall   SChirp
rcall WChirp
rcall SChirp
rcall WChirp
rcall   SChirp
rjmp main  ;go to main prog

to_p: ldi state, panic;load panic state
ldi EEaddr,0x02
mov EEdwr,state
rcall EEWrite ;save state in EEprom
clr temp ;reset Timer 1/Turn Off
out TCCR1B,temp
out TCNT1H,temp
out TCNT1L,temp
rjmp main  ;go to main prog

to_a: ldi state, arm;load armed state
ldi EEaddr,0x02
mov EEdwr,state
rcall EEWrite ;save state in EEprom
clr temp ;reset Timer 1/Turn Off
out TCCR1B,temp
out TCNT1H,temp
out TCNT1L,temp
rcall SChirp ;siren chirp
rcall WChirp ;delay between chirps
rcall SChirp
rjmp main

to_d: set  ;set T bit
cbi PORTC, 4;turn off siren
ldi state, disarm;load disarmed state
ldi EEaddr,0x02
mov EEdwr,state
rcall EEWrite ;save state in EEprom
clr temp ;reset Timer 1
out TCNT1H,temp
out TCNT1L,temp
rcall SChirp ;siren chirp
rjmp main

;disarmed state
d: sbi PORTA, 6
clr temp ;turn off timer 0
out TCCR0, temp
tst sensmem ;check if trigger while away
breq nosens ;else chirp three times
rcall WChirp
rcall SChirp
rcall WChirp
rcall SChirp
clr sensmem
nosens: sbrs uconfig,1;check for auto arm/lock enable
rjmp aarmoff
ldi temp,5
out TCCR1B,temp;timer1 clk/1024

in sensors,PINC;check for trigger
andi sensors,0x0F
cpi sensors, 0x0F;check for open trigger
brne open ;don't auto arm if trigger present
brtc to_a2 ;auto arm/lock
rjmp aarmoff  
open: set  ;reset auto/arm if trigger present
clr temp  
out TCNT1H,temp;reset Timer 1
out TCNT1L,temp
aarmoff:sbi PORTA,7
sbi PORTA,0 ;unlock doors
cbi PORTA,1 ;show disarm state on LED's
rcall stenter ;poll for button press, go to appropriate state
cpi press, button0
breq to_a
cpi press, button1
breq to_v2
cpi press, button2
breq to_p2
rjmp nosens

to_v2: rjmp to_v
to_p2: rjmp to_p

;active state
act: clr temp ;turn off timer 0
out TCCR0, temp  
ldi temp, 0x05
out TCCR1B, temp;turn on timer 1 clk/1024
sbi PORTA, 7

sbi PORTC, 4;turn on siren/strobe

act2: rcall  stenter ;poll for button press
cpi press, button0;look for disarm
breq to_d ;turn off if disarm button press
brtc to_a2 ;turn off after specified siren duration
rjmp act2

to_a2: cbi PORTC,4 ;turn off siren/strobe
ldi state, arm;load arm state
ldi EEaddr,0x02
mov EEdwr,state
rcall EEWrite ;save state in EEprom
clr temp ;reset Timer 1
out TCCR1B,temp
out TCNT1H,temp
out TCNT1L,temp
rjmp main ;go back to main prog

;panic state
p: clr temp ;turn off timer 0
out TCCR0, temp  

sbi PORTA, 7
cbi PORTA, 6;turn on siren/strobe

sbi PORTC,4 ;turn on siren

cpi lock,0 ;toggle locks
breq lockit2
sbi PORTA,0
clr lock
rjmp p2

lockit2:cbi PORTA,0
ser  lock

p2: rcall  stenter ;poll for button press
cpi press, button0;look for disarm button press
breq to_d2
rjmp p2

to_d2: rjmp to_d

;valet state
v: clr temp ;turn off timer 0
out TCCR0, temp  
cbi PORTA,7 ;constant LED light
sbi PORTA,1 ;clear other LED
rcall  stenter ;poll for button press
cpi press, button0;toggle lock on arm/disarm button press
breq toggle
cpi press, button1;get out of valet and go to disarm
breq to_d3
cpi press, button3;go to program state
breq to_prog

rjmp v

toggle: cpi lock,0 ;toggle lock upon disarm/arm button press
breq lockit
sbi PORTA,0
clr lock
rjmp v
 
lockit: cbi PORTA,0
ser  lock

rjmp v

to_d3: rjmp to_d

to_prog:ldi state, program;load program state
ldi temp, valet;store valet state in case of error
ldi EEaddr,0x02;store state in EEprom
mov EEdwr,temp
rcall EEWrite

ldi EEaddr,0x01;store user config settings
mov EEdwr,uconfig
rcall EEWrite
rjmp main  ;go back to main prog

stenter:cpi dbstate,st0;debounce state machine table for push buttons
breq _st0
cpi dbstate,st1
breq _st1
cpi dbstate,st2
breq _st2
cpi dbstate,st3
breq _st3
dberror:rjmp  dberror

_st0: in  temp, PINB;load input values
cpi temp, 0xFF;check for any button presses
breq _st0no ;if no press, return to itself
ldi dbstate,st1;go to next state
mov  press,temp;move button value into press register
_st0no: ret

_st1: in  temp,PINB;if current button doesn't equal last button pressed
cp temp,press
brne  _st1no ;go back to state 0
ldi dbstate,st2;else go to state 2
rjmp stenter

_st1no: ldi dbstate,st0;load state for state 0
ser press
ret

_st2: in  temp,PINB;if current button equals last button pressed
cp temp,press
breq _st2yes ;go back to itself
ldi dbstate,st3;else go to state 3

_st2yes:rjmp stenter

_st3: in  temp,PINB;if current button equals last button pressed
cp temp,press
breq _st3yes ;go back to state 2
ldi dbstate,st0;else return to state 0
ser press
ret

_st3yes:ldi dbstate,st2;load state for state 2
rjmp stenter

to_val2:rjmp to_val

;Program state
;wait for 'p' to start programming
prog: ser temp
out PORTA,temp;clear all LED's to signal program mode

rcall  stenter ;poll for button press
cpi press, button3;toggle program mode
breq to_val2 ;jump back to disarm state if button pressed

cpi  RXchar, go;wait for go signal - a 'p' on the keyboard
brne prog

msg: ldi RXchar,stop;reset RXchar - run once and wait

;set up the transmit pointer for the first message
ldi ZL, LOW(text1<<1) ;shifted becuase pgm memory is words
ldi ZH, HIGH(text1<<1);
lpm  ;put the char in r0
out UDR, r0 ;put the character in the UART buffer
ser TXflash ;string is in flash memory
ser TXbusy ;and set the TX busy flag
sbi UCR, UDRIE;enable the TXempty interrupt
rcall TXwait ;chill until done

ldi ZL, LOW(menu1<<1) ;shifted becuase pgm memory is words
ldi ZH, HIGH(menu1<<1);
lpm  ;put the char in r0
out UDR, r0 ;put the character in the UART buffer
ser TXflash ;string is in flash memory
ser TXbusy ;and set the TX busy flag
sbi UCR, UDRIE;enable the TXempty interrupt
rcall TXwait ;chill until done

ldi ZL, LOW(menu2<<1) ;shifted becuase pgm memory is words
ldi ZH, HIGH(menu2<<1);
lpm  ;put the char in r0
out UDR, r0 ;put the character in the UART buffer
ser TXflash ;string is in flash memory
ser TXbusy ;and set the TX busy flag
sbi UCR, UDRIE;enable the TXempty interrupt
rcall TXwait ;chill until done

ldi ZL, LOW(menu3<<1) ;shifted becuase pgm memory is words
ldi ZH, HIGH(menu3<<1);
lpm  ;put the char in r0
out UDR, r0 ;put the character in the UART buffer
ser TXflash ;string is in flash memory
ser TXbusy ;and set the TX busy flag
sbi UCR, UDRIE;enable the TXempty interrupt
rcall TXwait ;chill until done

ldi ZL, LOW(menu4<<1) ;shifted becuase pgm memory is words
ldi ZH, HIGH(menu4<<1);
lpm  ;put the char in r0
out UDR, r0 ;put the character in the UART buffer
ser TXflash ;string is in flash memory
ser TXbusy ;and set the TX busy flag
sbi UCR, UDRIE;enable the TXempty interrupt
rcall TXwait ;chill until done

ldi ZL, LOW(menu5<<1) ;shifted becuase pgm memory is words
ldi ZH, HIGH(menu5<<1);
lpm  ;put the char in r0
out UDR, r0 ;put the character in the UART buffer
ser TXflash ;string is in flash memory
ser TXbusy ;and set the TX busy flag
sbi UCR, UDRIE;enable the TXempty interrupt
rcall TXwait ;chill until done

;wait for input to change settings
prog2: cpi  RXchar, one;siren duration
breq m1
cpi RXchar, two;auto arm/lock
breq m2
cpi RXchar, three;quiet chirp
breq m3
cpi RXchar, go;quit
breq quit
rjmp prog2

;rjmp to fix branch out of reach
m1_br: rjmp m1
m2_br: rjmp m2
m3_br: rjmp m3

to_val: ldi EEaddr,0x01;store user config in EEprom
mov EEdwr,uconfig
rcall EEWrite
ldi state, valet;load valet state
ldi EEaddr,0x02
mov EEdwr,state
rcall EEWrite ;store state in EEprom
clr temp ;reset Timer 1/Turn off
out TCCR1B,temp
out TCNT1H,temp
out TCNT1L,temp
rjmp main  ;go back to main program

quit: ldi ZL, LOW(resp5<<1) ;ptr to RAM
ldi ZH, HIGH(resp5<<1)
lpm  ;put the char in r0
out UDR, r0 ;put the character in the UART buffer
ser TXflash ;string is in flash memory
ser TXbusy ;and set the TX busy flag
sbi UCR, UDRIE;enable the TXempty interrupt
rcall TXwait ;chill until done
ldi RXchar, stop

ldi temp, sdur ;setup siren duration
and temp, uconfig
cpi temp, sdur ;determine specified duration
breq s6
ldi temp,sec1 ;30 second duration
rjmp rel2
s6: ldi temp,sec2 ;60 second duration
rel2: mov reload, temp
mov  count30,reload

rjmp to_val  ;exit into valet mode

m1: ldi temp, sdur
eor uconfig, temp
sbrc uconfig, 0
rjmp sixty
rjmp thirty

m2: ldi temp, aarm
eor uconfig, temp
sbrc uconfig, 1
rjmp yes
rjmp no

m3: ldi temp, chirp
eor uconfig, temp
sbrc uconfig, 2
rjmp yes
rjmp no

yes: ldi ZL, LOW(resp3<<1) ;ptr to RAM
ldi ZH, HIGH(resp3<<1)
lpm  ;put the char in r0
out UDR, r0 ;put the character in the UART buffer
ser TXflash ;string is in flash memory
ser TXbusy ;and set the TX busy flag
sbi UCR, UDRIE;enable the TXempty interrupt
rcall TXwait ;chill until done
rjmp msg
no: ldi ZL, LOW(resp4<<1) ;ptr to RAM
ldi ZH, HIGH(resp4<<1)
lpm  ;put the char in r0
out UDR, r0 ;put the character in the UART buffer
ser TXflash ;string is in flash memory
ser TXbusy ;and set the TX busy flag
sbi UCR, UDRIE;enable the TXempty interrupt
rcall TXwait ;chill until done
rjmp msg
thirty: ldi ZL, LOW(resp1<<1) ;ptr to RAM
ldi ZH, HIGH(resp1<<1)
lpm  ;put the char in r0
out UDR, r0 ;put the character in the UART buffer
ser TXflash ;string is in flash memory
ser TXbusy ;and set the TX busy flag
sbi UCR, UDRIE;enable the TXempty interrupt
rcall TXwait ;chill until done
rjmp msg
sixty: ldi ZL, LOW(resp2<<1) ;ptr to RAM
ldi ZH, HIGH(resp2<<1)
lpm  ;put the char in r0
out UDR, r0 ;put the character in the UART buffer
ser TXflash ;string is in flash memory
ser TXbusy ;and set the TX busy flag
sbi UCR, UDRIE;enable the TXempty interrupt
rcall TXwait ;chill until done
rjmp msg

;*****************************
;interrupt routines
; UART needs a character
TXempty:in savSREG, SREG;save processor status
tst TXflash ;Is the string in flash memory?
breq TXram ;If not, it is in RAM
inc ZL ;get the next char from flash
lpm  ;and put it in r0
rjmp TXfls
TXram: inc ZL ;get the next char from RAM
ld r0,Z
TXfls: tst r0 ;if char is zero then exit
breq TXend
out  UDR, r0 ;otherwise transmit it
rjmp TXexit ;exit until next char
TXend: clr TXbusy ;no more chars
cbi UCR, UDRIE;clear the TXempty interrupt
TXexit: out SREG, savSREG;restore proc status
reti  ;back to pgm

;TX done -- buffer is empty  -- unused here
TXdone: in savSREG, SREG;save processor status
out SREG, savSREG;restore proc status
reti  ;back to pgm

;UART read a character
RXdone: in savSREG, SREG;save processor status
in RXchar, UDR ;get the character
out SREG, savSREG;restore proc status
reti  ;back to pgm

;T0overflow interrupt used for LED output
t0ovfl: in savSREG, SREG;save processor status
dec count
brne wait
ldi wreg,0b10000000  
in LED, PORTA ;get LED pattern
eor LED, wreg ;invert current LED Pattern
out PORTA, LED ;output LED pattern
ldi count, 8 ;reset counter
wait: ldi wreg, 6  
out TCNT0,wreg ;Reset Counter to 6
out  SREG, savSREG;restore proc status
reti  ;back to pgm

t1ovfl: dec count30
brne wait2
clt  ;clear T bit
mov count30,reload;reload counter
clr wreg
out TCCR1B,wreg;turn off timer 1
wait2: clr  wreg
out TCNT1H,wreg
out TCNT1L,wreg
reti  ;back to pgm


;*****************************
;subroutine
TXwait: tst TXbusy ;now wait for the tranmission to finish
brne TXwait
ret

;eeprom write subroutine
EEWrite:sbic EECR,EEWE;if EEWE not clear
rjmp EEWrite ;    wait more

out EEAR,EEaddr;output address
 
out EEDR,EEdwr;output data
sbi  EECR,EEMWE;set master write enable
sbi EECR,EEWE;set EEPROM Write strobe
  ;This instruction takes 4 clock cycles since
  ;it halts the CPU for two clock cycles
ret

;eeprom read subroutine
EERead: sbic EECR,EEWE;if EEWE not clear
rjmp EERead ;    wait more

out EEAR,EEaddr;output address

sbi EECR,EERE;set EEPROM Read strobe
  ;This instruction takes 4 clock cycles since
  ;it halts the CPU for two clock cycles
in EEdrd,EEDR;get data
ret

;single siren chirp routine
SChirp: ldi temp,0x4E
out TCNT1H,temp
ldi temp,0x20
out TCNT1L,temp
sbrs uconfig, 2;determine quiet chirp settings, on = skip
sbi PORTC, 4;turn on siren
set
ldi temp,1
mov count30,temp
ldi temp,2
out TCCR1B,temp
loop: brts loop
set
cbi PORTC, 4
ret

;silent chirp pause delay
Wchirp: ldi temp,0x4E
out TCNT1H,temp
ldi temp,0x20
out TCNT1L,temp
cbi PORTC,4
set
ldi temp,1
mov count30,temp
ldi temp,2
out TCCR1B,temp
tloop: brts tloop
set
ret

;------------------- EEPROM LISTING ---------------

.include "c:\avrtools\appnotes\4414def.inc"
.device AT90S4414


.eseg

eevar: .db 0x00,0x02,0x01



Schematics: http://instruct1.cit.cornell.edu/courses/e...jects/s1999/ji/



Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.