/* F = 20 MHz Генераторный кварц */

;Программа частотомера работающего по принципу обратного отсчета 
;Реализована формула fx = (20000000*M)/N
;M - количество периодов измеряемого сигнала за время измерения
;N - количество машинных циклов
;Врея измерения чуть более 1 секунды
;При входной fx=const время измерения должно быть постоянным, а значит и числитель и знаменатель - постоянны тоже!!!!!

;Версия рпограммы 1.0

;********************************************************************************* 
 
.device   tn2313;
.nolist;
.include   "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\tn2313def.inc";
;.include   "C:\Program Files\Atmel1\AVR Tools\AvrAssembler\Appnotes\tn2313def.inc";
.list;

;Определение рабочих регистров с присвоенными им символьными названиями
.def   temp = R16; Рабочий регистр
.def   temp1 = R17
.def   rab  = R18;
.def   rab1 = R19;
.def   rab2 = R20;
.def   rab3 = R21;
.def   rab4 = R22;
.def   rab5 = R23;
.def   rab6 = R24;
;.def   SIXTH = R25;


.def   Rez1 = R1;
.def   Rez2 = R2;
.def   Rez3 = R3;
.def   Rez4 = R4;
.def   Rez5 = R5;
.def   Rez6 = R6;
.def   Rez7 = R7;
.def   Rez8 = R8;
.def   Razn = R9;
.def   Razn1 = R10;

.def   ZaxvH = R14;
.def   ZaxvL = R15;


;Резервирование регистров в ОЗУ 
.dseg
Digit:     .byte 8; зарезервировали 8 двухбайтных регистров 


;Начало программного кода

	   .cseg;
	   .org	0;

;***** Определение векторов прерываний *****

	rjmp  INIT;     переход на начало программы
	reti;           внешнее прерывание 0
	reti;           внешнее прерывание 1          
	rjmp  ST_CCH;   Таймер/счетчик 1, захват
	reti;           Таймер/счетчик 1, совпадение, канал А
	rjmp  FULL_TC1; Таймер/счетчик 1, прерывание по переполнению            
	rjmp  TIME;     Таймер/счетчик 0, прерывание по переполнению   
	reti;           Прерывание UART прием завершен
	reti;           Прерывание UART регистр данных пуст
	reti; 	        Прерывание UART передача завершена
    reti;           Прерывание по компаратору
    reti;           Прерывание по изменению на любом контакте
    reti;           Таймер/счетчик 1, совпадение, канал В
    reti;           Таймер/счетчик 0, совпадение, канал A
    reti;           Таймер/счетчик 0, совпадение, канал B
    reti;           USI готовность к старту
	reti;           USI переполнение
	reti;           EEPROM готовность
    reti;           переполнение охранного таймера


INIT:
/* Инициализация стека */

	ldi   temp,   RAMEND /*0xFF*/; выбор адреса вершины стека
	out   SPL,    temp; запись его в регистр стека    
;****************************************************

;Инициализация портов
	
	ldi   temp, 0b11110011;
	out   DDRB, temp; направление передачи данных (вход/выход) 
 	ldi   temp, 0b00001100; 
	out   PORTB, temp;  PB7 - CLK,PB6 - SDA - для вывода на дисплей (по умолч на вых 0)  
					 ;	PB3 - переключ ВЧ/НЧ
					 ;	PB2 - переключ НЧ1/НЧ2  

	ldi   temp, 0b10111111;
	out   DDRD, temp; направление передачи данных (вход/выход) 
 	ldi   temp, 0b01000000;
	out   PORTD, temp;  порт условно выключен (обращения нет, на выводах 0)   

;***************************************************
	 
;Отключение компаратора

	ldi   temp, 0x80;
	out   ACSR, temp; оключение компаратора

;*******************************

;Инициализация отключения компаратора

	ldi   temp, 0x80;
	out   ACSR, temp; 

CLEAR_DISPLAY:
	ser  temp;  вытираем все показания дисплея
	ldi  rab6, 64; впихиваем в дисплей 64 единицы (чтобы полностью удалить инфу с дисплея)	
	sec;  чтобы в temp не было 0 из-за команды rol
 	
	rcall DISPLAY;
	clc;

