;C_ESR_Meter
;Версия 1.1.1
;Отключен USART, автовыключение, индикация разряда батареи
;Автор: Келехсашвили В.А.
;Версия программы для внешних прерываний по отрицательному уровню.
;Связь с LCD на основе временных задержек.
;Переключение на верхний диапазон только по переполнению счётчика таймера.
;Выход из цикла ожидания по прерыванию по U2.
;Частота 12МГц.
;Формирование задержек без использования стека.
;Отсчёт до 262144 на одном пределе.
;LCD нерусифицированный 0802 или 1602.
;Для согласования с LCD на HD44780U увеличина длительность задержки между передачей
;второй комманды в подпрограмма отправки команды на LCD (lcd_out)

.include	"tn2313def.inc"	;Присоединение файла описания

.list						;Включение листинга

.def	sotye 		= R0	;Число сотых долей (1)
.def	desyatye 	= R1	;Число десятых долей (2)
.def	edinicy 	= R2	;Число единиц (3)
.def	desyatki 	= R3	;Число десятков (4)
.def	sotni 		= R4	;Число сотен тысяч (5)
.def	tyshi 		= R5	;Число тысяч (6)
.def	des_tysh	= R6	;Число десятков тысяч (7)
.def	a1 = R7				;1-й байт переменной a (младший байт)
.def	a2 = R8				;2-й байт переменной a
.def	a3 = R9				;3-й байт переменной a
.def	b1 = R10			;1-й байт переменной b (младший байт)
.def	b2 = R11			;2-й байт переменной b
.def	b3 = R12			;3-й байт переменной b
.def	c1 = R13			;1-й байт переменной c (младший байт)
.def	c2 = R14			;2-й байт переменной c
.def	c3 = R15			;3-й байт переменной c
;--------------------------------------------------------
.def	c4 = R16			;4-й байт переменной c
.def	temp 	= R17		;Определение главного рабочего регистра
.def	temp2 	= R18		;Определение второго рабочего регистра
.def	lcd	= R19			;Определение регистра для обращения к LCD
.def	z1 	= R20			;1-й байт переменной z (младший байт)
.def	z2 	= R21			;2-й байт переменной z
.def	z3 	= R22			;3-й байт переменной z
.def	z4 	= R23			;4-й байт переменной z
.def	k_del	= R24		;Регистр поправки коеффициента деления таймера
.def	tok_zar	= R25		;Регистр величины тока заряда
;.def	autoff	= R28		;Регистр счётчика автовыключения (он же YL)
;.def	autoff2	= R29		;Регистр предела измерения в Фарадах (он же YH)

;--------------------------------------------------------
.equ	const1b = 15619		;Константа перевода результата в ёмкость для большего тока (32768)
.equ	const1m = 14717		;Константа перевода результата в ёмкость для малого тока (524288)
.equ	const2 = 2064		;Константа 100*U1/Ib
.equ	const3 = 3812		;Константа 100*U2/Ib
;.equ	const4 = 77		;Константа для задания скорости USART (9600 бит/с)

.equ	ESRmax=2001			;Порог максимального значения ESR (20,00 Ом)
.equ	porog1 = 32700		;Порог переключения на младший предел (по U2)
.equ	porog2 = 15001		;Порог переключения на малый ток (150 мкФ)
.equ	porog3 = 2001		;Порог переключения предела на малом токе (20 мкФ)
.equ	d20m = 39321		;Значение длительности паузы (~20мс при 20МГц) (тактов-9)/6
.equ	d3m = 5999			;Значение длительности паузы (~3мс при 20МГц) (тактов-9)/6
.equ	d40u = 141			;Значение длительности паузы (~40мкс при 20МГц) (тактов-4)/3
.equ	d1u	=	4			;Значение длительности паузы (~1мкс при 20МГц) (тактов-4)/3
.equ	RS = 2				;
.equ	E = 3				;

;------------------------Резервирование ячеек памяти EEPROM

.eseg
.org	0x08			;установка текущего адреса сегмента

n1_1b:
.byte	1				;Ячейка EEPROM для 1-го байта поправки для n1

n1_2b:
.byte	2				;Ячейка EEPROM для 2-го байта поправки для n1

n2_1b:
.byte	3				;Ячейка EEPROM для 1-го байта поправки для n2

n2_2b:
.byte	4				;Ячейка EEPROM для 2-го байта поправки для n2

n2_n1_1b:
.byte	5				;Ячейка EEPROM для 1-го байта поправки для (n2-n1)

n2_n1_2b:
.byte	6				;Ячейка EEPROM для 2-го байта поправки для (n2-n1)

flag:
.byte	7				;Ячейка EEPROM для записи флага расчёта поправки

;------------------------Начало программного кода

.cseg
.org	0				;установка текущего адреса на ноль

;------------------------Переопределение векторов прерываний

start:	rjmp	init	;Переход на начало программы
		rjmp	com_U1	;Внешнее прерывание 0
		rjmp	com_U2	;Внешнее прерывание 1
		reti			;Таймер/счётчик 1, захват
		reti			;Таймер/счётчик 1, совпадение, канал А
		rjmp	ovtim1	;Таймер/счётчик 1, прерывание по переполнению
		reti			;Таймер/счётчик 0, прерывание по переполнению
		reti			;Прерывание USART приём завершён
		reti			;Прерывание USART регистр данных пуст
		reti			;Прерывание USART передача завершена
		reti			;Прерывание по компаратору
		reti			;Прерывание по изменению на любом контакте
		reti			;Таймер/счётчик 1, совпадение, канал В
		reti			;Таймер/счётчик 0, совпадение, канал В
		reti			;Таймер/счётчик 0, совпадение, канал А
		reti			;USI готовность к старту
		reti			;USI переполнение
		reti			;EEPROM готовность
		reti			;Переполнение охранного таймера

;-----------------------Модуль инициализации
init:
;-----------------------Инициализация стека

ldi	temp, RAMEND		;Выбор адреса внешнего стека
out	SPL, temp			;Запись его в регистр стека

;-----------------------Инициализация USART

;cli							;Глобально запрещаем прерывания
;ldi		temp, high(const4)	;Старший полубайт константы в temp
;out		UBRRH, temp			;Запись в регистр скорости обмена USART старшего полубайта
;ldi		temp, low(const4)	;Младший полубайт константы в temp
;out		UBRRL, temp			;Запись в регистр скорости обмена USART младшего полубайта
;ldi		temp, 0b00000000	;Установка одинарной скорости обмена
;out		UCSRA, temp			;
;ldi		temp, 0b00001000	;Разрешение передачи, запрет прерываний
;out		UCSRB, temp			;
;ldi		temp, 0b00000110	;Настройка режима работы USART (8-бит, асинхр., без контроля чётности)
;out		UCSRC, temp			;

;-----------------------Инициализация портов ВВ

ldi		temp,0b00000100	;PA2 на вывод, PA0, PA1 на ввод
out		DDRA,temp		;
ldi		temp,0b00000100	;Устанавливаем PA2, отключаем резисторы на PA0, PA1
out		PORTA,temp		;

ldi		temp,0b11111101	;PB0, PB2...PB7 на вывод, PB1 на ввод
out		DDRB,temp		;
ldi		temp,0b00000000	;Обнуляем PB1...PB7, устанавливаем PB1 и включаем резистор на PB0
out		PORTB,temp		;

ldi		temp,0b00110011	;PD0, PD1, PD4...PD5 на вывод, PD2, PD3, PD6 на ввод
out		DDRD,temp		;
ldi		temp,0b01111111	;Устанавливаем PD0, PD1, PD4...PD5 и включаем резисторы PD2, PD3, PD6
out		PORTD,temp		;

;-----------------------Инициализация таймера Т1

ldi		temp,0b00000000	;Останов таймера, нормальный режим
out		TCCR1B,temp		;

;-----------------------Инициализация компаратора

ldi		temp,0b01110000	;Настройка компаратора
out		ACSR,temp		;

;-----------------------Определение масок прерываний 

ldi		temp,0b00000000	;Выбор режима вызова внешних прерываний PD2 (U1) и PD3 (U2)
out		MCUCR,temp		;

ldi		temp,0b00000000	;Запрет прерываний по таймеру 1
out		TIMSK,temp

ldi		temp,0b00000000	;Запрет внешних прерываний
out		GIMSK,temp		;

;-----------------------Инициализация LCD (KS0066)

lcd_init:
rcall	del20m			;Вызов подпрограммы задержки (~20мс)
rcall	del20m			;Вызов подпрограммы задержки (~20мс)
rcall	del20m			;Вызов подпрограммы задержки (~20мс)

						;Команда 0010
sbi		PORTB,E			;Строб вверх
ldi		temp,0b00101000	;Команда (строб вверх + команда)
out		PORTB,temp		;Запись команды в порт
rcall	del1u			;Вызов подпрограммы задержки (~1мкс)
cbi		PORTB,E			;Строб вниз
rcall	del40u			;Вызов подпрограммы задержки (~40мкс)

ldi		lcd,0b00101000	;Команды 0010 и 1000
rcall	lcd_com			;Вызов подпрограммы отправки команды на LCD

ldi		lcd,0b00001000	;Команды 0000 и 1000
rcall	lcd_com			;Вызов подпрограммы отправки команды на LCD

ldi		lcd,0b00000001	;Команды 0000 и 0001
rcall	lcd_com			;Вызов подпрограммы отправки команды на LCD

rcall	del3m			;Вызов подпрограммы задержки (~3мс)

ldi		lcd,0b00000110	;Команды 0000 и 0110
rcall	lcd_com			;Вызов подпрограммы отправки команды на LCD

;-----------------------Начало основной программы

