.include "tn2313def.inc"


.def temp1=R16
.def temp2=R17
.def temp3=R18

.def digit=R20

.equ DIGITS=3           ;число разрядов индикатора
.equ SEG7_PORT=PORTB    ;порт, к которому подключен индикатор
.equ SEG7_ANOD=PORTD    ;порт, к которому подключен анод индикатора

;---------------------------------Переменные в ОЗУ----------------------------------
.dseg 
 Display_Buf: .byte DIGITS ;буфер индикатора
 bounce_cnts: .byte 4 ;резервируем 4 байта для счетчиков подавления дребезга контактов кнопок

;-------------------------------Переменные в ЭСППЗУ---------------------------------
.eseg
high_H: .db 40
low_H:  .db 20

;-----------------------------------------------------------------------------------
.cseg
.org 0

;Переопределение векторов прерываний
rjmp Reset        ;прерывание по сбросу
reti              ;INT_0 - первое внешнее прерывание (сигнал на вывод микросхемы "INT0") 
reti              ;INT_1 - второе внешнее прерывание (сигнал на "INT1") 
reti              ;Timer1_capt1 - Таймер/счетчик1, захват
reti              ;Timer1_comp1 - прерывание компаратора A 1-го таймера
reti              ;Timer1_OVF1 - по переполнению 1-го таймера
reti              ;Timer0_OVF0 - по переполнению 0-го таймера
reti              ;UART_RX - по окончанию приема пакета по протоколу UART
reti              ;UART_UDRE - по опустошению регистра данных UART
reti              ;UART_TX - по окончанию передачи пакета по UART
reti              ;ANA_COMP - прерывание аналогового компаратора
reti              ;Прерывание по изменению на любом контакте
reti              ;Таймер/счетчик1, совпадение, канал B
rjmp Timer0_compA ;Таймер/счетчик0, совпадение, канал A
reti              ;Таймер/счетчик0, совпадение, канал B
reti              ;USI готовность к старту
reti              ;USI переполнение
reti              ;EEPROM готовность
reti              ;Переполнение сторожевого таймера



;--------------------------------Инициализация-------------------------------------
reset:
       
      ;Инициализация стека
       ldi temp1, RAMEND
       out SPL, temp1


      ;Инициализация портов ввода-вывода
       ;настройка порта B
	   ldi temp1,0b11111111
       out DDRB, temp1 ;все линии порта B на вывод
       ;настройка порта D
       ldi temp1,0b01001111
       out DDRD, temp1 ;1-3 и 6 линии порта D на вывод, 5 и 4 линии - на ввод

      ;Инициализация таймера 0
	   ldi temp1, 0x02
       out TCCR0A, temp1
       ldi temp1, 0x03
       out TCCR0B, temp1
       ldi temp1, 0x00
       out TCNT0, temp1
	   ldi temp1, 124
       out OCR0A, temp1

      ;Инициализация таймера 1
	   ldi temp1, 0x07
       out TCCR1B, temp1

      ;Разрешение прерываний от таймера 0
	   ldi temp1, 0x01
	   out TIMSK, temp1

      ;Выключение аналогового компаратора
	   ldi temp1, 0x80
	   out ACSR, temp1

      ;Инициализация сторожевого таймера
       ldi temp1, 0x18
	   out WDTCR, temp1
	   ldi temp1, 0b00001001
	   out WDTCR, temp1

	   sei ;разрешение прерываний

;========================Основной бесконечный цикл программы=======================
main:
     ldi temp1,0
rjmp main
;==================================================================================

seg7_DC:
;массив - таблица истинности декодера
              ;     hgfedcba   hgfedcba
              .db 0b11000000,0b11111001	;0,1
              .db 0b10100100,0b10110000	;2,3
              .db 0b10011001,0b10010010	;4,5
              .db 0b10000010,0b11111000	;6,7
              .db 0b10000000,0b10010000	;8,9

;-----преобразование двоичной цифры в код 7-сегментного индикатора----
Decoder:
		 push temp2

         ldi ZL,Low(seg7_DC*2)   ;инициализация массива
         ldi ZH,High(seg7_DC*2)

         ldi temp2,0             ;прибавление переменной
         add ZL,temp1            ;к 0-му адресу массива
         adc ZH,temp2

         lpm                     ;загрузка значения
         mov temp1,r0
         
		 pop temp2
ret
;---------Динамическая индикация на 7-сегментном индикаторе-----------
seg7_Display:
         
		 push temp1
		 push temp2
		 push YL
		 push YH
         
		 ldi temp1,1
		 ldi temp2,0

seg7_shl_beg:
         cp temp2,digit
		 brsh seg7_shl_end
         lsl temp1
		 inc temp2
		 rjmp seg7_shl_beg
seg7_shl_end:

		 in temp2,SEG7_ANOD
		 andi temp2,(0xFF<<DIGITS)&0xFF
         or temp2,temp1
		 out SEG7_ANOD,temp2


		 ;загрузка адреса буфера индикатора в Y-регистр
		 ldi YL,Low(Display_Buf*2)   
         ldi ZH,High(Display_Buf*2)
         
		 ;прибавление номера разряда к адресу нулевого разряда
		 ldi temp1,0
		 add YL,digit
		 adc YH,temp1

         ld temp1,Y          ;загрузка индицируемой цифры в РОН
		 rcall Decoder       ;преобразование цифры в 7-сегментный код
         out SEG7_PORT,temp1 ;вывод цифры на индикатор
		 
		 inc digit

         cpi digit,DIGITS
         brlo seg7_no_inc_dig
         clr digit
seg7_no_inc_dig:
		 
		 pop YH
		 pop YL
		 pop temp1
ret

;-----------------Обработчик прерываний компаратора A 0-го таймера-----------------
Timer0_compA:
       
       wdr

       ldi temp1,1
	   sts Display_Buf,temp1
	   ldi temp1,2
	   sts Display_Buf+1,temp1
	   ldi temp1,3
	   sts Display_Buf+1,temp1
	    
       rcall seg7_display
reti ;выход из обработчика прерываний компаратора A 0-го таймера