HELLO:
/*
rcall TIMER;

		ldi  temp, 0b10011000; H
		ldi  rab6, 8;   впихиваем в дисплей 8 бит соответст букве Н
		rcall DISPLAY;
		rcall TIMER;

		ldi  temp, 0b00110100; E
		ldi  rab6, 8;   впихиваем в дисплей 8 бит соответст букве E
		rcall DISPLAY;
		rcall TIMER;
	
		ldi  temp, 0b00111101; L
		ldi  rab6, 8;   впихиваем в дисплей 8 бит соответст букве L
		rcall DISPLAY;
		rcall TIMER;

		ldi  temp, 0b00111101; L
		ldi  rab6, 8;   впихиваем в дисплей 8 бит соответст букве L
		rcall DISPLAY;
		rcall TIMER;

		ldi  temp, 0b00010001; O
		ldi  rab6, 8;   впихиваем в дисплей 8 бит соответст букве O
		rcall DISPLAY;
		rcall TIMER;

		ser  temp;
		ldi  rab6, 8; 
		sec;  
		rcall DISPLAY;
		
			ldi  temp, 0b00000101; Ф/1024
			rcall TIMER+1;
				
		ser  temp;
		ldi  rab6, 8; 
		sec;  
		rcall DISPLAY;
		rcall TIMER;

		ser  temp;
		ldi  rab6, 8; 
		sec;  
		rcall DISPLAY;
		rcall TIMER;

		ser  temp;
		ldi  rab6, 8; 
		sec;  
		rcall DISPLAY;
		rcall TIMER;

  		ser  temp;
		ldi  rab6, 8; 
		sec;  
		rcall DISPLAY;
		rcall TIMER;

		ser  temp;
		ldi  rab6, 8; 
		sec;  
		rcall DISPLAY;
		rcall TIMER;

		ser  temp;
		ldi  rab6, 8; 
		sec;  
		rcall DISPLAY;
		rcall TIMER;

		ser  temp;
		ldi  rab6, 8; 
		sec;  
		rcall DISPLAY;
		rcall TIMER;

		clc;
*/



OPROS_PEREKLUCHATELEY:
;	PB3 - переключ ВЧ/НЧ
;	PB2 - переключ НЧ1/НЧ2  
	in   temp, PINB;
	sbrs temp, 3;  если да - НЧ
		rjmp VCH;
		sbrc temp, 2; если да - НЧ1; 
			rjmp NCH2;
			rjmp NCH1;


	VCH:
;проверка наличия метки
;		in   temp, GPIOR0;
;		clz;      подготовка проверки на 0
;		tst temp; проверка на 0


;установка миетки для умножения числителя на коэфициент деления делителя входной частоты
		clr  temp;
		out  GPIOR0, temp;

		ldi  temp, 0b00110100; E
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b10111110; r
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b10111110; r
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b00011110; 0
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b10111110; r
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11111111;
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11111111;
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11111111;
		ldi  rab6, 8;
		rcall DISPLAY;

		rjmp WAIT_PEREKL;
		
	
	NCH1:
;проверка наличия метки
;		in   temp, GPIOR0;
;		sbrc temp, 0;
;			rjmp WAIT_PEREKL;

;установка миетки для умножения числителя на коэфициент деления делителя входной частоты
		ldi  temp,   0x01;
		out  GPIOR0, temp;

		ldi  temp, 0b11111111; 
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11111110; -
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11011000; 4
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11111111; 
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11111111; 
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11111111;
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11111111;
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b00000001; 0.
		ldi  rab6, 8;
		rcall DISPLAY;

		rjmp WAIT_PEREKL;


	NCH2:
;проверка наличия метки
;		in   temp, GPIOR0;
;		sbrc temp, 1;
;			rjmp WAIT_PEREKL;

;установка миетки для умножения числителя на коэфициент деления делителя входной частоты
		ldi  temp,   0x02;
		out  GPIOR0, temp;

		ldi  temp, 0b11011000; 4
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11111110; -
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b00010100; 6
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b00010001; 0
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11111111; 
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11111111;
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b11111111;
		ldi  rab6, 8;
		rcall DISPLAY;

		ldi  temp, 0b00000001; 0.
		ldi  rab6, 8;
		rcall DISPLAY;

		rjmp WAIT_PEREKL;