cli						;Глобально запрещаем прерывания
clr		k_del			;Очистка k_del
clr		tok_zar			;Очистка tok_zar
;clr		autoff			;Очистка autoff
;clr		autoff2			;Очистка autoff2
ldi		lcd,0b00001100	;Включение дисплея и выбор курсора
rcall	lcd_com			;

;-----------------------Отображение приветствия

ldi		ZL,low(Prvt*2)	;Запись в ZL младшего байта адреса ячейки из таблицы Prvt (альтернативная адресация)
ldi		ZH,high(Prvt*2)	;Запись в ZH старшего байта адреса ячейки из таблицы Prvt (альтернативная адресация)
rcall	lcd_all			;Вызов подпрограммы отображения двух строк на LCD по данным из таблиц

rcall	del300m			;Вызов подпрограммы задержки (~300мс)
rcall	del300m			;Вызов подпрограммы задержки (~300мс)
rcall	del300m			;Вызов подпрограммы задержки (~300мс)
rcall	del300m			;Вызов подпрограммы задержки (~300мс)
rcall	del300m			;Вызов подпрограммы задержки (~300мс)

main:
clr		c3				;Очистка c3 (очистка 3-го байта счётчика таймера)
sbi		PORTD,0			;Выключение большого тока заряда конденсатора
sbi		PORTD,4			;Выключение малого тока заряда конденсатора
sbi		PORTD,5			;Включение разряда конденсатора
clr		temp			;Обнуляем счётный регистр таймера 1
out		TCNT1H,temp		;
out		TCNT1L,temp		;

;-----------------------Автовыключение и контроль за напряжением питания

