⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 safety lock 2313.asm

📁 编辑音乐乐谱 通过单片机实现音乐编辑功能
💻 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 + -