;/**********
WAIT_PEREKL:
;ждем входного импульса 0.013 сек, а потом опять идет опрос переключателей




	ldi   temp,   0b01000001; Ф
	out   TCCR1B, temp; активация захвата (захват по переднему фронту) и пуск таймера 

	ldi   temp1,  0b01000000; заготовка для выключения Т/С1 по оконч цикла измерения
	ldi   temp,   0b00000101; Ф/1024
	out   TCCR0B, temp; пуск таймера ожидания сработки прерывания по захвату
	
	ldi   temp,   0b00001000;
	out   TIMSK,  temp; разрешаем прерывание по захвату

	sei;	разрешаем прерывание по захвату

	W_P:
		in    temp,  TIFR;
		sbrs  temp,  1;   проверка наличия переполнения Т/С0
			rjmp W_P;
			
			cli;  запретили прерывание по захвату
	
		clr  temp;
		out  TCCR0B, temp; остановка счетчика Т/С0
		out  TCNT0, temp; сброс регистров счетчика Т/С0
	
		ser  temp;
		out  TIFR, temp;

	rjmp OPROS_PEREKLUCHATELEY;

;*****************/


ST_CCH:
;счетчик Т/С0 работает как таймер ~ 1 сек.
;	cli; запретили прерывание по захвату

	brts CATCH; переход если Т=1	

	set;
	

;определение коэффициента умножения на который следует умножить числитель
	in   temp, PINB;
	sbrs temp, 3;
		rjmp  PC+4;   GPIOR0 -> 00 -> *1000 
	sbrs temp, 2;
		rjmp  PC+5;   GPIOR0 -> 01 -> *10
		rjmp  PC+7;   GPIOR0 -> 10 -> *80

	clr  temp;
	out  GPIOR0, temp;
	rjmp STR;

	ldi  temp, 0x01;
	out  GPIOR0, temp;
	rjmp STR;

	ldi  temp, 0x02;
	out  GPIOR0, temp;
	rjmp STR;


	
	STR:

	clr  temp;
	out  TCCR0B, temp; остановка счетчика Т/С0
	out  TCNT0, temp; сброс регистров счетчика Т/С0
	ldi  temp,  0b00000001; 
	out  GTCCR, temp; сброс прескалеров для Т/С0
	ser  temp;	
	out  TIFR, temp; для сброса флагов
	ldi  rab,  0x4D; 77 переполнений Т/С0 для таймера ~ 1 сек. 

	in   ZaxvL, ICR1L; сохраняем значение регистра захвата при старте 
	in   ZaxvH, ICR1H;

		ldi  temp, 0b00000101;
		out  TCCR0B, temp;

	ldi  temp, 0b10001010;
	out  TIMSK, temp; маска прерываний по захвату и переполнению таймера Т/С0
	sei;
	

WAIT:  
;ждем наличие входного сигнала	
	rjmp  WAIT;

	
	CATCH:
	;количество вошедших импульсов fx (YL; XH; XL)
		sbrc rab,7;
			rjmp  END_OF_MEASUREING; выход из цикла измерения

			clc;
			adiw  XL, 1;
			brcc  PC+3; PC+8; 
			inc   YL;
			clc;

			reti;


	FULL_TC1:
	;количество раз переполнений Т/С1

;		ldi   temp,  0b10000000; 
;		out   TIFR, temp;

		clc;
		adiw  ZL, 1;		
		reti;  


	TIME:
;таймер ~ 1 сек.
		sbrc rab,7;
			rjmp OFF; недождались прихода последнего импульса по захвату. Сброс счета при ложном срабатывании.	
				
		clz;
		dec   rab;
		breq  PC+2; если результат 0, переход на ON_PRERIV
			reti;

			clr   temp;
			out   TCCR0B, temp;
			out   TCNT0,  temp;
			ldi   temp,  0x01;
			out   GTCCR, temp;
			ldi   temp, 0b10001010;
			out   TIMSK, temp;

			ldi   rab, 0b10000000; метка для выходы из цикла измерения

			reti;



;*****************************
OFF:
	out  TCCR1B, temp1; выкл Т/С1	
	out  TCCR0,  temp1; выкл Т/С0
	cli;
	clt;
	clr  temp1;	
	out  TCNT1H, temp1;
	out  TCNT1L, temp1;
	out  TCNT0,  temp1;
	clr  XL;
	clr  XH;
	clr  YL;
	clr  ZL;
	clr  ZH;

	ldi  temp, 0xDF;
	out  SPL,  temp;

		rjmp  WAIT_PEREKL;

;*****************************
END_OF_MEASUREING:

	out  TCCR1B, temp1; выкл Т/С1	
	cli;
	clt;
	clr  temp1;	
	out  TCNT1H, temp1;
	out  TCNT1L, temp1;

;ICR1L -> temp
;ICR1H -> temp1

	in   temp,  ICR1L; сохраненное значение регистра захвата при старте 
	in   temp1, ICR1H;

	clc;
	sub  temp,  ZaxvL;
		mov  ZaxvL, temp;
	sbc  temp1, ZaxvH;
		mov  ZaxvH, temp1;
	sbci ZL, 0;
	sbci ZH, 0;  

	ldi  temp, 0xDF;
	out  SPL,  temp;

;значение числителя находится в YL,XH,XL



/*
;Проверка числителя на нуль
	clz;
	tst  XH;
	brne  BRAIN; переход если не 0 (Z=0)

	tst  XL;
	brne  BRAIN; переход если не 0 (Z=0)

	set; T=1
*/

;*******************************************************

;	brts PC+7;  


BRAIN:
	rcall MATH;
	rcall TRANSLATOR;
	rcall MOVE;
	rcall DIG;
	rcall PASS_ZERO_POINT;
;	rcall DISPLAY;
	rcall CLEAR;
;	rcall TIMER;
	rjmp  WAIT_PEREKL;


;B:  rjmp  B;





;*******************************************************
MATH:

;***умножение числителя на константу коэфициента деления входного делитя частоты
	in   temp, GPIOR0;
	sbrc temp, 0;
	rjmp MULTY_10;
	sbrc temp, 1;
	rjmp MULTY_80;	
	rjmp MULTY_1000; 


	MULTY_10:		
;умножение на 10 
;YL,XH,XL - числитель
	ldi  rab2,  0x00;
	ldi  rab3,  0xC2;
	ldi  rab4,  0xEB;  
	ldi  rab5,  0x0B;

		rjmp CHISLITEL;


	MULTY_80:		
;умножение на 80 
;YH,YL,XH,XL - числитель + используем пустой YH
	ldi  rab2,  0x00;
	ldi  rab3,  0x10;
	ldi  rab4,  0x5E;  
	ldi  rab5,  0x5F;

		rjmp CHISLITEL;


	MULTY_1000:

/*


;умножение на 1000 => X*512+X*256+X*128+X*64+X*32+X*8
;YH,YL,XH,XL - числитель + используем пустой YH
	mov  rab1, XL;
	mov  rab2, XH;
	mov  rab3, YL;
	clr  YH;

;умножение на 8 (3 сдвига)
		clr  rab4;
		ldi  rab, 4;
		clc;
		lsl  XL;
		rol  XH;
		rol  YL;
		rol  YH;
		dec  rab;
		brne PC-6;

;умножение на 32 (5 сдвига)
		clr  rab4;
		ldi  rab, 5;
		clc;
		lsl  rab1;
		rol  rab2;
		rol  rab3;
		rol  rab4;
		dec  rab;
		brne PC-6;

		add  XL, rab1;
		adc  XH, rab2;
		adc  YL, rab3;
		adc  YH, rab4;

		inc  rab;
		cpi  rab, 9;
		brne PC-13;  если Z=0 то переход
		 
			rjmp CHISLITEL;

*/








;fx=(fclk*(YL,XH,XL))/(ZH,ZL,ZaxvH,ZaxvL)

;Проверка
;fx=(fclk*(XL,XH,YL))/(ZH,ZL,ICR1H,ICR1L)  при fx = 31250

/*
;Проверка к вычислениям
	subi  XL, 1; 
	sbci  XH, 0;	
*/

		/*
		;*******************
		;Числитель на дисплей
			clc;
			mov  Rez1, XL;
			mov  Rez2, XH;
			mov  Rez3, YL;
			clr  YH;
			ret;
		;*******************
		*/
	CHISLITEL:
;		/*
		;*******************
		;Знаминатель на дисплей
			clc;
			in   temp,  ICR1L;
			in   temp1, ICR1H;
			mov  Rez1, temp;
			mov  Rez2, temp1;
			mov  Rez3, ZL;
			mov  Rez4, ZH;
			ret;
		;*******************
;		*/


		
;	CHISLITEL:
		
	clc;
;	mov  temp,  XL;
;	mov  temp1, XH;
;	mov  rab,   YL;
	clr  YH;
	clr  rab1;


		/*
		;********************
			ldi  temp,  0x84;
			ldi  temp1, 0x80;
			ldi  rab,   0x00;
		;********************
		*/

;fclk = 16000000 => F42400
;fclk = 20000000 => 01312D00


/*
	ldi  rab2,  0x00;
	ldi  rab3,  0x2D;
	ldi  rab4,  0x31;  
	ldi  rab5,  0x01;
*/


	ldi  rab6,  32;

MULTIPLY:
;32*32
		clc;
		lsr  YH; rab1;
		ror  YL; rab;
		ror  XH; temp1;
		ror  XL; temp;
	MULTI:
		brcc NOAD32;
		add  Rez1,  rab2;
		adc  Rez2,  rab3;
		adc  Rez3,  rab4;
		adc  Rez4,  rab5;
	
	NOAD32:
		ror  Rez4;
		ror  Rez3;
		ror  Rez2;
		ror  Rez1;
		ror  YH;  rab1;
		ror  YL; rab;
		ror  XH; temp1;
		ror  XL; temp;

		dec  rab6;
		brne MULTI;

DIVIDE:
		ldi  rab6, 64;
;Делимое/результат	
		mov  Rez8, Rez4;
		mov  Rez7, Rez3;
		mov  Rez6, Rez2;
		mov  Rez5, Rez1;
		mov  Rez4, YH;  rab1;
		mov  Rez3, YL; rab;
		mov  Rez2, XH; temp1;
		mov  Rez1, XL; temp;

;Делитель ZH,ZL,ZaxvH,ZaxvL      
;		in   temp,  ICR1L;
;		in   temp1, ICR1H;
;			mov  temp,  YL;
;			mov  temp1, YH;

		mov  rab,   ZL;
		mov  rab1,  ZH;
		clr  rab2;
		clr  rab3;
		clr  rab4;
		clr  rab5;

		/*
		;*******************
			ldi  temp, 0xFF;
			ldi  temp1,0xFF;
			ldi  rab,  0x00;
			ldi  rab1, 0x01; 	
		;*******************
		*/

;Разница
		clr  XL;
		clr  XH;
		clr  YL;
		clr  YH;
		clr  ZL;
		clr  ZH;
		clr  Razn;
		clr  Razn1;
		

		sub  Razn1, Razn1;
	DIV:
		rol  Rez1;
		rol  Rez2;
		rol  Rez3;
		rol  Rez4;
		rol  Rez5;
		rol  Rez6;
		rol  Rez7;
		rol  Rez8;

		rol  XL;
		rol  XH;
		rol  YL;
		rol  YH;
		rol  ZL;
		rol  ZH;
		rol  Razn;
		rol  Razn1;

		sub  XL, ZaxvL; temp;
		sbc  XH, ZaxvH; temp1;
		sbc  YL, rab;
		sbc  YH, rab1;
		sbc  ZL, rab2;
		sbc  ZH, rab3;
		sbc  Razn, rab4;
		sbc  Razn1, rab5;

		brcc D32_1;
		add  XL, ZaxvL; temp;
		adc  XH, ZaxvH; temp1;
		adc  YL, rab;
		adc  YH, rab1;
		adc  ZL, rab2;
		adc  ZH, rab3;
		adc  Razn, rab4;
		adc  Razn1, rab5;
		clc;
		rjmp DV;

	D32_1:  sec;

	DV:
		dec  rab6;
		brne DIV;

		rol  Rez1;
		rol  Rez2;
		rol  Rez3;
		rol  Rez4;
		rol  Rez5;
		rol  Rez6;
		rol  Rez7;
		rol  Rez8;
;результат в Rez1 Rez2 Rez3 Rez4
		ret;

;*******************************************************
TRANSLATOR:
; подпрограмма перевода 16-ричного числа в десятичное шестиразрядное 

	rcall DIV10;
	mov   Rez5, temp;
	rcall DIV10;
	swap  temp;
	or    Rez5, temp;
	rcall DIV10;
	mov   Rez6, temp;
	rcall DIV10;
	swap  temp;
	or    Rez6, temp;
	rcall DIV10;
	mov   Rez7, temp;
	rcall DIV10;
	swap  temp;
	or    Rez7, temp;
	rcall DIV10;
	mov   Rez8, temp;
	rcall DIV10;
	swap  temp;
	or    Rez8, temp;

	ret;

	DIV10:
		clr  temp;
	
		lsl  Rez1;
		rol  Rez2;
		rol  Rez3;
		rol  Rez4;
		rol  temp;
	
		lsl  Rez1;
		rol  Rez2;
		rol  Rez3;
		rol  Rez4;
		rol  temp;
		
		lsl  Rez1;
		rol  Rez2;
		rol  Rez3;
		rol  Rez4;
		rol  temp;
	
		ldi  rab6, 29; для оставшихся 29 разрядов

		
	LOOP10:
		lsl  Rez1;
		rol  Rez2;
		rol  Rez3;
		rol  Rez4;
		rol  temp;
		subi temp, 10;
		brlo HB1;
		inc  Rez1;
		rjmp HB2;
		
	HB1:
		subi temp, -10;
		
	HB2:
		dec	 rab6;
		brne LOOP10;
		ret;

;**********************************************************
MOVE:
/*
;сохранение текущего значения частоты в GPIOR1 для дальнейшего его сравнения со следующим значением
*/

	mov  rab1, Rez5;
	mov  rab2, Rez6;
	mov  rab3, Rez7;
	mov  rab4, Rez8;

	ldi  temp1, 0b00001111;

	mov  temp, rab1;
	and  temp, temp1;
	mov  Rez1, temp;
	swap rab1;
	and  rab1, temp1;
	mov  Rez2, rab1;    
	
	mov  temp, rab2;
	and  temp, temp1;
	mov  Rez3, temp;
	swap rab2;
	and  rab2, temp1;
	mov  Rez4, rab2;

	mov  temp, rab3;
	and  temp, temp1;
	mov  Rez5, temp;
	swap rab3;
	and  rab3, temp1;
	mov  Rez6, rab3;

	mov  temp, rab4;
	and  temp, temp1;
	mov  Rez7, temp;
	swap rab4;
	and  rab4, temp1;
	mov  Rez8, rab4;  

	ret;

/********** Подпрограмма перевода двоично-десятичного кода
	 в код семисегментного индикатора *******************/
DIG:
	push  ZL;
	push  ZH;
	clr  temp;
			
        sts Digit,   Rez1;  загрузка начальных значений    
        sts Digit+1, Rez2;        
        sts Digit+2, Rez3;
        sts Digit+3, Rez4;
		sts Digit+4, Rez5;
		sts Digit+5, Rez6;
		sts Digit+6, Rez7;
		sts Digit+7, Rez8;

		lds temp,  Digit;
		rcall  DcMatrix;
        mov Rez1, temp;
		lds temp,  Digit+1;
		rcall  DcMatrix;
		mov Rez2, temp;		
		lds temp,  Digit+2;
		rcall  DcMatrix;
		mov Rez3, temp;
		lds temp,  Digit+3;
		rcall  DcMatrix;
		mov Rez4, temp;
		lds temp,  Digit+4;
		rcall  DcMatrix;
		mov Rez5, temp;
		lds temp,  Digit+5;
		rcall  DcMatrix;	
		mov Rez6, temp;
		lds temp,  Digit+6;
		rcall  DcMatrix;	
		mov Rez7, temp;
		lds temp,  Digit+7;
		rcall  DcMatrix;	
		mov Rez8, temp;
	
	pop  ZH;
	pop  ZL;
	
	ret; выход наверх

DcMatrix:
	 		ldi ZL, Low(Matrix*2); инициализация массива
            ldi ZH, High(Matrix*2);

            clr temp1;             прибавление переменной
            add ZL,temp;           к 0-му адресу массива
            adc ZH,temp1;
			lpm;                   загрузка значения в R0
            mov temp,R0;
            ret;
Matrix:
 
 				;   dechabfg   dechabfg
              .db 0b00010001,0b11011011	;0,1
              .db 0b00110010,0b01010010	;2,3
              .db 0b11011000,0b01010100	;4,5             
			  .db 0b00010100,0b11010011 ;6,7
              .db 0b00010000,0b01010000	;8,9

;***********************************************************

