Кодовый замок

Схема
  
 
Текст программы микроконтроллера
 
.include "c:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8535def.inc"
.cseg
.org 0
 
.def tmp = r16                        ;временный регистр
.def t1 = r17                         ;1 разряд индикатора (VT3)
.def t2 = r18                         ;2 разряд индикатора (VT2)
.def t3 = r19                         ;3 разряд индикатора (VT1)
.def tmp2 = r20                       ;сдвиговая последовательность        
.def tm = r21                         ;число для текущего разряда
 
         rjmp RESET
RESET:   ldi tmp,HIGH(RAMEND)         ;определение начала стека
         out SPH,tmp                  ;в ОЗУ
         ldi tmp,LOW(RAMEND)        
         out SPL,tmp
         ser tmp                      ;установить tmp (= $ff)
         out DDRA,tmp                 ;линии порта A - выходы на индикатор
         out DDRB,tmp                 ;линии порта B - выходы
         out DDRC,tmp                 ;линии порта C - выходы на транзисторы
         ldi tmp,15                   ;инициализация сторожевого таймера:
         out WDTCR,tmp                ;при отсутствии команды сброса (wdr)
                                      ;в течение 2 с произойдет переход на
                                      ;прерывание RESET
         clr tmp                      ;очистить регистр tmp (= 0)
         out DDRD,tmp                 ;линии порта D - входы от кнопок
         out PORTA,tmp                ;очистить индикатор
         out PORTB,tmp
         out PORTC,tmp
                                      ;начальные значения регистров
         ldi XL,low(300)              ;загрузка в XH:XL константы 900
        ldi XH,high(300)
         ldi tmp2,0b00010000          ;регистр tmp2 = 00010000   
         clr tm                       ;очистить регистр tm (= 0)
         clr t1                       ;очистить регистр t1 (= 0)
         clr t2                       ;очистить регистр t2 (= 0)
         clr t3                       ;очистить регистр t3 (= 0)
 
;=====================================================
;управление разрядами индикатора
;=====================================================
Start:   wdr                          ;сброс сторожевого таймера
        
         rcall ind                    ;вывод на индикатор tm
         lsl tmp2                     ;сдвиг tmp2 влево
         out PORTC,tmp2               ;вывод на транзистор
         sbrc tmp2,7                  ;если в регистре tmp2 7 бит = 1
         ldi tmp2,0b00010000          ;то tmp2 = 00010000
        
         rcall key                    ;набор кода
        
         sbis PIND,PD3                ;если кнопка нажата             
         rcall Cod                    ;проверка набранного кода
 
         cpi tmp2,0b00100000          ;если транзистор VT3 открыт
         breq m1                      ;то перейти на метку m1                  
         cpi tmp2,0b01000000          ;если транзистор VT2 открыт
         breq m2                      ;то перейти на метку m2
         cpi tmp2,0b10000000          ;если транзистор VT1 открыт
         breq m3                      ;то перейти на метку m3
 
m1:      mov tm,t1                    ;копировать t1 в tm
         rjmp Start                   ;на метку Start
m2:      mov tm,t2                    ;копировать t2 в tm
         rjmp Start                   ;на метку Start
m3:      mov tm,t3                    ;копировать t3 в tm    
rjmp Start                            ;переход на метку Start
 
;=====================================================
;проверка набранного кода (825)
;=====================================================
Cod:
         cpi t1,8                     ;сравнение tm c 8          
         breq xm1                     ;если tm = 8 то перейти на метку xm1
         rjmp ex3
xm1: cpi t2,2                         ;сравнение tm c 2          
         breq xm2                     ;если tm = 2 то перейти на метку xm2
         rjmp ex3
xm2: cpi t3,5                         ;сравнение tm c 5          
         breq open                    ;если tm = 5 то перейти на метку open
         rjmp ex3
open:
         ser tmp                      ;установить tmp (= $ff)
         out PORTB,tmp                ;открыть замок
ex3:
ret
 
;=====================================================
;набор кода
;=====================================================
key:
         cpi XH,0                     ;проверка регистра XH
         brne ex2                     ;если XH<>0 перейти на метку ex2
         ldi XL,low(300)              ;загрузка в XH:XL константы 300
        ldi XH,high(300)
        
         sbis PIND,PD0                ;если в регистре PIND 0 бит = 0
         inc t3                       ;t1=t1+1
         sbis PIND,PD1                ;если в регистре PIND 1 бит = 0
         inc t2                       ;t2=t2+1
         sbis PIND,PD2                ;если в регистре PIND 2 бит = 0
         inc t1                       ;t3=t3+1
                                
          cpi t1,10                   ;если t1<>10
         brne w1                      ;то перейти на метку w1
         clr t1                       ;очистить регистр t1 (= 0)
w1:      cpi t2,10                    ;если t2<>10
         brne w2                      ;то перейти на метку w2
         clr t2                       ;очистить регистр t2 (= 0)               
w2:      cpi t3,10                    ;если t3<>10
         brne ex2                     ;то перейти на метку next2
         clr t3                       ;очистить регистр t3 (= 0)
ex2:
         sbiw XL,1                    ;XL=XL-1
ret                                   ;возврат из подпрограммы
 
;=====================================================
;подпрограмма вывода числа на текущий разряд индикатора
;=====================================================
ind:
     cpi tm,0                         ;сравнение tm c 0          
     breq x0                          ;если tm = 0 то перейти на метку x0
     cpi tm,1                         ;сравнение tm c 1          
     breq x1                          ;если tm = 1 то перейти на метку x1  
     cpi tm,2                         ;сравнение tm c 2
     breq x2                          ;если tm = 2 то перейти на метку x2
     cpi tm,3                         ;сравнение tm c 3
     breq x3                          ;если tm = 3 то перейти на метку x3
     cpi tm,4                         ;сравнение tm c 4
     breq x4                          ;если tm = 4 то перейти на метку x4
     cpi tm,5                         ;сравнение tm c 5
     breq x5                          ;если tm = 5 то перейти на метку x5
     cpi tm,6                         ;сравнение tm c 6
     breq x6                          ;если tm = 6 то перейти на метку x6
     cpi tm,7
     breq x7
     cpi tm,8
     breq x8
     cpi tm,9
     breq x9
 
x0: ldi tmp,0b10111011                ;загрузить код 0 в tmp
     out PORTA,tmp                    ;вывести tmp на индикатор
     rjmp ex                          ;переход на метку ex
x1: ldi tmp,0b10000010                ;загрузить код 1
     out PORTA,tmp                    ;вывести 1
     rjmp ex                          ;переход на метку ex
x2: ldi tmp,0b00111110                ;загрузить код 2
     out PORTA,tmp                    ;вывести 2
     rjmp ex                          ;переход на метку ex
x3: ldi tmp,0b10101110                ;загрузить код 3
     out PORTA,tmp                    ;вывести 3
     rjmp ex                          ;переход на метку ex
x4: ldi tmp,0b10000111                ;загрузить код 4
     out PORTA,tmp                    ;вывести 4
     rjmp ex                          ;переход на метку ex
x5: ldi tmp,0b10101101                ;загрузить код 5
     out PORTA,tmp                    ;вывести 5
     rjmp ex                          ;переход на метку ex
x6:  ldi tmp,0b10111101               ;загрузить код 6
     out PORTA,tmp                    ;вывести 6
     rjmp ex                          ;переход на метку ex
x7: ldi tmp,0b10100010                ;загрузить код 7
     out PORTA,tmp                    ;вывести 7
     rjmp ex                          ;переход на метку ex
x8: ldi tmp,0b10111111                ;загрузить код 8
     out PORTA,tmp                    ;вывести 8
     rjmp ex                          ;переход на метку ex
x9: ldi tmp,0b10101111                ;загрузить код 9
     out PORTA,tmp                    ;вывести 9
ex:
ret                                   ;возврат из подпрограммы

Скачать файлы проекта для AVR Studio 4 (7,08 КБ)