;autoff_check:
;cpi		autoff,255		;Сравнение autoff с 255 (~4'35")
;breq	autoff_check1	;Если autoff=255, то на autoff_check1, иначе далее

;cpi		k_del,4			;Сравнение k_del с 4
;brlo	autoff_check00	;Если k_del<4, то на autoff_check00, иначе далее

;cpi		autoff2,10		;Сравнение autoff2 с 10 (~2'17")
;brlo	bat_check1		;Если autoff2<10, то на bat_check1, иначе далее
;rjmp	autoff_check1	;На autoff_check1

;autoff_check00:
;cpi		k_del,3			;Сравнение k_del с 3
;brlo	autoff_check0	;Если k_del<3, то на autoff_check0, иначе далее

;cpi		autoff2,31		;Сравнение autoff2 с 31 (~2'22")
;brlo	bat_check1		;Если autoff2<31, то на bat_check1, иначе далее
;rjmp	autoff_check1	;На autoff_check1

;autoff_check0:
;cpi		autoff2,100		;Сравнение autoff2 с 100 (~2'17")
;brlo	bat_check1		;Если autoff2<100, то на bat_check1, иначе далее

;autoff_check1:
;-----------------------Выключение прибора

;ldi		temp,0b01110000	;Разрешение перехода в режим Power-Down
;out		MCUCR,temp		;
;sbi		PORTB,0			;Выключение питания
;sleep					;Переход в режим Power-Down

;bat_check1:
;clr		z1				;Очистка z1
;clr		z2				;Очистка z2
;ldi		temp,55			;Запись 55 в temp

;bat_check2:
;rcall	del20m			;Вызов подпрограммы задержки (~20мс)
;dec		temp			;Уменьшение temp на 1
;sbis	ACSR,ACO		;Если на выходе компаратора 1, то пропуск след. команды, иначе далее
;rjmp	bat_check3		;На bat_check3
;inc		z1				;Увеличение z1 на 1
;rjmp	bat_check4		;На bat_check4

;bat_check3:
;inc		z2				;Увеличение z2 на 1

;bat_check4:
;cpi		temp,0			;Сравнение temp с 0
;brne	bat_check2		;Если temp<>0, то на bat_check2, иначе далее

;cp		z1,z2			;Сравнение z1 с z2
;brlo	pusk_0			;Если z1<z2, то на pusk_0, иначе далее

;ldi		ZL,low(Bat*2)	;Запись в ZL младшего байта адреса ячейки из таблицы Bat (альтернативная адресация)
;ldi		ZH,high(Bat*2)	;Запись в ZH старшего байта адреса ячейки из таблицы Bat (альтернативная адресация)
;rcall	lcd_all			;Вызов подпрограммы отображения двух строк на LCD по данным из таблиц
;inc		autoff2			;Увеличение autoff2 на 1

;-----------------------Передача сообщения о разряде батареи

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

;ldi		temp,0xD6		;Запись 0xD6 в temp
;out		UDR,temp		;Передача из temp в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

;-----------------------Формирование паузы для отображения сообщения о замене батареи (~0,3с при 20МГц)

rcall	del300m			;Вызов подпрограммы задержки (~300мс)

;cpi		k_del,2			;Сравнение k_del с 2
;brsh	pusk_0			;Есл k_del>=2, то на pusk_0, иначе далее

;ldi		ZL,low(Gdit*2)	;Запись в ZL младшего байта адреса ячейки из таблицы Gdit (альтернативная адресация)
;ldi		ZH,high(Gdit*2)	;Запись в ZH старшего байта адреса ячейки из таблицы Gdit (альтернативная адресация)
;ldi		temp,1			;Отображение 1-й строки
;rcall	lcd_mess		;Вызов подпрограммы отображения сообщений

;ldi		ZL,low(Gdit*2)	;Запись в ZL младшего байта адреса ячейки из таблицы Gdit (альтернативная адресация)
;ldi		ZH,high(Gdit*2)	;Запись в ZH старшего байта адреса ячейки из таблицы Gdit (альтернативная адресация)
;ldi		temp,2			;Отображение 2-й строки
;rcall	lcd_mess		;Вызов подпрограммы отображения сообщений

;pusk_0:
;-----------------------Передача сообщения о пределе измерения

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

;ldi		temp,0xC0		;Запись 0xC0 в temp
;or		temp,k_del		;Логическое сложение k_del с temp, результат в temp
;out		UDR,temp		;Передача из temp в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

pusk:
ldi		temp,0b01000000	;Разрешение внешнего прерывания только по PD2 (U1)
out		GIMSK,temp		;

ldi		temp,0b10000000	;Разрешение прерывания только по переполнению таймера 1
out		TIMSK,temp		;

cbi		PORTD,5			;Выключение разряда конденсатора

rcall	del1u			;Вызов подпрограммы задержки (~1мкс), подождём немного закрытия MOSFET

sei						;Глобально разрешаем прерывания

cpi		tok_zar,1		;Сравнение tok_zar с 1
breq	m_tok			;Если tok_zar=1, то на m_tok, иначе далее

;-----------------------Измерение на большом токе заряда

b_tok:
ldi		temp,0b00000001	;Пуск таймера (clk/1)
add		temp,k_del		;с коррекцией коеффициента деления таймера
cbi		PORTD,0			;Включение заряда конденсатора
out		TCCR1B,temp		;
rjmp	cikl			;На cikl

;-----------------------Измерение на малом токе заряда

m_tok:
ldi		temp,0b00000001	;Пуск таймера (clk/1)
add		temp,k_del		;с коррекцией коеффициента деления таймера
cbi		PORTD,4			;Включение заряда конденсатора
out		TCCR1B,temp		;

cikl:
rjmp	cikl			;Зацикливаем

;-----------------------Уменьшение предела измерения (увеличение частоты таймера)

clk_up:
cpi		k_del,0			;Сравнение k_del с 0
breq	clk_no_ch		;Если k_del=0, то на clk_no_ch, иначе далее
dec		k_del			;Уменьшение поправки на 1 (уменьшение коэффициента деления)
rjmp	clk_pred		;На clk_pred

;-----------------------Увеличение предела измерения (уменьшение частоты таймера)

clk_down:
clr		tok_zar			;Очистка k_del
cpi		k_del,4			;Сравнение k_del с 4.
brlo	clk_down_0		;Если k_del<4, то на clk_down_0, иначе далее
rjmp	step3			;Иначе на step3 (отображение сообщения о КЗ)

clk_down_0:
inc		k_del			;Увеличение поправки на 1 (увеличение коэффициента деления)

clk_pred:
ldi		ZL,low(Pred*2)	;Запись в ZL младшего байта адреса ячейки из таблицы Pred (альтернативная адресация)
ldi		ZH,high(Pred*2)	;Запись в ZH старшего байта адреса ячейки из таблицы Pred (альтернативная адресация)
rcall	lcd_all			;Вызов подпрограммы отображения двух строк на LCD по данным из таблиц
rcall	pred_num		;Вызов подпрограммы отображения номера предела
;clr		autoff			;Очистка autoff

;-----------------------Передача сообщения "ждите..."

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

;ldi		temp,0xD4		;Запись 0xD4 в temp
;out		UDR,temp		;Передача из temp в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

clk_no_ch:
rjmp	main			;На main

;-----------------------Проверка нижнего порога (porog1)
;Если значение счётчика больше или равно porog1, то на внесение поправок (на step4),
;Если значение счётчика меньше porog1, то на проверку частоты таймера (далее на step2)

step1:
ldi		z1,low(porog1)	;Заносим младший байт porog1 в z1
ldi		z2,high(porog1)	;Заносим старший байт porog1 в z2
ldi		z3,0			;Заносим 0 в z3
cp		b1,z1			;Сравнение b2+b1 с z2+z1 с учётом переноса
cpc		b2,z2			;
cpc		b3,z3			;
brsh	step4			;Если b3+b2+b1 больше или равно z3+z2+z1, то на step4, иначе далее (на step2)

;-----------------------Проверка частоты таймера
;Если k_del=0 (clk/1), то на внесение поправок (на step4), если k_del<>0,
;то на  уменьшение предела измерения (на clk_up)

step2:
cpi		k_del,0			;Сравнение k_del с 0
breq	step4			;Если k_del=0, то на внесение поправок (на step4)
rjmp	clk_up			;Иначе на уменьшение предела измерения (на clk_up)

;-----------------------Отображение сообщения о КЗ при превышении ожидания

step3:
ldi		ZL,low(KZ_Cmx*2)	;Запись в ZL младшего байта адреса ячейки из таблицы KZ_Cmx (альтернативная адресация)
ldi		ZH,high(KZ_Cmx*2)	;Запись в ZH старшего байта адреса ячейки из таблицы KZ_Cmx (альтернативная адресация)
rcall	lcd_all				;Вызов подпрограммы отображения двух строк подряд на LCD по данным из таблиц
;ldi		temp,85				;Допустимые значения 1, 3, 5, 15, 17, 51, 85, 255 (при 85 около 50 сек)
;add		autoff,temp

;-----------------------Передача сообщений "Cx > max" и "ESR < min"

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

;ldi		temp,0xD0		;Запись 0xD0 в temp
;out		UDR,temp		;Передача из temp в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

rjmp	main			;На main

;-----------------------Внесение поправок на задержки

step4:
cpi		tok_zar,1		;Сравнение tok_zar с 1
breq	step6_0			;Если tok_zar=1, то на step6_0, иначе далее

;-----------------------Чтение из EEPROM

ldi		temp2,flag		;Записывает в temp2 адрес читаемой ячейки EEPROM
rcall	EEPROM_read		;Вызов подпрограммы чтения ячейки EEPROM

cpi		temp2,100		;Сравнение temp2 с 100
breq	step5			;Если temp2=100, то на step5, иначе далее
rjmp	step6			;На step6

step5:
ldi		temp2,n1_1b		;Записываем в temp2 адрес читаемой ячейки EEPROM
rcall	EEPROM_read		;Вызов подпрограммы чтения ячейки EEPROM
mov		z1,temp2		;Копируем прочитанный байт из temp2 в z1

ldi		temp2,n1_2b		;Записываем в temp2 адрес читаемой ячейки EEPROM
rcall	EEPROM_read		;Вызов подпрограммы чтения ячейки EEPROM
mov		z2,temp2		;Копируем прочитанный байт из temp2 в z2

rcall	predel			;Вызов подпрограммы predel

sub		a1,z1			;Вычитание z1 из a1
sbc		a2,z2			;Вычитание z2 из a2 с учётом переноса
sbc		a3,temp2		;Вычитание temp2 из a3 с учётом переноса

ldi		temp2,n2_1b		;Записываем в temp2 адрес читаемой ячейки EEPROM
rcall	EEPROM_read		;Вызов подпрограммы чтения ячейки EEPROM
mov		z1,temp2		;Копируем прочитанный байт из temp2 в z1

ldi		temp2,n2_2b		;Записываем в temp2 адрес читаемой ячейки EEPROM
rcall	EEPROM_read		;Вызов подпрограммы чтения ячейки EEPROM
mov		z2,temp2		;Копируем прочитанный байт из temp2 в z2

rcall	predel			;Вызов подпрограммы predel

sub		b1,z1			;Вычитание z1 из b1
sbc		b2,z2			;Вычитание z2 из b2 с учётом переноса
sbc		b3,temp2		;Вычитание temp2 из b3 с учётом переноса

ldi		temp2,n2_n1_1b	;Записываем в temp2 адрес читаемой ячейки EEPROM
rcall	EEPROM_read		;Вызов подпрограммы чтения ячейки EEPROM
mov		z1,temp2		;Копируем прочитанный байт из temp2 в z1

ldi		temp2,n2_n1_2b	;Записываем в temp2 адрес читаемой ячейки EEPROM
rcall	EEPROM_read		;Вызов подпрограммы чтения ячейки EEPROM
mov		z2,temp2		;Копируем прочитанный байт из temp2 в z2

rcall	predel			;Вызов подпрограммы predel

sub		c1,z1			;Вычитание z1 из c1
sbc		c2,z2			;Вычитание z2 из c2 с учётом переноса
sbc		c3,temp2		;Вычитание temp2 из c3 с учётом переноса

;-----------------------Расчёт и отображение

step6:

push	c1				;Сохранение c1 в стеке (сохранение n2-n1)
push	c2				;Сохранение c2 в стеке
push	c3				;Сохранение c3 в стеке

push	a1				;Сохранение a1 в стеке (сохранение n1)
push	a2				;Сохранение a2 в стеке
push	a3				;Сохранение a3 в стеке
rjmp	step6_1			;На step6_1

step6_0:

;-----------------------Умножение (c3+c2+c1)*(XH+XL)=(c4+c3+c2+c1) или (n2-n1)*const1b

ldi		XL,low(const1m)		;Запись младшего байта const1m в XL
ldi		XH,high(const1m)	;Запись старшего байта const1m в XH
rjmp	step6_2				;На step6_2

step6_1:
ldi		XL,low(const1b)		;Запись младшего байта const1b в XL
ldi		XH,high(const1b)	;Запись старшего байта const1b в XH

step6_2:
rcall 	mul16x16		;Вызов подпрограммы перемножения 16-ти битных чисел

;-----------------------Деление на 32...32768 с помощью переносов

cpi		k_del,4			;Если поправка равна 4 (clk/1024), то переход на divC_32
breq	divC_32			;иначе далее

cpi		k_del,3			;Если поправка равна 3 (clk/256), то переход на divC_128
breq	divC_128		;иначе далее

cpi		k_del,2			;Если поправка равна 2 (clk/64), то переход на divC_512
breq	divC_512		;иначе далее

cpi		k_del,1			;Если поправка равна 1 (clk/8), то переход на divC_4096
breq	divC_4096		;иначе далее

divC_32768:
rcall	del32_8			;/8

divC_4096:
rcall	del32_8			;/8

divC_512:
rcall	del32_4			;/4

divC_128:
rcall	del32_4			;/4

divC_32:
rcall	del32_32		;/32

cpi		tok_zar,0		;Сравнение tok_zar с 0
breq	step6_3			;Если tok_zar=0, то на step6_3, иначе далее
rcall	del32_2			;/2
rcall	del32_8			;/8
clr		k_del			;Очистка k_del
clr		tok_zar			;Очистка tok_zar

;-----------------------Перевод двоичного результата ёмкости в двоично-десятичный (ёмкость, малый ток)

rcall	bin2dec			;Вызов подпрограммы перевода двоичного числа в двоично-десятичное (ёмкость, малый ток))

;-----------------------Отображение первой строки LCD

rcall	lcd_1str		;Вызов подпрограммы отображения первой строки LCD

;-----------------------Передача с 1-го по 7-й байт через USART

;rcall	usart_1_7		;Вызов подпрограммы передачи с 1-го по 7-й байт через USART

rjmp	main			;На main

step6_3:
ldi		z1,low(porog2)	;Запись младшего байта porog2 в z1
ldi		z2,high(porog2)	;Запись старшего байта porog2 в z2
clr		z3				;Очистка z3
clr		z4				;Очистка z4
cp		c1,z1			;Сравнение c1 с z1
cpc		c2,z2			;Сравнение c2 с z2 с учётом переноса
cpc		c3,z3			;Сравнение c3 с z3 с учётом переноса
cpc		c4,z4			;Сравнение c4 с z4 с учётом переноса
brsh	step6_3_1		;Если (c4+c3+c2+c1)>=porog2, то на step6_3_1, иначе далее
ldi		tok_zar,1		;Запись 1 в tok_zar

ldi		z1,low(porog3)	;Запись младшего байта porog3 в z1
ldi		z2,high(porog3)	;Запись старшего байта porog3 в z2
cp		c1,z1			;Сравнение c1 с z1
cpc		c2,z2			;Сравнение c2 с z2 с учётом переноса
cpc		c3,z3			;Сравнение c3 с z3 с учётом переноса
cpc		c4,z4			;Сравнение c4 с z4 с учётом переноса
brlo	step6_3_0		;Если (c4+c3+c2+c1)<porog3, то на step6_3_0, иначе далее
inc		k_del			;Увеличение поправки на 1 (увеличение коэффициента деления)

step6_3_0:
rjmp	step7			;На step7

step6_3_1:
ldi		z1,0x80			;Запись 1-го байта порога переключения на доли Фарад (10000000)
ldi		z2,0x96			;Запись 2-го байта порога переключения на доли Фарад
ldi		z3,0x98			;Запись 3-го байта порога переключения на доли Фарад
cp		c1,z1			;Сравнение c1 с z1
cpc		c2,z2			;Сравнение c2 с z2 с учётом переноса
cpc		c3,z3			;Сравнение c3 с z3 с учётом переноса
cpc		c4,z4			;Сравнение c4 с z4 с учётом переноса
brlo	step6_4			;Если (c4+c3+c2+c1)<(z4+z3+z2+z1), то на step6_4, иначе далее

;-----------------------Деление (c4+c3+c2+c1)/10000=(c3+c2+c1)    (b3+b2+b1)
step6_3_2:
ldi		temp,low(10000)	;Запись младшего байта 10000 в temp
mov		a1,temp			;Копирование из temp в a1
ldi		temp,high(10000);Запись старшего байта 10000 в temp
mov		a2,temp			;Копирование из temp в a2
clr		a3				;Очистка a3

rcall 	div32_16		;Вызов подпрограммы деления 32-х на 16-ти битное число

;-----------------------Перевод двоичного результата ёмкости в двоично-десятичный

step6_4:
rcall	bin2dec			;Вызов подпрограммы перевода двоичного числа в двоично-десятичное (ёмкость)

;-----------------------Отображение первой строки LCD

rcall	lcd_1str		;Вызов подпрограммы отображения первой строки LCD
;clr		autoff			;Очистка autoff

;-----------------------Передача с 1-го по 7-й байт через USART

step6_5:
;rcall	usart_1_7		;Вызов подпрограммы передачи с 1-го по 7-й байт через USART

step7:
pop		c3				;Извлечение из стека в c3 (извлечение n1)
pop		c2				;Извлечение из стека в c2
pop		c1				;Извлечение из стека в c1

;-----------------------Умножение (c3+c2+c1)*(XH+XL)=(c4+c3+c2+c1) или (U2/I)*n1

ldi		XL,low(const3)	;Запись младшего байта const3 в XL
ldi		XH,high(const3)	;Запись старшего байта const3 в XH
rcall 	mul16x16		;Вызов подпрограммы перемножения 16-ти битных чисел

mov		z1,c1			;Копирование результата умножения из c1 в z1
mov		z2,c2			;Копирование результата умножения из c2 в z2
mov		z3,c3			;Копирование результата умножения из c3 в z3
mov		z4,c4			;Копирование результата умножения из c4 в z4

mov		c1,b1			;Копирование 1-го байта n2 из b1 в c1
mov		c2,b2			;Копирование 2-го байта n2 из b2 в c2
mov		c3,b3			;Копирование 3-го байта n2 из b3 в c3

;-----------------------Умножение (c3+c2+c1)*(XH+XL)=(c4+c3+c2+c1) или (U1/I)*n2

ldi		XL,low(const2)	;Запись младшего байта const2 в XL
ldi		XH,high(const2)	;Запись старшего байта const2 в XH
rcall 	mul16x16		;Вызов подпрограммы перемножения 16-ти битных чисел

pop		a3				;Извлечение из стека в a3 (извлечение n2-n1)
pop		a2				;Извлечение из стека в a2
pop		a1				;Извлечение из стека в a1

sub		c1,z1			;Вычитание z1 из c1 ((U1/I)*n2)-((U2/I)*n1)
sbc		c2,z2			;Вычитание z2 из c2 с учётом переноса
sbc		c3,z3			;Вычитание z3 из c3 с учётом переноса
sbc		c4,z4			;Вычитание z4 из c4 с учётом переноса

brpl	step8				;Если результат положительный, то на step8, иначе далее
ldi		ZL,low(ESRmn*2)		;Запись в ZL младшего байта адреса ячейки из таблицы ESRmn (альтернативная адресация)
ldi		ZH,high(ESRmn*2)	;Запись в ZH старшего байта адреса ячейки из таблицы ESRmn (альтернативная адресация)

;-----------------------Передача сообщения "ESR < 0,01 Оm"

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

;ldi		temp,0xD3		;Запись 0xD3 в temp
;out		UDR,temp		;Передача из temp в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

rjmp	step8_0			;На step8_0

;-----------------------Деление (c4+c3+c2+c1)/(a3+a2+a1)=(c3+c2+c1)  (b3+b2+b1) или (((U1/I)*n2)-((U2/I)*n1))/(n2-n1)
step8:
rcall 	div32_16		;Вызов подпрограммы деления 32-х на 16-ти битное число

;-----------------------Сравнение результата вычитания с максимальным значением

clr		c3					;Очистка c3
ldi		temp,low(ESRmax)	;Запись младшего байта ESRmax в temp
ldi		temp2,high(ESRmax)	;Запись старшего байта ESRmax в temp2
cp		c1,temp				;Сравнение c1 с temp
cpc		c2,temp2			;Сравнение c2 с temp2 с учётом переноса
brlo	step9				;Если (c2+c1)< ESRmax, то на step9, иначе далее
ldi		ZL,low(ESRmx*2)		;Запись в ZL младшего байта адреса ячейки из таблицы ESRmx (альтернативная адресация)
ldi		ZH,high(ESRmx*2)	;Запись в ZH старшего байта адреса ячейки из таблицы ESRmx (альтернативная адресация)

;-----------------------Передача сообщения "ESR >20,0 Оm"

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

;ldi		temp,0xD2		;Запись 0xD2 в temp
;out		UDR,temp		;Передача из temp в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

step8_0:
ldi		temp,2			;Отображение 2-й строки
rcall	lcd_mess		;Вызов подпрограммы отображения сообщений

rjmp	main			;На main

;-----------------------Перевод двоичного результата ESR в двоично-десятичный

step9:
rcall	bin2dec			;Вызов подпрограммы перевода двоичного числа в двоично-десятичное (ESR)

;-----------------------Отображение второй строки LCD

step10:
rcall	lcd_2str		;Вызов подпрограммы отображения второй строки LCD

;-----------------------Передача 8-го...11-й байт через USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

;ldi		temp,0x80		;Запись 0x80 в temp
;or		desyatki,temp	;Логическое сложение desyatki с temp, результат в desyatki
;out		UDR,desyatki	;Передача из desyatki в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

;ldi		temp,0x90		;Запись 0x90 в temp
;or		edinicy,temp	;Логическое сложение edinicy с temp, результат в edinicy
;out		UDR,edinicy		;Передача из edinicy в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

;ldi		temp,0xA0		;Запись 0xA0 в temp
;or		desyatye,temp	;Логическое сложение desyatye с temp, результат в desyatye
;out		UDR,desyatye	;Передача из desyatye в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

;ldi		temp,0xB0		;Запись 0xB0 в temp
;or		sotye,temp		;Логическое сложение sotye с temp, результат в sotye
;out		UDR,sotye		;Передача из sotye в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

rjmp	main			;На main

;-----------------------Подпрограмма отображение первой строки LCD

lcd_1str:

;-----------------------Отображение ёмкости

ldi		lcd,0x80		;Выбор знакоместа (начало 1й строки)
rcall	lcd_com			;Вызов подпрограммы отправки команды на LCD

;-----------------------Отображение "12345" или " 2345"

clr		temp			;Очистка temp
cp		des_tysh,temp	;Если значение десятков тысяч не равно нулю, то переход на lcd_1str_4
brne	lcd_1str_4		;иначе далее
		
cp		tyshi,temp		;Если значение тысяч не равно нулю, то переход на lcd_1str_3
brne	lcd_1str_3		;иначе далее

cp		sotni,temp		;Если значение сотен не равно нулю, то переход на lcd_1str_2
brne	lcd_1str_2		;иначе далее

cp		desyatki,temp	;Если значение десятков не равно нулю, то переход на lcd_1str_0
brne	lcd_1str_0		;иначе далее

;-----------------------Отображение " 5,67" или "45,67"

ldi		lcd,0x20		;Отображение " " (ёмкость)
rcall	lcd_dat			; 
rjmp	lcd_1str_1		;На lcd_1str_1

lcd_1str_0:
cpi		k_del,4			;Сравнение k_del с 4
brne	lcd_1str_0_1	;Если k_del<>4, то на lcd_1str_0_1

ldi		lcd,0x30		;Отображение "0" (ёмкость)
rcall	lcd_dat			;

ldi		lcd,0x2C		;Отображение "," (ёмкость)
rcall	lcd_dat			; 

lcd_1str_0_1:
ldi		lcd,0x30		;Определение кода для числа десятков (ёмкость)
add		lcd,desyatki	;
rcall	lcd_dat			;Отображение числа десятков (ёмкость)

lcd_1str_1:
ldi		lcd,0x30		;Определение кода для числа единиц (ёмкость)
add		lcd,edinicy	;
rcall	lcd_dat			;Отображение числа единиц (ёмкость)

cpi		k_del,4			;Сравнение k_del с 4
brne	lcd_1str_1_1	;Если k_del<>4, то на lcd_1str_1_1

ldi		lcd,0x30		;Определение кода для числа десятых долей (ёмкость)
add		lcd,desyatye	;
rcall	lcd_dat			;Отображение числа десятых долей (ёмкость)

ldi		lcd,0x30		;Определение кода для числа сотых долей (ёмкость)
add		lcd,sotye		;
rcall	lcd_dat			;Отображение числа сотых долей (ёмкость)

ldi		lcd,0x20		;Отображение " " (ёмкость)
rcall	lcd_dat			; 

rjmp	F_lcd			;На F_lcd

lcd_1str_1_1:
ldi		lcd,0x2C		;Отображение "," (ёмкость)
rcall	lcd_dat			; 

ldi		lcd,0x30		;Определение кода для числа десятых долей (ёмкость)
add		lcd,desyatye	;
rcall	lcd_dat			;Отображение числа десятых долей (ёмкость)

ldi		lcd,0x30		;Определение кода для числа сотых долей (ёмкость)
add		lcd,sotye		;
rcall	lcd_dat			;Отображение числа сотых долей (ёмкость)
rjmp	uF_lcd			;На uF_lcd

;-----------------------Отображение "345,6"

lcd_1str_2:
ldi		lcd,0x30		;Определение кода для числа сотен (ёмкость)
add		lcd,sotni		;
rcall	lcd_dat			;Отображение числа сотен (ёмкость)

ldi		lcd,0x30		;Определение кода для числа десятков (ёмкость)
add		lcd,desyatki		;
rcall	lcd_dat			;Отображение числа десятков (ёмкость)

ldi		lcd,0x30		;Определение кода для числа единиц (ёмкость)
add		lcd,edinicy	;
rcall	lcd_dat			;Отображение числа единиц (ёмкость)

ldi		lcd,0x2C		;Отображение "," (ёмкость)
rcall	lcd_dat			; 

ldi		lcd,0x30		;Определение кода для числа десятых долей (ёмкость)
add		lcd,desyatye	;
rcall	lcd_dat			;Отображение числа десятых долей (ёмкость)
rjmp	uF_lcd			;На uF_lcd

;-----------------------Отображение " 2345" или "12345"

lcd_1str_3:
ldi		lcd,0x20		;Отображение " " (ёмкость)
rcall	lcd_dat			; 
rjmp	lcd_1str_5		;На lcd_1str_5

lcd_1str_4:
ldi		lcd,0x30		;Определение кода для числа десятков тысяч (ёмкость)
add		lcd,des_tysh	;
rcall	lcd_dat			;Отображение числа десятков тысяч (ёмкость)

lcd_1str_5:
ldi		lcd,0x30		;Определение кода для числа тысяч (ёмкость)
add		lcd,tyshi		;
rcall	lcd_dat			;Отображение числа тысяч (ёмкость)

ldi		lcd,0x30		;Определение кода для числа сотен (ёмкость)
add		lcd,sotni		;
rcall	lcd_dat			;Отображение числа сотен (ёмкость)

ldi		lcd,0x30		;Определение кода для числа десятков (ёмкость)
add		lcd,desyatki	;
rcall	lcd_dat			;Отображение числа десятков (ёмкость)

ldi		lcd,0x30		;Определение кода для числа единиц (ёмкость)
add		lcd,edinicy	;
rcall	lcd_dat			;Отображение числа единиц (ёмкость)

uF_lcd:
ldi		lcd,0x20		;Отображение " " (ёмкость)
rcall	lcd_dat			; 

ldi		lcd,0x75		;Отображение "u" (ёмкость)
rcall	lcd_dat			; 

F_lcd:
ldi		lcd,0x46		;Отображение "F" (ёмкость)
rcall	lcd_dat			;
ret						;Выход из подпрограммы

;-----------------------Подпрограмма отображение второй строки LCD

lcd_2str:

;-----------------------Отображение ESR

ldi		lcd,0xC0		;Выбор знакоместа (начало 2й строки)
rcall	lcd_com			;

clr		temp			;Очистка temp
cp		desyatki,temp	;Если значение десятков равно нулю, то переход на lcd_2str_0
breq	lcd_2str_0		;иначе далее

ldi		lcd,0x30		;Определение кода для числа десятков (ESR)
add		lcd,desyatki			;
rcall	lcd_dat			;Отображение числа десятков (ESR)
rjmp	lcd_2str_1		;Переход на lcd_2str_1

lcd_2str_0:
ldi		lcd,0x20		;Отображение " " (ESR)
rcall	lcd_dat			; 

lcd_2str_1:
ldi		lcd,0x30		;Определение кода для числа единиц (ESR)
add		lcd,edinicy			;
rcall	lcd_dat			;Отображение числа единиц (ESR)

ldi		lcd,0x2C		;Отображение "," (ESR)
rcall	lcd_dat			; 

ldi		lcd,0x30		;Определение кода для числа десятых долей (ESR)
add		lcd,desyatye			;
rcall	lcd_dat			;Отображение числа десятых долей (ESR)

ldi		lcd,0x30		;Определение кода для числа сотых долей (ESR)
add		lcd,sotye			;
rcall	lcd_dat			;Отображение числа сотых долей (ESR)

ldi		lcd,0x4F		;Отображение "О" (ESR)
rcall	lcd_dat			; 

ldi		lcd,0x6D		;Отображение "m" (ESR)
rcall	lcd_dat			; 
ret						;Выход из подпрограммы

;-----------------------Подпрограмма отображение сообщений на LCD

lcd_mess:
ldi		z4,8			;Запись 8 в z4
cpi		temp,1			;Сравнение temp с 1
brne	lcd_mess_2str	;Если str не равен 1, то на lcd_mess_2str, иначе далее

lcd_mess_1str:
ldi		lcd,0x80		;Выбор знакоместа (начало 1й строки)
rcall	lcd_com			;
rjmp	lcd_mess_0		;На lcd_mess_0

lcd_mess_2str:
ldi		lcd,0xC0		;Выбор знакоместа (начало 2й строки)
rcall	lcd_com			;

lcd_mess_0:
lpm		lcd,Z+			;Запись lcd байта состояния строк из ячейки с адресом из Z
rcall	lcd_dat			;
dec		z4				;Уменьшение z4 на 1
cpi		z4,0			;Сравнение z4 с 0
brne	lcd_mess_0		;Если z4<>0, то на lcd_mess_0, иначе далее
ret						;Выход из подпрограммы

;-----------------------Подпрограмма отображения двух строк подряд на LCD по данным из таблиц 

lcd_all:
ldi		temp,1			;Отображение 1-й строки
rcall	lcd_mess		;Вызов подпрограммы отображения сообщений
ldi		temp,2			;Отображение 2-й строки
rcall	lcd_mess		;Вызов подпрограммы отображения сообщений
ret						;Выход из подпрограммы

;-----------------------Подпрограмма отображения номера предела 

pred_num:
ldi		lcd,0x87		;Выбор знакоместа (конец 1й строки)
rcall	lcd_com			;

ldi		lcd,0x30		;Определение кода для предела
add		lcd,k_del		;
inc		lcd				;
rcall	lcd_dat			;
ret						;Выход из подпрограммы

;-----------------------Подпрограмма преобразование 24 битного числа в двоично-десятичное
;Число для преобразования из XL, XH, результат в des_tysh, tyshi, sotni, desyatki,
;edinicy, desyatye, sotye

bin2dec:
clr		des_tysh		;Сброс десятков тысяч
clr		tyshi			;Сброс тысяч
clr		sotni			;Сброс сотен
clr		desyatki		;Сброс десятков
clr		edinicy			;Сброс единиц
clr		desyatye		;Сброс десятых долей
clr		sotye			;Сброс сотых долей

des_tysh0:
ldi		z1,0x40			;Занесение 1000000 в z1...z3
ldi		z2,0x42			;
ldi		z3,0x0F			;

des_tysh1:
rcall	c_minus_z		;Вычитание 1000000
brmi	des_tysh2		;Если результат вычисления отрицательный, то переход на des_tysh2
inc		des_tysh		;Иначе увеличение на 1 числа десятков тысяч
rjmp	des_tysh1		;На des_tysh1

des_tysh2:
rcall	c_plus_z		;Прибавление 1000000 к отрицательному результату

tyshi0:
ldi		z1,0xA0			;Занесение 100000 в z1...z3
ldi		z2,0x86			;
ldi		z3,0x01			;

tyshi1:
rcall	c_minus_z		;Вычитание 100000
brmi	tyshi2			;Если результат вычисления отрицательный, то переход на tyshi2
inc		tyshi			;Иначе увеличение на 1 числа тысяч
rjmp	tyshi1			;На tyshi1

tyshi2:
rcall	c_plus_z		;Прибавление 100000 к отрицательному результату

sotni0:
ldi		z1,0x10			;Занесение 10000 в z1...z3
ldi		z2,0x27			;
ldi		z3,0x00			;

sotni1:
rcall	c_minus_z		;Вычитание 10000
brmi	sotni2			;Если результат вычисления отрицательный, то переход на sotni2
inc		sotni			;Иначе увеличение на 1 числа сотен
rjmp	sotni1			;На sotni1

sotni2:
rcall	c_plus_z		;Прибавление 10000 к отрицательному результату

desyatki0:
ldi		z1,0xE8			;Занесение 1000 в z1...z3
ldi		z2,0x03			;

desyatki1:
rcall	c_minus_z		;Вычитание 1000
brmi	desyatki2		;Если результат вычисления отрицательный, то переход на desyatki2
inc		desyatki		;Иначе увеличение на 1 числа десятков
rjmp	desyatki1		;На desyatki1

desyatki2:
rcall	c_plus_z		;Прибавление 1000 к отрицательному результату

edinicy0:
ldi		z1,0x64			;Занесение 100 в z1...z3
ldi		z2,0x00			;

edinicy1:
rcall	c_minus_z		;Вычитание 100
brmi	edinicy2		;Если результат вычисления отрицательный, то переход на edinicy2
inc		edinicy			;Иначе увеличение на 1 числа единиц
rjmp	edinicy1		;На edinicy1

edinicy2:
rcall	c_plus_z		;Прибавление 100 к отрицательному результату

desyatye0:
ldi		z1,0x0A			;Занесение 10 в z1...z3

desyatye1:
rcall	c_minus_z		;Вычитание 10
brmi	desyatye2		;Если результат вычисления отрицательный, то переход на desyatye2
inc		desyatye		;Иначе увеличение на 1 числа десятых долей
rjmp	desyatye1		;На desyatye1

desyatye2:
rcall	c_plus_z		;Прибавление 10 к отрицательному результату

sotye0:
ldi		z1,0x01			;Занесение 1 в z1...z3

sotye1:
rcall	c_minus_z		;Вычитание 1
brmi	bin2dec1		;Если результат вычисления отрицательный, то переход на bin2dec1
inc		sotye			;Иначе увеличение на 1 числа сотых долей
rjmp	sotye1			;На sotye1

bin2dec1:
clr		c1				;Очистка c1
clr		c2				;Очистка c2
clr		c3				;Очистка c3
ret						;Выход из подпрограммы

;-----------------------Подпрограмма перемножения 16-ти битных чисел с оптимизацией
;времени выполнения засчёт смены умножаемого и множителя местами в зависимости от их величин
;1-е число: (c4+c3+c2+c1), 2-е число: (XH+XL), Результат: (c4+c3+c2+c1)

;-----------------------Очистка используемых регистров

mul16x16:
clr		temp			;Очистка temp
clr		c4				;Очистка c4

;-----------------------Оптимизация времени вычисления

mul16x16_0:
cp		c1,XL			;Сравнение 1-ых байтов чисел
cpc		c2,XH			;Сравнение 2-ых байтов чисел с учётом переноса
cpc		c3,temp			;Сравнение 3-их байтов чисел с учётом переноса
brsh	mul16x16_1		;Если c3+c2+c1 больше или равно XH+XL, то на mul16x16_1,
push	c1				;иначе далее (смена чисел местами через стек)
push	c2				;
push	XL				;
push	XH				;
pop		c2				;
pop		c1				;
pop		XH				;
pop		XL				;

;-----------------------Подготовка к умножению

mul16x16_1:
mov		a1,c1			;Копирование 1-го байта умножаемого в a1
mov		a2,c2			;Копирование 2-го байта умножаемого в a1
mov		a3,c3			;Копирование 3-го байта умножаемого в a1

;-----------------------Умножение 

mul16x16_2:
sbiw	X,1				;Уменьшение множителя на 1
cp		XL,temp			;Сравнение результата с 0
cpc		XH,temp			;Сравнение результата с 0, с учётом переноса
breq	mul16x16_3		;Если множитель равен нулю, то переход на mul16x16_3, иначе далее
add		c1,a1			;Сложение c1 и a1, результат в c1
adc		c2,a2			;Сложение c2 и a2 с учётом переноса, результат в c2
adc		c3,a3			;Сложение c3 и a3 с учётом переноса, результат в c3
adc		c4,temp			;Сложение c4 и temp с учётом переноса, результат в c4
rjmp	mul16x16_2		;На mul16x16_2

mul16x16_3:
ret						;Выход из подпрограммы

;-----------------------Подпрограмма деления 32-х битного на 16-ти битное число
;Делимое: (c4+c3+c2+c1), Делитель: (XH+XL), Результат: (c3+c2+c1)     (b3+b2+b1)

div32_16:
clr		temp			;Очистка temp
clr		temp2			;Очистка temp2
clr		XL				;Очистка XL			
clr		XH				;Очистка XH	

div32_16_0:
sub		c1,a1			;Вычитание a1 из c1
sbc		c2,a2			;Вычитание a2 из c2 с учётом переноса
sbc		c3,a3			;Вычитание a3 из c3 с учётом переноса
sbc		c4,temp			;Вычитание temp из c4 с учётом переноса
brcs	div32_16_1		;Если результат вычисления отрицательный, то переход на div32_16_1
adiw	X,1				;Прибавление 1 к регистровой паре X
adc		temp2,temp		;Сложение temp2 и temp с учётом переноса, результат в temp2
rjmp	div32_16_0		;Переход на div32_16_0

div32_16_1:
mov		c1,XL			;Копирование 1-го байта результата из XL в c1
mov		c2,XH			;Копирование 2-го байта результата из XH в c2
mov		c3,temp2		;Копирование 3-го байта результата из temp2 в c3
ret						;Выход из подпрограммы

;-----------------------Подпрограмма деления 32-x битного числа на 2 через перенос вправо

del32_2:
lsr		c4				;/2 (итого /2)
ror		c3				;
ror		c2				;
ror		c1				;
ret						;Выход из подпрограммы

;-----------------------Подпрограмма деления 32-x битного числа на 4 через перенос вправо

del32_4:
rcall	del32_2			;/2 (итого /2)
rcall	del32_2			;/2 (итого /4)
ret						;Выход из подпрограммы

;-----------------------Подпрограмма деления 32-x битного числа на 8 через перенос вправо

del32_8:
rcall	del32_2			;/2 (итого /2)
rcall	del32_4			;/4 (итого /8)
ret						;Выход из подпрограммы

;-----------------------Подпрограмма деления 32-x битного числа на 32 через перенос вправо

del32_32:
rcall	del32_4			;/4 (итого /4)
rcall	del32_8			;/8 (итого /32)
ret						;Выход из подпрограммы

;-----------------------Подпрограмма вычитания (c3+c2+c1)-(z3+z2+z1)=(c3+c2+c1)

c_minus_z:
sub		c1,z1			;
sbc		c2,z2			;
sbc		c3,z3			;
ret						;Выход из подпрограммы

;-----------------------Подпрограмма сложения (c3+c2+c1)+(z3+z2+z1)=(c3+c2+c1)

c_plus_z:
add		c1,z1			;
adc		c2,z2			;
adc		c3,z3			;
ret						;Выход из подпрограммы

;-----------------------Подпрограмма задержки (~1мкс при 20МГц)
;Число тактов для выполнения (3*N)+4

del1u:
ldi		temp2,d1u		;Запись d1u в temp2

del1u_1:
dec		temp2			;Уменьшение temp2 на 1
brne	del1u_1			;Если результат не равен 0, то переход на del1u_1
ret						;Выход из подпрограммы

;-----------------------Подпрограмма задержки (~40мкс при 20МГц)
;Число тактов для выполнения (3*N)+4

del40u:
ldi		temp2,d40u		;Запись d40u в temp2

del40u_1:
dec		temp2			;Уменьшение temp2 на 1
brne	del40u_1		;Если результат не равен 0, то переход на del40u_1
ret						;Выход из подпрограммы

;-----------------------Подпрограмма задержки (~3мс при 20МГц)
;Число тактов для выполнения (6*N)+9

del3m:
ldi		XL,low(d3m)		;Задание длительности
ldi		XH,high(d3m)	;Задание длительности
clr		temp2			;Очистка temp

del3m_1:
sbiw	X,1				;Вычитание из регистровой пары X числа 1
cp		XL,temp2		;Сравнение результата с 0
cpc		XH,temp2		;Сравнение результата с 0, с учётом переноса
brne	del3m_1			;Если результат не равен 0, то переход на del3m_1
ret						;Выход из подпрограммы

;-----------------------Подпрограмма задержки (~20мс при 20МГц)
;Число тактов для выполнения (6*N)+9

del20m:
ldi		XL,low(d20m)	;Задание длительности
ldi		XH,high(d20m)	;Задание длительности
clr		temp2			;Очистка temp

del20m_1:
sbiw	X,1				;Вычитание из регистровой пары X числа 1
cp		XL,temp2		;Сравнение результата с 0
cpc		XH,temp2		;Сравнение результата с 0, с учётом переноса
brne	del20m_1		;Если результат не равен 0, то переход на del20m_1
ret						;Выход из подпрограммы

;-----------------------Подпрограмма задержки (~300мс при 20МГц)

del300m:
ldi		temp,15			;Задание длительности

del300m_1:
rcall	del20m			;Вызов подпрограммы задержки (~20мс)
dec		temp			;Уменьшение temp на 1
cpi		temp,0			;Сравнение temp с 0
brne	del300m_1		;Если temp<>0, то на del300m_1, иначе далее
ret						;Выход из подпрограммы

;-----------------------Подпрограмма отправки команды на LCD

lcd_com:
cbi		PORTB,RS		;Команда
in		temp,PORTB
andi	temp,0b00000011	;Маска 00000011 для обнуления лишнего
ori		temp,0b00001000	;Логическое сложение temp с 00001000 (строб вверх + команда)
rcall	lcd_out			;Вызов подпрограммы lcd_out
ret						;Выход из подпрограммы

;-----------------------Подпрограмма отправки данных на LCD

lcd_dat:
sbi		PORTB,RS		;Данные
in		temp,PORTB
andi	temp,0b00000011	;Маска 00000011 для обнуления лишнего
ori		temp,0b00001100	;Логическое сложение temp с 00001100 (строб вверх + команда)
rcall	lcd_out			;Вызов подпрограммы lcd_out
ret						;Выход из подпрограммы

;-----------------------Подпрограмма отправки на LCD

lcd_out:
rcall	del1u			;Вызов подпрограммы задержки (~1мкс)
sbi		PORTB,E			;Строб вверх
push	lcd				;Сохранение lcd в стеке
andi	lcd,0b11110000	;Маска 11110000 для обнуления младшего полубайта
or		lcd,temp		;Логическое сложение lcd с temp (строб вверх + команда)
out		PORTB,lcd		;Запись команды в порт
rcall	del1u			;Вызов подпрограммы задержки (~1мкс)
cbi		PORTB,E			;Строб вниз
rcall	del40u			;Вызов подпрограммы задержки (~40мкс)

sbi		PORTB,E			;Строб вверх
pop		lcd				;Извлечение lcd из стека
swap	lcd				;Смена полубайт местами
andi	lcd,0b11110000	;Маска 11110000 для обнуления младшего полубайта
or		lcd,temp		;Логическое сложение lcd с temp (строб вверх + команда)
out		PORTB,lcd		;Запись команды в порт
rcall	del1u			;Вызов подпрограммы задержки (~1мкс)
cbi		PORTB,E			;Строб вниз
rcall	del40u			;Вызов подпрограммы задержки (~40мкс)
rcall	del40u			;Вызов подпрограммы задержки (~40мкс)
ret						;Выход из подпрограммы

;-----------------------Подпрограмма ожидания готовности буфера передачи

;USART_ready:
;sbis	UCSRA,UDRE		;Если UDRE установлен, то пропуск след. команды
;rjmp	USART_ready		;На USART_ready
;ret						;Выход из подпрограммы

;-----------------------Подпрограмма записи в ячейку EEPROM
;Адрес записываемой ячейки в temp2, записываемый байт в temp

EEPROM_write:
out		EEAR,temp2		;Переносим адрес в EEAR
out		EEDR,temp		;Переносим записывемый байт в EEDR

EEPROM_write_1:
sbic	EECR,EEPE		;Если EERE сброшен, то пропуск след. команды
rjmp	EEPROM_write_1	;На EEPROM_write_1
sbi		EECR,EEMPE		;Разрешаем запись в EEPROM (устанавливаем EEMPE)
sbi		EECR,EEPE		;Записываем байт в ячейку EEPROM (устанавливаем EEPE)
rcall	del3m			;Вызов подпрограммы задержки (~3мс)
rcall	del3m			;Вызов подпрограммы задержки (~3мс)
ret						;Выход из подпрограммы

;-----------------------Подпрограмма чтения ячейки EEPROM
;Адрес читаемой ячейки в temp2, прочитанная ячейка в temp2

EEPROM_read:
out		EEAR,temp2		;Переносим адрес в EEAR

EEPROM_read_1:
sbic	EECR,EEPE		;Если EEPE сброшен, то пропуск след. команды
rjmp	EEPROM_read_1	;На EEPROM_read_1
sbi		EECR,EERE		;Читаем ячейку EEPROM (устанавливаем EERE)
in		temp2,EEDR		;Переносим прочитанный байт в temp2
ret						;Выход из подпрограммы

;-----------------------Подпрограмма изменения поправки в зависимости от предела

predel:
ldi		temp,1			;Запись 1 в temp
clr		temp2			;Очистка temp2

cpi		k_del,0			;Если поправка предела равна 0 (clk/1), то переход на predel5
breq	predel5			;иначе далее

cpi		k_del,1			;Если поправка предела равна 1 (clk/8), то переход на predel4
breq	predel4			;иначе далее

cpi		k_del,2			;Если поправка предела равна 2 (clk/64), то переход на predel3
breq	predel3			;иначе далее

cpi		k_del,3			;Если поправка предела равна 3 (clk/256), то переход на predel2
breq	predel2			;иначе далее

;-----------------------Деление на 8...1024 с помощью переносов

predel1:
lsr		z2				;/2 (итого /2)
ror		z1				;
lsr		z2				;/2 (итого /4)
ror		z1				;

predel2:
lsr		z2				;/2 (итого /2)
ror		z1				;
lsr		z2				;/2 (итого /4)
ror		z1				;

predel3:
lsr		z2				;/2 (итого /2)
ror		z1				;
lsr		z2				;/2 (итого /4)
ror		z1				;
lsr		z2				;/2 (итого /8)
ror		z1				;

predel4:
lsr		z2				;/2 (итого /2)
ror		z1				;
lsr		z2				;/2 (итого /4)
ror		z1				;
lsr		z2				;/2 (итого /8)
ror		z1				;

predel5:
cp		z1,temp			;Сравнение z1 с temp
cpc		z2,temp2		;Сравнение z2 с temp2 с учётом переноса
brsh	predel6			;Если z2+z1>=1, то на predel6, иначе далее
clr		z1				;Очистка z1
clr		z2				;Очистка z2

predel6:
ret						;Выход из подпрограммы

;-----------------------Подпрограмма отображения числовых строк (для отладки)

otlad:
sbic	PIND,6			;Если PD6=0, то пропуск след. команды
rjmp	otlad_2			;На otlad_2
rcall	del3m			;Вызов подпрограммы задержки (~3мс)
sbic	PIND,6			;Если PD6=0, то пропуск след. команды
rjmp	otlad_2			;На otlad_2

rcall 	lcd_both_str	;Вызов подпрограммы отображения двух числовых строк

otlad_1:
rcall	knop_off		;Вызов подпрограммы ожидания отпускания кнопки

pop		temp			;Очистка стека (поскольку выход не по ret)
pop		temp			;Очистка стека
rjmp	main			;На main

otlad_2:
ret						;Выход из подпрограммы

;-----------------------Подпрограмма ожидания отпускания кнопки

knop_off:
sbis	PIND,6			;Если PD6=1, то пропуск след. команды
rjmp	knop_off		;На knop_off
rcall	del3m			;Вызов подпрограммы задержки (~3мс)
sbis	PIND,6			;Если PD6=1, то пропуск след. команды
rjmp	knop_off		;На knop_off
ret						;Выход из подпрограммы

;-----------------------Подпрограмма передачи с 1-го по 7-й байт через USART

;usart_1_7:
;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи
;ldi		temp,0x10		;Запись 0x10 в temp
;or		des_tysh,temp	;Логическое сложение des_tysh с temp, результат в des_tysh
;out		UDR,des_tysh	;Передача из des_tysh в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи
;ldi		temp,0x20		;Запись 0x20 в temp
;or		tyshi,temp		;Логическое сложение tyshi с temp, результат в tyshi
;out		UDR,tyshi		;Передача из tyshi в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи
;ldi		temp,0x30		;Запись 0x30 в temp
;or		sotni,temp		;Логическое сложение sotni с temp, результат в sotni
;out		UDR,sotni		;Передача из sotni в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи
;ldi		temp,0x40		;Запись 0x40 в temp
;or		desyatki,temp	;Логическое сложение desyatki с temp, результат в desyatki
;out		UDR,desyatki	;Передача из desyatki в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи
;ldi		temp,0x50		;Запись 0x50 в temp
;or		edinicy,temp	;Логическое сложение edinicy с temp, результат в edinicy
;out		UDR,edinicy		;Передача из edinicy в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи
;ldi		temp,0x60		;Запись 0x60 в temp
;or		desyatye,temp	;Логическое сложение desyatye с temp, результат в desyatye
;out		UDR,desyatye	;Передача из desyatye в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи
;ldi		temp,0x70		;Запись 0x70 в temp
;or		sotye,temp		;Логическое сложение sotye с temp, результат в sotye
;out		UDR,sotye		;Передача из sotye в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи
;ret						;Выход из подпрограммы

;-----------------------Подпрограмма отображения одной числовой строки

lcd_one_str:
ldi		lcd,0x4E		;Отображение "N"
rcall	lcd_dat			;

ldi		lcd,0x30		;Определение кода для числа тысяч
add		lcd,tyshi		;
rcall	lcd_dat			;Отображение числа тысяч

ldi		lcd,0x30		;Определение кода для числа сотен
add		lcd,sotni		;
rcall	lcd_dat			;Отображение числа сотен

ldi		lcd,0x30		;Определение кода для числа десятков
add		lcd,desyatki	;
rcall	lcd_dat			;Отображение числа десятков

ldi		lcd,0x30		;Определение кода для числа единиц
add		lcd,edinicy	;
rcall	lcd_dat			;Отображение числа единиц

ldi		lcd,0x30		;Определение кода для числа десятых долей
add		lcd,desyatye	;
rcall	lcd_dat			;Отображение числа десятых долей

ldi		lcd,0x30		;Определение кода для числа сотых долей
add		lcd,sotye		;
rcall	lcd_dat			;Отображение числа сотых долей
ret						;Выход из подпрограммы

;-----------------------Подпрограмма отображения двух числовых строк по данным

lcd_both_str:
mov		c1,a1			;Копирование из a1 в c1
mov		c2,a2			;Копирование из a2 в c2
mov		c3,a3			;Копирование из a3 в c3

;-----------------------Перевод двоичного результата коеффициента в двоично-десятичный

rcall	bin2dec			;Вызов подпрограммы перевода двоичного числа в двоично-десятичное

;-----------------------Отображение смещения от нуля для U1 "1=     "

ldi		lcd,0x80		;Выбор знакоместа (начало 1й строки)
rcall	lcd_com			;

rcall	lcd_one_str		;Вызов подпрограммы отображения одной числовой строки

mov		c1,b1			;Копирование из b1 в c1
mov		c2,b2			;Копирование из b2 в c2
mov		c3,b3			;Копирование из b3 в c3

;-----------------------Перевод двоичного результата коеффициента в двоично-десятичный

rcall	bin2dec			;Вызов подпрограммы перевода двоичного числа в двоично-десятичное

;-----------------------Отображение смещения от нуля для U2 "2=     "

ldi		lcd,0xC0		;Выбор знакоместа (начало 2й строки)
rcall	lcd_com			;

rcall	lcd_one_str		;Вызов подпрограммы отображения одной числовой строки

ret						;Выход из подпрограммы

;-----------------------Подпрограмма обработки прерывания по переполнению таймера 1
;Поскольку выход не по reti, то глобально запрещённые прерывания остаются запрещены

ovtim1:
cli						;Глобально запрещаем прерывания
ldi		temp,3			;Заносим 3 в temp
cp		c3,temp			;Сравнение c3 с temp
breq	ovtim1_0		;Если с3=3, то на ovtim1_0, иначе далее
inc		c3				;Увеличение c3 на 1
reti					;Выход из подпрограммы обработки прерывания

ovtim1_0:
sbi		PORTD,0			;Выключение большого тока заряда конденсатора
sbi		PORTD,4			;Выключение малого тока заряда конденсатора
sbi		PORTD,5			;Включение разряда конденсатора
ldi		temp,0b00000000	;Останов таймера
out		TCCR1B,temp		;
pop		temp			;Очистка стека (поскольку выход по clk_down, а не по reti)
pop		temp			;Очистка стека
rjmp	clk_down		;Переход на clk_down

;-----------------------Подпрограмма обработки внешнего прерывания по U1
;Поскольку выход не по reti, то глобально запрещённые прерывания остаются запрещены

com_U1:
in		a1,TCNT1L		;Сохраняем 1-й байт n1
in		a2,TCNT1H		;Сохраняем 2-й байт n1
mov		a3,c3			;Копируем из c3 в a3 3-й байт n1
ldi		temp,0b10000000	;Разрешение внешнего прерывания только по PD3 (U2)
out		GIMSK,temp		;
reti					;Выход из подпрограммы обработки прерывания

;-----------------------Подпрограмма обработки внешнего прерывания по U2

com_U2:
in		c1,TCNT1L		;Сохраняем 1-й байт n2
in		c2,TCNT1H		;Сохраняем 2-й байт n2
cli						;Глобально запрещаем прерывания
sbi		PORTD,0			;Выключение большого тока заряда конденсатора
sbi		PORTD,4			;Выключение малого тока заряда конденсатора
sbi		PORTD,5			;Включение разряда конденсатора
ldi		temp,0b00000000	;Останов таймера
out		TCCR1B,temp		;
pop		temp			;Очистка стека (поскольку выход не по reti)
pop		temp			;Очистка стека

;-----------------------Проверка (c2+c1)-(a2+a1)<0 и (c2+c1)<>0

com_U2_0:
mov		b1,c1			;Копирование в b1 из c1 (n2)
mov		b2,c2			;Копирование в b2 из c2
mov		b3,c3			;Копирование в b3 из c3
sub		c1,a1			;Определение разности n2-n1
sbc		c2,a2			;результат в c3+c2+c1
sbc		c3,a3			;

cpi		tok_zar,0		;Сравнение tok_zar с 0
breq	com_U2_0_1		;Если tok_zar=0, то на com_U2_0_1, иначе далее

com_U2_0_0:
ldi		temp,255		;Запись 255 temp
rjmp	com_U2_0_2		;На com_U2_0_2

com_U2_0_1:
ldi		temp,30			;Запись 30 temp

com_U2_0_2:
clr		temp2			;Очистка temp2
cp		c1,temp			;Сравнение c1 с temp
cpc		c2,temp2		;Сравнение c2 с temp2 с учётом переноса
cpc		c3,temp2		;Сравнение c3 с temp2 с учётом переноса
brlo	com_U2_1		;Если (c2+c1)<30(255), то на com_U2_1, иначе далее

rcall	otlad			;Вызов подпрограммы отображения числовых строк (для отладки)

rjmp	step1			;На step1

;-----------------------Калибровка

com_U2_1:
cpi		k_del,0			;Сравнение k_del с 0
breq	com_U2_2		;Если k_del=0, то на com_U2_2, иначе далее
rjmp	com_U2_5		;На com_U2_5

com_U2_2:
cpi		tok_zar,0		;Сравнение tok_zar с 0
breq	com_U2_2_0		;Если tok_zar=0, то на com_U2_2_0, иначе далее
clr		tok_zar			;Очистка tok_zar
rjmp	com_U2_5		;На com_U2_5

com_U2_2_0:
sbic	PIND,6			;Если PD6=0, то пропуск след. команды
rjmp	com_U2_5		;На com_U2_5
rcall	del3m			;Вызов подпрограммы задержки (~3мс)
sbic	PIND,6			;Если PD6=0, то пропуск след. команды
rjmp	com_U2_5		;На com_U2_5

;-----------------------Проверка флага записи в EEPROM

ldi		temp2,flag		;Записывает в temp2 адрес читаемой ячейки EEPROM
rcall	EEPROM_read		;Вызов подпрограммы чтения ячейки EEPROM

cpi		temp2,100		;Сравнение temp2 с 100
brne	com_U2_3		;Если temp2<>100, то на com_U2_3, иначе далее

;-----------------------Сброс флага записи в EEPROM

ldi		temp,0xFF		;Заносим 0xFF в temp
ldi		temp2,flag		;Заносим в temp2 адрес ячейки EEPROM
rcall	EEPROM_write	;Вызов подпрограммы записи в EEPROM

;-----------------------Отображение "Калибр. " и "откл.   "

ldi		ZL,low(Popr_off*2)	;Запись в ZL младшего байта адреса ячейки из таблицы Popr_off (альтернативная адресация)
ldi		ZH,high(Popr_off*2)	;Запись в ZH старшего байта адреса ячейки из таблицы Popr_off (альтернативная адресация)
rcall	lcd_all			;Вызов подпрограммы отображения двух строк подряд на LCD по данным из таблиц

rcall	knop_off		;Вызов подпрограммы ожидания отпускания кнопки

rjmp	main			;На main

;-----------------------Запись в EEPROM

;-----------------------Запись n1 (1-й и 2-й байт)

com_U2_3:
mov		temp,a1			;Копируем a1 в temp
ldi		temp2,n1_1b		;Заносим в temp2 адрес ячейки EEPROM
rcall	EEPROM_write	;Вызов подпрограммы записи в EEPROM

mov		temp,a2			;Копируем a2 в temp
ldi		temp2,n1_2b		;Заносим в temp2 адрес ячейки EEPROM
rcall	EEPROM_write	;Вызов подпрограммы записи в EEPROM

;-----------------------Запись n2 (1-й и 2-й байт)

mov		temp,b1			;Копируем b1 в temp
ldi		temp2,n2_1b		;Заносим в temp2 адрес ячейки EEPROM
rcall	EEPROM_write	;Вызов подпрограммы записи в EEPROM

mov		temp,b2			;Копируем b2 в temp
ldi		temp2,n2_2b		;Заносим в temp2 адрес ячейки EEPROM
rcall	EEPROM_write	;Вызов подпрограммы записи в EEPROM

;-----------------------Запись n2-n1 (1-й и 2-й байт)

mov		temp,c1			;Копируем c1 в temp
ldi		temp2,n2_n1_1b	;Заносим в temp2 адрес ячейки EEPROM
rcall	EEPROM_write	;Вызов подпрограммы записи в EEPROM

mov		temp,c2			;Копируем c2 в temp
ldi		temp2,n2_n1_2b	;Заносим в temp2 адрес ячейки EEPROM
rcall	EEPROM_write	;Вызов подпрограммы записи в EEPROM

;-----------------------Запись флага записи в EEPROM

ldi		temp,100		;Заносим 100 в temp
ldi		temp2,flag		;Заносим в temp2 адрес ячейки EEPROM
rcall	EEPROM_write	;Вызов подпрограммы записи в EEPROM

rcall 	lcd_both_str	;Вызов подпрограммы отображения двух числовых строк

;-----------------------Предотвращение многократной записи в EEPROM при удержании кнопки

rcall	knop_off		;Вызов подпрограммы ожидания отпускания кнопки

ldi		ZL,low(Popr_on*2)	;Запись в ZL младшего байта адреса ячейки из таблицы Popr_on (альтернативная адресация)
ldi		ZH,high(Popr_on*2)	;Запись в ZH старшего байта адреса ячейки из таблицы Popr_on (альтернативная адресация)
rcall	lcd_all				;Вызов подпрограммы отображения двух строк подряд на LCD по данным из таблиц
rcall	del300m				;Вызов подпрограммы задержки (~300мс)

rjmp	main				;На main

;-----------------------Отображение "Cx < min" и "Rx > max"

com_U2_5:
ldi		ZL,low(Cmn_Rmx*2)	;Запись в ZL младшего байта адреса ячейки из таблицы Сmin_Rmax (альтернативная адресация)
ldi		ZH,high(Cmn_Rmx*2)	;Запись в ZH старшего байта адреса ячейки из таблицы Сmin_Rmax (альтернативная адресация)
rcall	lcd_all				;Вызов подпрограммы отображения двух строк подряд на LCD по данным из таблиц
;inc		autoff				;Увеличение autoff на 1

;-----------------------Передача сообщения "Cx < min" и "ESR > max"

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

;ldi		temp,0xD1		;Запись 0xD1 в temp
;out		UDR,temp		;Передача из temp в USART

;rcall	USART_ready		;Вызов подпрограммы ожидания готовности буфера передачи

rjmp	clk_up			;На уменьшение предела измерения (на clk_up)

;-----------------------Таблица сообщений

Prvt:
.db	0x49,0x67,0x6F,0x72,0x20,0x49,0x2E,0x26 	;"Igor I.& "
.db	0x20,0x59,0x65,0x76,0x67,0x65,0x6E,0x20 	;"Yevgen "

Pred:
.db	0x52,0x61,0x6E,0x67,0x65,0x3A,0x20,0x20 	;"Range:  "
.db	0x77,0x61,0x69,0x74,0x2E,0x2E,0x2E,0x20 	;"wait... "

Cmn_Rmx:
.db	0x43,0x78,0x3C,0x20,0x6D,0x69,0x6E,0x20 	;"Cx< min "
.db	0x45,0x53,0x52,0x3E,0x6D,0x61,0x78,0x20 	;"ESR>max "

ESRmn:
.db	0x3C,0x30,0x2C,0x30,0x31,0x4F,0x6D,0x20 	;"<0,01Оm "

ESRmx:
.db	0x3E,0x32,0x30,0x2C,0x30,0x4F,0x6D,0x20  	;">20,0Оm "

KZ_Cmx:
.db	0x43,0x78,0x3E,0x6D,0x61,0x78,0x20,0x6F		;"Cx>max o"
.db	0x72,0x20,0x73,0x68,0x6F,0x72,0x74,0x20 	;"r short "

Popr_on:
.db	0x43,0x6F,0x72,0x72,0x65,0x63,0x2D,0x20 	;"Correc- "
.db	0x74,0x69,0x6F,0x6E,0x20,0x4F,0x4E,0x20		;"tion ON "

Popr_off:
.db	0x43,0x6F,0x72,0x72,0x65,0x63,0x2D,0x20 	;"Correc- "
.db	0x74,0x69,0x6F,0x6E,0x4F,0x46,0x46,0x20		;"tionOFF "

;Bat:
;.db	0x52,0x65,0x70,0x6C,0x61,0x63,0x65,0x20 	;"Replace "
;.db    0x62,0x61,0x74,0x74,0x65,0x72,0x79,0x20 	;"battery "

;Gdit:
;.db	0x77,0x61,0x69,0x74,0x2E,0x2E,0x2E,0x20 	;"wait... "