PASS_ZERO_POINT:
; Убираем пассивные нули и ставим тысячные точки

	mov  temp, Rez8;
	cpi  temp, 0x11;
	brne PC+3;
		ser  temp;
		mov  Rez8, temp;

	mov  temp, Rez7;
	cpi  temp, 0x11;
	brne PC+3;
		ser  temp;
		mov  Rez7, temp;
	andi temp, 0b11101111; ставим тысячные точки
	mov  Rez7, temp;

	mov  temp, Rez6;
	cpi  temp, 0x11;
	brne PC+3;
		ser  temp;
		mov  Rez6, temp;

	mov  temp, Rez5;
	cpi  temp, 0x11;
	brne PC+3;
		ser  temp;
		mov  Rez5, temp;

	mov  temp, Rez4;
	cpi  temp, 0x11;
	brne PC+3;
		ser  temp;
		mov  Rez4, temp;
	andi temp, 0b11101111; ставим тысячные точки
	mov  Rez4, temp;

		mov  temp, Rez3;
	cpi  temp, 0x11;
	brne PC+3;
		ser  temp;
		mov  Rez3, temp;

	mov  temp, Rez2;
	cpi  temp, 0x11;
	brne PC+3;
		ser  temp;
		mov  Rez2, temp;

	mov  temp, Rez1;
	cpi  temp, 0x11;
	brne PC+3;
		ser  temp;
		mov  Rez1, temp;
		rjmp PC+3; ставим 0. приотсутствии входного сигнала
	andi temp, 0b11101111; ставим тысячные точки
	mov  Rez4, temp;

;	ret;

		mov temp, Rez8;
		ldi rab6, 8;
		rcall DISPLAY;

		mov temp, Rez7;
		ldi rab6, 8;
		rcall DISPLAY;

		mov temp, Rez6;
		ldi rab6, 8;
		rcall DISPLAY;

		mov temp, Rez5;
		ldi rab6, 8;
		rcall DISPLAY;

		mov temp, Rez4;
		ldi rab6, 8;
		rcall DISPLAY;

		mov temp, Rez3;
		ldi rab6, 8;
		rcall DISPLAY;

		mov temp, Rez2;
		ldi rab6, 8;
		rcall DISPLAY;

		mov temp, Rez1;
		ldi rab6, 8;
		rcall DISPLAY;

	ret;

;***********************************************************
DISPLAY:
;PB6 - data; PB7 - clock
/*
	ldi  rab6, 64;
*/	
	DIS:
;двигаем справа налево - первым выводится самый старший информацион разряд
/*
	lsl  Rez1; старший инфо разряд
	rol  Rez2;
	rol  Rez3;
	rol  Rez4;
	rol  Rez5;
	rol  Rez6;
	rol  Rez7;
	rol  Rez8; младший инфо разряд
*/
	
	rol  temp;

	brcs  SET_ONE;  выставляем 1 на выводе
	rcall CLOCK;    на выводе 0 стоит по умолчанию
	
	DIS_COUNT:
	dec  rab6;
	brne DIS;   переход на DIS если rab6 не равно 0
	ret;   выход наверх
	
	SET_ONE:  
	sbi  PORTB, 6;
	nop;
	nop;
	nop;
	nop;
	rcall CLOCK;
	cbi  PORTB, 6;
	nop;
	nop;
	nop;
	rjmp DIS_COUNT;

	CLOCK:
	sbi  PORTB, 7;
	nop;
	nop;
	nop;
	cbi  PORTB, 7;
	nop;
	nop;
	nop;
	ret;
	
;**************************************************************
CLEAR:
	clr  temp;
;	out  TCNT1L, temp;
;	out  TCNT1H, temp;

;	out  ICR1L, temp;
;	out  ICR1H, temp;

	clr  temp1;
;	out  TCCR0B, temp1;
;	out  TCNT0,  temp1;
	clr  rab;
	clr  rab1;
	clr  rab2;
	clr  rab3;
	clr  rab4;
	clr  rab5;
	clr  rab6;
	clr  XL;
	clr  XH;
	clr  YL;
	clr  YH;
	clr  ZL;
	clr  ZH;

	clr  Rez1;
	clr  Rez2;
	clr  Rez3;
	clr  Rez4;
	clr  Rez5;
	clr  Rez6;
	clr  Rez7;
	clr  Rez8;
	clr  Razn;
	clr  Razn1;
	clr  R0;
	
	ret;
	
;**************************************************
TIMER:
	ldi  temp, 0b00000011; Ф/64       b00000011; Ф/64
	out  TCCR1B, temp;
	in   temp, TIFR;
	sbrs temp, 7;
	rjmp PC-2;

	clr  temp;
	out  TCCR1B, temp;
	ser  temp;
	out  TIFR, temp;

	ret;
