📄 safety lock 2313.asm
字号:
;===================================================================================
;=
;= Electronic safety lock with telecard-key (AT90s2313 version)
;=
;= Date: 23-Dec-2003
;= Author: Serasidis Vasilis
;= Target: AT90S2313 at 4MHz crystal
;= Writed with: AVR Studio 4.07
;=
;= Home: http://www.serasidis.gr
;= email: info@serasidis.gr
;=
;=
;====================================================================================
;
;***** Pin definitions
.equ reg_crd =0 ;Register card to eeprom button PB0 (SW2)
.equ unreg_crd =1 ;Unregister card from eeprom button PB1 (SW3)
.equ relay =2 ;relay output
.equ crd_sw =3 ;Switch for start reading the card is PB3
.equ Data =4 ;Input-Output pin is PB4
.equ CLK =5 ;Clock pin is PB5
.equ RST =6 ;Reset pin is PB6
.equ green_led =0 ;Green LED to PD0 pin
.equ red_led =1 ;Led LED to PD1 pin
;***** Global register variables
.def temp =R16 ;temporary storage register
.def byte_length =R17
.def group_length=R18
.def EEadr =R19 ;EEPROM address to read from
.def Byte =R20 ;Telecards data
.def delay2seconds=R20 ;
.def temp2 =R21
.def leds_flash =R22
.include "2313def.inc"
reset:
ldi temp,RAMEND ;Init Stack Pointer
out SPL,temp
ldi temp,0b11100100
out DDRB,temp ;Make PB0,PB1,PB6 outputs and other pins inputs
ser temp ;
out PortB,temp ;Enable internal pullup resistors on PB2-PB7
ldi temp,0xff
out DDRD,temp ;port D output
clr temp
out portD,temp
;--------------------------------------------------------------------------
; Reading of the card
;--------------------------------------------------------------------------
read_card:
cbi portD,red_led
cbi portD,green_led
cbi portB,relay ;disarm the relay
ldi delay2seconds,6
chk_sw3:
sbic PINB,unreg_crd ;check if 'unregister card' button is closed, when no card is inside to the slot.
rjmp nxt ;if not, go to check the card`s base switch
rcall delay ;delay
rcall delay
rcall delay
rcall delay
dec delay2seconds ;this make a loop for 2 seconds, to see if SW3 is pressed continued for 2 seconds...
brne chk_sw3 ; to erase entire internal eeprom of AT90s2313.
ldi group_length,127;if yes, select 128 bytes of eeprom (0-127)
clr EEadr ;clear eeprom address
ldi Byte,$0F ;we fill all eeprom bytes with $0F value
ldi leds_flash,4 ;flash 4 times the red led
flash_led2:
cbi portD,green_led ;turn off the red led
rcall delay ;delay
rcall delay ;delay
rcall delay ;delay
rcall delay ;delay
sbi portD,green_led ;turn on the red led
rcall delay ;delay
rcall delay ;delay
rcall delay ;delay
rcall delay ;delay
dec leds_flash ;decrease 'leds_flash' register
brne flash_led2 ;if not the last led "flash" go to flash more the red led
rcall clr_group ;if yes, call the routine 'clr_group' to clear the internal eeprom
nxt:
sbis PINB,crd_sw ;Check if card`s base switch is closed
rjmp read_card ;if not, read it again
rcall delay ;if yes, delay some time
sbi portB,RST ;reset the card
rcall delay
rcall delay
rcall delay
rcall delay
cbi portB,RST ;
rcall delay
rcall delay
rcall delay
rcall delay
ldi YL,96 ;First RAM address
clr eeadr ;clear EEPROM address
ldi group_length,16 ;read the 16 first bytes of the card
next_byte:
clr Byte
ldi byte_length,8 ;8 bits length for the byte
next_bit:
ror Byte ;Rotate right the Byte register
sbi PORTB,clk ;Clear the clock
nop
nop
nop
nop
sbic PINB,data ;Read if the data pin, is '1'
sbr Byte,0x80 ;If yes, make '1' to the 8th bit of Byte register
nop
nop
nop
nop
cbi PORTB,clk ;Set the clock
nop
nop
nop
nop
dec byte_length ;Decrease by 1 the byte_length register
brne next_bit ;If byte_length register its not 0, go to next_bit
st Y+,Byte ;store current byte to RAM and increase RAM address
dec group_length ;Decrease byte counter
brne next_byte ;if its not the last byte (16th), go to read next
;--------------------------------------------------------------------------
; compare the readed bytes with the stored to eeprom
;--------------------------------------------------------------------------
compare:
ldi YL,96 ;First RAM address
clr EEadr ;Clear eeprom address
ldi group_length,16 ;16 bytes it will read
ldi temp,16
lnb:
ld temp2,Y+ ;load byte from the RAM to 'temp2'
rcall EEread ;load byte from the eeprom to 'Byte'
dec group_length ;decrease bytes counter
breq arm_relay ;if its the last byte, go to arm the relay
cp Byte,temp2 ;compare 'Byte' with 'temp2'
breq lnb ;if its the same, go get next bytes
ldi temp2,15 ;if not...
ldi group_length,16 ;set byte counter to 16
add temp2,temp ;add 16 to temp2
mov temp,temp2 ;copy temp2 to temp
ldi YL,96 ;init RAM to first address
mov EEadr,temp ;set the eeprom start address to the next group (next 16 bytes)
cpi temp,127 ;if its the last RAM byte address,
breq read_switches ; exit from this routine
rjmp lnb ;else, check next group
;--------------------------------------------------------------------------
; If comparing is OK, arm the relay
;--------------------------------------------------------------------------
arm_relay:
sbi portD,green_led
cbi portD,red_led
sbi portB,relay ;arm the relay
rcall delay
sbis PINB,unreg_crd ;
rjmp unregister_card ;
sbic PINB,crd_sw ;Check if card`s base switch is still closed
rjmp arm_relay
rjmp read_card
;--------------------------------------------------------------------------
; If comparing is not OK, check if user want to register new telecard
;--------------------------------------------------------------------------
read_switches:
cbi portD,green_led
sbi portD,red_led
sbic PINB,crd_sw ;Check if card`s base switch is still closed...
rjmp read_next_sw ;if its stil closed, go to read 'register card' button
rcall delay ;if its not closed...
rjmp read_card ;go to read another telecard (if card`s base switch is closed)
read_next_sw:
sbis PINB,reg_crd ;Check if 'register card' button is closed
rjmp reg_card ;if yes, go to register
rjmp read_switches ;if not, read the switches again
;--------------------------------------------------------------------------
; Register a telecard to eeprom
;--------------------------------------------------------------------------
reg_card:
sbis PINB,reg_crd ;Check if 'register card' button is closed
rjmp reg_card ;
ldi temp2,8 ;set the group counter to 8 ( 8 group of 16 bytes each)
clr EEadr
read_again_eeprom:
ldi temp,16
rcall EEread
dec EEadr
cpi Byte,$0F ;check if is empty area (16 bytes long)
breq store
dec temp2
breq memory_full
add EEadr,temp ;go to next 16 bytes group
rjmp read_again_eeprom
store:
ldi group_length,16 ;define how many bytes are the code
ldi YL,96 ;first RAM address
nxt_byte:
ld Byte,Y+ ;load a byte from RAM
rcall EEwrite ;and write it to free eeprom group
dec group_length ;Decrease byte counter
brne nxt_byte ;if its not the last byte (16th), go to read next
rjmp reset ;read_card
;--------------------------------------------------------------------------
; Unregister telecard from eeprom
;--------------------------------------------------------------------------
unregister_card:
sbis PINB,unreg_crd ;
rjmp unregister_card
ldi group_length,16
subi EEadr,16
ldi Byte,$0F
clr_group:
rcall EEwrite
dec group_length
brne clr_group
rjmp read_card
;--------------------------------------------------------------------------
; Read the contain of the eeprom to 'byte' register
;--------------------------------------------------------------------------
EERead:
sbic EECR,EEWE ;if EEWE not clear
rjmp EERead ; wait more
out EEAR,EEadr ;output address
sbi EECR,EERE ;set EEPROM Read strobe
in Byte,EEDR ;get data
inc EEadr ;increase eeprom address
ret
;--------------------------------------------------------------------------
; Write the contain of 'byte' to the eeprom
;--------------------------------------------------------------------------
EEWrite:
sbic EECR,EEWE ;if EEWE not clear
rjmp EEWrite ;wait more
out EEAR,EEadr
out EEDR,Byte ;output data
sbi EECR,EEMWE ;set master write enable
sbi EECR,EEWE ;set EEPROM Write strobe
inc eeadr ;increase eeprom address
ret
;--------------------------------------------------------------------------
; If eeprom memory is full, flash 4 times the leds
;--------------------------------------------------------------------------
memory_full:
ldi leds_flash,4 ;flash 4 times the 2 leds
flash_leds:
sbi portD,red_led
cbi portD,green_led
rcall delay
rcall delay
rcall delay
rcall delay
dec leds_flash
cbi portD,red_led
sbi portD,green_led
rcall delay
rcall delay
rcall delay
rcall delay
dec leds_flash
brne flash_leds
ret
;--------------------------------------------------------------------------
; Delay routine
;--------------------------------------------------------------------------
delay:
ldi temp2,255
delay_:
ldi temp,255
delay1:
dec temp
brne delay1
dec temp2
brne delay_
ret
;--------------------------------------------------------------------------
; internal eeprom contain (128 bytes)
;--------------------------------------------------------------------------
.eseg
.db $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
.db $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
.db $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
.db $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
.db $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
.db $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
.db $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
.db $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -