.def fASCIIL =r24;r11
.def fASCIIH =r19;r12
.def tASCII0 =r24;r11
.def tASCII1 =r23;r16
.def tASCII2 =r22;r13
.def tASCII3 =r21;r14
.def tASCII4 =r20;r15
.def cnt16a =r23;r16
.def tmp16a =r16;r17
.def tmp16b =r17;r18
bin2ASCII_digit:
ldi cnt16a, -1
bin2ASCII_digit_loop:
inc cnt16a
sub fASCIIL, tmp16a
sbc fASCIIH, tmp16b
brsh bin2ASCII_digit_loop
add fASCIIL, tmp16a
adc fASCIIH, tmp16b
ret
;* End bin2ASCII_digit
;***********************************
;***********************************
;*div16u 16/16 Bit Unsigned Division ;* dd8uH:dd8uL / dv16uH:dv16uL =
;*dres16uH:dres16uL drem16uH:drem16uL
.def drem16uL =r14
.def drem16uH =r15
.def dres16uL =r24;=r16
.def dres16uH =r19;=r17
.def dd16uL =r24;=r16
.def dd16uH =r19;=r17
.def dv16uL =r27;=r18
.def dv16uH =r25;=r19
.def dcnt16u =r26;=r20
div16u: ;clear remainder Low byte:
clr drem16uL
;clear remainder High byte and carry:
sub drem16uH,drem16uH
;init loop counter:
ldi dcnt16u,17
d16u_1: ;shift left dividend:
rol dd16uL
rol dd16uH
;decrement counter:
dec dcnt16u
brne d16u_2 ;if done
ret ; return
d16u_2: ;shift dividend into
; remainder
rol drem16uL
rol drem16uH
;remainder = remainder - divisor
sub drem16uL,dv16uL sbc drem16uH,dv16uH ;
brcc d16u_3 ;if result
;negative restore remainder
add drem16uL,dv16uL
adc drem16uH,dv16uH
clc
;clear carry to be shifted into ;result
rjmp d16u_1 ;else
d16u_3: sec ;set carry to be
;shifted into result
rjmp d16u_1
;* End div16u
;************************************
;************************************;* Timer1 Capture Handler
TIM1_CAPT: in temp1, SREG
;in capture_l, ICR1L
;in capture_h, ICR1H
in capture_l, TCNT1L
in capture_h, TCNT1H
ldi temp, 0
out TCNT1H, temp
out TCNT1L, temp
ldi temp, 0xC3
out TCCR1B, temp
out SREG, temp1
set
reti
;* End Timer1 Capture Handler
;************************************
;************************************
;* Timer1 OverFlow Handler
TIM1_OVF: in temp1, SREG
ldi char0, 0
ldi char1, 0
ldi char2, 0
ldi char3, 0
ldi char4, 0
ldi temp, 0xC0
out TCCR1B, temp
ldi temp, 0
out TCNT1H, temp
out TCNT1L, temp
out SREG, temp1
reti
;* End Timer1 OverFlow Handler
;************************************
;************************************
;* Timer0 OverFlow Handler
TIM0_OVF: in temp1, SREG
tst out_counter
breq get_char
rjmp show_char
get_char: mov out_char0, char0
mov out_char1, char1
mov out_char2, char2
mov out_char3, char3
mov out_char4, char4
rjmp continue
show_char: ld char_pointer, Z+
ldi temp, eetbl3
add char_pointer, temp
out EEARL, char_pointer
;address EEPROM
ldi temp, 0
out EEARH, temp;address EEPROM
sbi EECR, EERE ;strobe EEPROM
in char, EEDR ;read code
out PORTA, ZerRol
out PORTC, char
sbrc ZerRol, last_seg;brcs carry
rjmp move_ZerRol
New_loop: ldi ZH, 0
ldi ZL, start_addr
ldi ZerRol,0xFE ;rol ZerRol
rjmp continue
move_ZerRol: sec
rol ZerRol
continue: inc out_counter
out SREG, temp1
reti
;* End Timer0 OverFlow Handler
;************************************
.include "1200def.inc"
;Port B pins
.equ ROW1 =3
.equ ROW2 =2
.equ ROW3 =1
.equ ROW4 =0
.equ COL1 =7
.equ COL2 =6
.equ COL3 =5
.equ COL4 =4
;Port D pins
.equ GREEN =1;green LED indicate
;keynumber
.equ RED =0;red LED
;initialization & zero keynumber
.equ INT =2 ;interrupt input
.equ max_count =21
.equ reset_btn =4
.equ psw_length =2
.def temp =r16 ;
.def key =r17 ;key code pointer
;for EEPROM
.def fine =r18 ;loop delay
;counters
.def medium =r19
.def coarse =r20
.def status =r21 ;preserve
;sreg here
.def rowid =r22
.def colid =r23
.def counter =r24
.def key_pr_count =r25
.eseg ;EEPROM segment
.org 0
eetbl1: .db 4,3,2,1,8,7 ,6,5,12,11,10,9,16,15,14,13
eetbl2: .db 3,1,2,4
.cseg ;CODE segment
.org 0
rjmp reset ;Reset handler
nop
nop ;unused timer interrupt
nop ;unused analogue
;interrupt
reset:
ldi temp,0x03 ;initialise port D as O/I
out DDRD,temp ;
out PORTD,temp ;
sbi ACSR,ACD ;shut down
;comparator to save power
cli ;disable global
;interrupts
ldi key_pr_count, 0
set ;T=1 - true password ;(default);T=0 - false password
ldi temp,2
rjmp red_flash ;flash LEDs
;for example usage
init_scan: clr counter
scan: ldi temp,0xff
out DDRB,temp
ldi temp, 0x0f
out PORTB, temp
ldi rowid,0xAA
;0xAA - значение по умолчанию
;кнопка не нежата
sbis PINB,ROW1 ;find row of
;keypress
ldi rowid,0 ;and set ROW pointer
sbis PINB,ROW2
ldi rowid,4
sbis PINB,ROW3
ldi rowid,8
sbis PINB,ROW4
ldi rowid,12
cpi rowid, 0xAA
breq init_scan ;Branch if equal //counter=0
inc counter
cpi counter, max_count;
brlo scan ;Branch if not
;equal
ldi temp,0xF0 ;change port B I/O to find column press
out PORTB,temp ;
rcall settle ;allow time for
;port to settle
ldi colid, 0xAA
;0xAA - значение по умолчанию кнопка не нежата
sbis PINB,COL1
;find column of keypress
ldi colid,0
;and set COL pointer
sbis PINB,COL2
ldi colid,1
sbis PINB,COL3
ldi colid,2
sbis PINB,COL4
ldi colid,3
cpi colid, 0xAA
breq init_scan
;Branch if equal //counter=0
add rowid,colid
;merge ROW and COL for pointer
mov key, rowid
rjmp clr_counter
misc_rst: rjmp reset
clr_counter: clr counter
ldi temp, 0xAA
key_up_wait: sbis PINB,COL1 ;;ожидание поднятия клавиши
ldi temp, 0xCC
;если бит=0 то temp=cc
sbis PINB,COL2
ldi temp, 0xCC
sbis PINB,COL3
ldi temp, 0xCC
sbis PINB,COL4
ldi temp, 0xCC
cpi temp, 0xCC
breq clr_counter
inc counter
cpi counter, max_count ;
brlo key_up_wait
;Branch if not equal
ldi temp,0x00 ;reinitialise port B as I/O
out DDRB,temp ;
out PORTB,temp ;
flash: ldi temp, eetbl1
add key, temp
out EEAR, key;address EEPROM
sbi EECR, EERE;strobe EEPROM
in key, EEDR
;read code of pressed button
cpi key, reset_btn
;if key pressed = reset button
breq misc_rst
;then goto reset
ldi temp, eetbl2
add temp, key_pr_count
out EEAR, temp
sbi EECR, EERE
in temp, EEDR
;read password code
inc key_pr_count
cp key, temp
;if pressed wrong key
brne not_equal
;then goto not equal
equal: rjmp continue
not_equal: clt
;T=0 - false password
continue: cpi key_pr_count, psw_length;if kpc > psw length
brge kpr_exceed
;then goto kpr_exceed
not_kpr_exceed: rjmp init_scan
kpr_exceed: brts psw_true
;if T=1 then password is true
ldi key_pr_count, psw_length
;else (T=0 password is false)
rjmp init_scan
psw_true: ldi temp, 3
green_flash:
cbi PORTD,GREEN ; rcall delay
sbi PORTD,GREEN
rcall delay
dec temp
brne green_flash
exit: rjmp reset ;scan ;ret
red_flash: sbi PORTD,RED
rcall delay
cbi PORTD,RED
rcall delay
dec temp
brne red_flash
rjmp init_scan
;****Time Delay Subroutine for ;****LED flash****
delay: ldi coarse,3;8 ;triple nested FOR loop
cagain: ldi medium,255 ;
magain: ldi fine,255 ;
fagain: dec fine
brne fagain
dec medium
brne magain
dec coarse
brne cagain
ret
;***Settling time delay for port ;***to stabilise****
settle:
cagain2: ldi medium,2 ;
magain2: ldi fine,255 ;
fagain2: dec fine
brne fagain2
dec medium
brne magain2
ret
AT90S | 1200 | 2313 | 4414 | 8515 | 2323 | 4433 |
Диапазон напряжений питания, В | 2,7 - 6,0 | |||||
Тактовая частота, МГц *) | 0 - 16 | 0 - 20 | 0 - 16 | 0 - 20 | ||
Количество линий ввода/вывода (max) | 15 | 32 | 5 | 18 | ||
Количество инструкций | 89 | 120 | ||||
Объем Flash ROM, байт | 1K | 2K | 4K | 8K | 2K | 4K |
Объем EEPROM, байт | 64 | 128 | 256 | 512 | 128 | 256 |
Объем внутренней SRAM, байт | - | 128 | 256 | 512 | 128 | 128 |
Объем внешней SRAM, байт (max) | - | - | 64K | 64K | - | - |
Объем регистрового файла, байт | 32 | |||||
Количество таймеров/счетчиков | 1 | 2 | 2 | 2 | 1 | 2 |
ШИМ: Число каналов/разрядность | - | 1/8-10 | 2/8-10 | 2/8-10 | - | 2/8-10 |
Количество модулей захвата/сравнения | - | 1 | 2 | 2 | - | 2 |
Аналоговый компаратор | + | + | + | + | - | + |
SPI (загрузка ROM и EEPROM) | + | + | + | + | + | + |
SPI интерфейс (Master/Slave port) | - | - | + | + | - | + |
Сторожевой таймер | + | + | + | + | + | + |
Асинхронный последовательный порт | - | + | + | + | - | + |
Аналого - цифровой преобразователь | - | - | - | - | - | + |
Количество битов защиты | 2 | |||||
Число источников прерывания: внутренних/внешних | 2/1 | 8/2 | 10/2 | 10/2 | 2/1 | 11/2 |
Тип корпуса | DIP20, SOIC20, SSOP20 | DIP40, PLCC44, TQFP44 | DIP8, SOIC8 | DIP28, PLCC28 |