		;Вольтметр на ATtiny2313 или AT90S2313


;GIMSK.7,GIMSK.6-разрешение прерывания INT0,INT1, 0x00.
;GIFR.7,GIFR.6-флаги прерывания INT0,INT1.
;TIMSK-маска прерываний таймеров,0x8a-активация.
;TIMSK.7-прерывание по переполнению Т1.
;TIMSK.3-прерывание по захвату Т1.
;TIMSK.1-прерывание по переполнению Т0. 
;TCCR0-источник тактового сигнала T0, 0x04, CK/256, 0x00-останов таймера.
;TCCR1B-источник тактового сигнала T1, 0x02, CK/8, 0x00-останов таймера.
;WDTCR-сторожевой таймер,0x06-установка таймера, 0x0e-запуск.
;ACSR-компаратор, 0x91.
;DDRB-напрвление передачи данных порта B, 0xff. 
;PORTB-регистр данных порта B, 0xff.
;DDRD-напрвление передачи данных порта D, 0x3f.
;PORTD-регистр данных порта D, 0x20.

;ОЗУ 0x0060:маска индикаторов частотой 2 Гц
;ОЗУ 0x0061:индикатор №1, семисегментный код 
;ОЗУ 0x0062:индикатор №2, семисегментный код
;ОЗУ 0x0063:индикатор №3, семисегментный код
;ОЗУ 0x0064:индикатор №4, семисегментный код
;ОЗУ 0x0065:измеренное напряжение, младшая часть, binary
;ОЗУ 0x0066:измеренное напряжение, старшая часть, binary
;ОЗУ 0x0067:маска индикаторов
;ОЗУ 0x0068:счетчик АЦП, перезапуск через равные интервалы t=N*8,192 мс.
;ОЗУ 0x0069:счетчик тиков, 8,192 мс
;ОЗУ 0x006a:счетчик 2Гц
;ОЗУ 0x006b:константа ацп, без делителя
;ОЗУ 0x006c:константа ацп, с делителем
;ОЗУ 0x0070:семисегментный код цифры "0"
;ОЗУ 0x0071:семисегментный код цифры "1"
;ОЗУ 0x0072:семисегментный код цифры "2"
;ОЗУ 0x0073:семисегментный код цифры "3"
;ОЗУ 0x0074:семисегментный код цифры "4"
;ОЗУ 0x0075:семисегментный код цифры "5"
;ОЗУ 0x0076:семисегментный код цифры "6"
;ОЗУ 0x0077:семисегментный код цифры "7"
;ОЗУ 0x0078:семисегментный код цифры "8"
;ОЗУ 0x0079:семисегментный код цифры "9"
;ОЗУ 0x007a:семисегментный код цифры "A"
;ОЗУ 0x007b:семисегментный код цифры "b"
;ОЗУ 0x007c:семисегментный код цифры "C"
;ОЗУ 0x007d:семисегментный код цифры "d"
;ОЗУ 0x007e:семисегментный код цифры "E"
;ОЗУ 0x007f:семисегментный код цифры "F"
;РОН r25, b.0 - флаг ацп запущен
;РОН r25, b.1 - флаг делитель включен
;РОН r25, b.2 - флаг переполнение
	

.equ	SREG	= 0x3f
.equ	SPL	= 0x3d
.equ	OCR0B	= 0x3c
.equ	GIMSK	= 0x3b
.equ	EIFR	= 0x3a
.equ	TIMSK	= 0x39
.equ	TIFR	= 0x38
.equ	SPMCSR	= 0x37
.equ	OCR0A	= 0x36
.equ	MCUCR	= 0x35
.equ	MCUSR	= 0x34
.equ	TCCR0B	= 0x33
.equ	TCNT0	= 0x32
.equ	OSCCAL	= 0x31
.equ	TCCR0A	= 0x30
.equ	TCCR1A	= 0x2f
.equ	TCCR1B	= 0x2e
.equ	TCNT1L	= 0x2c
.equ	TCNT1H	= 0x2d
.equ	OCR1AL	= 0x2a
.equ	OCR1AH	= 0x2b
.equ	OCR1BL	= 0x28
.equ	OCR1BH	= 0x29
.equ	CLKPR	= 0x26
.equ	ICR1L	= 0x24
.equ	ICR1H	= 0x25
.equ	GTCCR	= 0x23
.equ	TCCR1C	= 0x22
.equ	WDTCR	= 0x21
.equ	PCMSK	= 0x20
.equ	EEAR	= 0x1e
.equ	EEDR	= 0x1d
.equ	EECR	= 0x1c
.equ	PORTA	= 0x1b
.equ	DDRA	= 0x1a
.equ	PINA	= 0x19
.equ	PORTB	= 0x18
.equ	DDRB	= 0x17
.equ	PINB	= 0x16
.equ	GPIOR2	= 0x15
.equ	GPIOR1	= 0x14
.equ	GPIOR0	= 0x13
.equ	PORTD	= 0x12
.equ	DDRD	= 0x11
.equ	PIND	= 0x10
.equ	USIDR	= 0x0f
.equ	USISR	= 0x0e
.equ	USICR	= 0x0d
.equ	UDR	= 0x0c
.equ	UCSRA	= 0x0b
.equ	UCSRB	= 0x0a
.equ	UBRRL	= 0x09
.equ	ACSR	= 0x08
.equ	UCSRC	= 0x03
.equ	UBRRH	= 0x02
.equ	DIDR	= 0x01
.equ    TCCR0   =TCCR0B ;для совместимости с AT90S2313	

	;Семисегментные коды для индикатора с общим катодом

	.EQU KN_0=0x3F  
	.EQU KN_1=0x06  
	.EQU KN_2=0x5B  
	.EQU KN_3=0x4F  
	.EQU KN_4=0x66  
	.EQU KN_5=0x6D  
	.EQU KN_6=0x7D  
	.EQU KN_7=0x07  
	.EQU KN_8=0x7F  
	.EQU KN_9=0x6F  
	.EQU KN_A=0x77  
	.EQU KN_B=0x7C  
	.EQU KN_C=0x39  
	.EQU KN_D=0x5E  
	.EQU KN_E=0x79  
	.EQU KN_F=0x71
        
	;Семисегментные коды для индикатора с общим анодом

	.EQU AN_0=0x00C0  
	.EQU AN_1=0x00F9  
	.EQU AN_2=0x00A4  
	.EQU AN_3=0x00B0  
	.EQU AN_4=0x0099  
	.EQU AN_5=0x0092  
	.EQU AN_6=0x0082  
	.EQU AN_7=0x00F8  
	.EQU AN_8=0x0080  
	.EQU AN_9=0x0090  
	.EQU AN_A=0x0088  
	.EQU AN_B=0x0083  
	.EQU AN_C=0x00C6  
	.EQU AN_D=0x00A1  
	.EQU AN_E=0x0086  
	.EQU AN_F=0x008E
        
        .CSEG

	.ORG 0x00	;Сброс
	rjmp 0x30	;
	.ORG 0x01	;Вход INT0
        reti		;
	.ORG 0x02	;Вход INT1
	reti		;
	.ORG 0x03	;Захват счетчика Т1
        rjmp ADC1	;
	.ORG 0x04	;Совпадение счетчика Т1
        reti		;
        .ORG 0x05	;Переполнение счетчика Т1
        rjmp ADC2	;
	.ORG 0x06	;Переполнение счетчика Т0
	rjmp DISP	;
        .ORG 0x07	;UART,прием завершен
	reti		;
	.ORG 0x08	;UART,регистр данных пуст
	reti		;
	.ORG 0x09	;UART,передача завершенна
	reti		;
	.ORG 0x0a	;Аналоговый компаратор
	reti		;
        .ORG 0x0b	;
	reti		;
        .ORG 0x0c	;
	reti		;
	.ORG 0x0d	;
	reti		;
	.ORG 0x0e	;
	reti		;
	.ORG 0x0f	;
	reti		;
	.ORG 0x10	;
	reti		;
	.ORG 0x11	;
	reti		;
        .ORG 0x12	;
	reti		;

	.CSEG
	.ORG 0x30	;Начало 

	cli		;
	ldi r20, 0xdf	;
	out SPL, r20	;
	ldi r20, 0x91	;отключение компаратора
	out ACSR, r20	;
	clr r20		;запрет внешних прерываний
	out GIMSK, r20	;
	ldi r20, 0xff	;
	out DDRB, r20	;
	ldi r20, 0xff	;
	out PORTB, r20	;
        ldi r20, 0x3f	;  
	out DDRD, r20	;
        ldi r20, 0x20	;
	out PORTD, r20	;	
        ldi r20, 0x0e	;настройка сторожевого таймера
	out WDTCR, r20	;
	clr r25		;очистка флагового регистра АЦП
	clr r20		;
	sts 0x0069, r20	;
	sts 0x0067, r20	;
	out TCNT1H, r20	;
	out TCNT1L, r20	;
	sts 0x006a, r20	;
	ldi r20, 0x02	;разрешение прерывания от Т0
        out TIMSK, r20	;
	ldi r20, 0x04	;разрешение счета Т0
        out TCCR0, r20	;
	ldi r20, 0x00	;константа без делителя
	sts 0x006b, r20	;
	ldi r20, 0x00	;константа с делителем
	sts 0x006c, r20	;
	ldi r20, 0x20	;
	sts 0x0068, r20	;
	                ;/семисегментные коды
	ldi r20, AN_0	;
	sts 0x0070, r20	;
	ldi r20, AN_1	;
	sts 0x0071, r20	;
	ldi r20, AN_2	;
	sts 0x0072, r20	;
	ldi r20, AN_3	;
	sts 0x0073, r20	;
	ldi r20, AN_4	;
	sts 0x0074, r20	;
	ldi r20, AN_5	;
	sts 0x0075, r20	;
	ldi r20, AN_6	;
	sts 0x0076, r20	;
	ldi r20, AN_7	;
	sts 0x0077, r20	;
	ldi r20, AN_8	;
	sts 0x0078, r20	;
	ldi r20, AN_9	;
	sts 0x0079, r20	;
	ldi r20, AN_A	;
	sts 0x007a, r20	;
	ldi r20, AN_B	;
	sts 0x007b, r20	;
	ldi r20, AN_C	;
	sts 0x007c, r20	;
	ldi r20, AN_D	;
	sts 0x007d, r20	;
	ldi r20, AN_E	;
	sts 0x007e, r20	;
	ldi r20, AN_F	;
	sts 0x007f, r20	;
			;/семисегментные коды
	sei		;

	ldi r20, AN_8	;
	sts 0x0061, r20	;
        ldi r20, AN_0	;
	sts 0x0062, r20	;
	ldi r20, AN_4	;
	sts 0x0063, r20	;
	ldi r20, AN_1	;
	sts 0x0064, r20	;
	
	ldi r20, 0xff	;
	sts 0x0069, r20	;
s1:	lds r20, 0x0069	;
	tst r20		;
	brne s1         ;
	rcall CLRSCR	;

s3:	rcall SADC	;
	nop             ;
	rjmp s3		;

	                ;автозапуск АЦП
SADC:	sbrc r25, 0	;
	ret		;если ацп запущен
	lds r16, 0x0068	;
	tst r16		;
	breq sa1	;
	ret		;
sa1:	cli		;
	in r1, SREG	;
        sbr r25, 0x01	;ацп запущен
	;ldi r16, 0x0c	;загрузка счетчика ацп
	;sts 0x0068, r16	;запуск преобразования через каждые 98,3 мс 
        clr r16		;сброс флагов прерывания
	out TIFR, r16	;
	;out TCNT1H, r16	;
	;out TCNT1L, r16	;
	ldi r16, 0x8a	;разрешение прерываний Т0,Т1
        out TIMSK, r16	;
	ldi r16, 0x02	;запуск счета
        out TCCR1B, r16	;
        cbi PORTD, 5	;запуск интегратора
	out SREG, r1	;
	sei		;
	ret		;
	
                        ;вывод на индикатор
DISP:	wdr		;
	in r1, SREG	;
	push r16	;
	push r17	;
	push r18	;
	push r19	;
	push r20	;
	push r21	;
	push r26	;
	push r27	;
	lds r18, 0x0068	;
	tst r18		;
	breq d1		;
	dec r18		;
	sts 0x0068, r18	;
d1:	lds r18, 0x0069	;
	tst r18		;
	breq d2		;
	dec r18		;
	sts 0x0069, r18	;
d2:	lds r18, 0x006a	;счетчик тиков
	clc		;
	cpi r18, 0x3e	;
	brsh d3		;больше или равно 61
	inc r18		;меньше 61
	sts 0x006a, r18	;счетчик тиков
	ser r18		;
	sts 0x0060, r18	;установка маски
	rjmp d4		;
d3:	clc		;больше 61
	cpi r18, 0x7a	;
	brsh d8		;больше или равно 122
	inc r18		;меньше 122
	sts 0x006a, r18	;счетчик тиков
	clr r18		;
	sts 0x0060, r18	;сброс маски
	rjmp d4		;
d8:	clr r18		;больше 122        
        sts 0x006a, r18	;сброс счетчика
d4:	ldi r16, 0x04	;кол-во индикаторов
	ldi r17, 0x01	;первый индикатор
	clr r27		;
	ldi r26, 0x61	;начальный адрес ОЗУ индикатора
d7:	in r18, PORTD	;
	andi r18, 0xf0  ;
	or r18, r17	;выделение номера индикатора
	out PORTD, r18	;включение индикатора
	ld r19, X+	;загрузка семисегментного кода
	lds r20, 0x0067	;маска индикаторов
	or r19, r20	;
	out PORTB, r19	;включение сегментов
	ldi r21, 0x04	;
d6:	ldi r20, 0xff	;
d5:	dec r20		;
	tst r20		;
	nop		;
	nop		;
	brne d5		;задержка 190 мкс
	dec r21		;
	tst r21		;
	brne d6		;суммарная задержка.760 мкс свечения каждого индикатора. 
	lsl r17		;следующий индикатор
	dec r16		;
	tst r16		;
	brne d7		;
	ser r18		;
	out PORTB, r18	;гашение сегментов
	in r18, PORTD	;
	andi r18, 0xf0	;	
	out PORTD, r18	;отключение всех индикаторов
d10:	pop r27		;
	pop r26		;
	pop r21		;
	pop r20		;
	pop r19		;
	pop r18		;
	pop r17		;
	pop r16		;
	out SREG, r1	;
	reti		;

	                ;конвертор HEX - BCD - семисегментный код
UBCD:	in r1, SREG	;
	clr r8		;1d
	clr r9		;10d
	clr r10		;100d
	clr r11		;1000d
	lds r16, 0x0065	;младшая часть, binary
	lds r17, 0x0066	;старшая часть, binary
	mov r18, r16	;
	mov r19, r17	;
	clc		;
u2:	sbci r16, 0xe8	;
	sbci r17, 0x03	;1000d
	brcs u1		;
	inc r11		;+1000d
	mov r18, r16	;
	mov r19, r17	;
        rjmp u2		;
u1:	clc		;
	mov r16, r18	;
	mov r17, r19	;
u4:	sbci r16, 0x64	;
	sbci r17, 0x00	;100d
	brcs u3		;
        inc r10		;+100d
        mov r18, r16	;
	mov r19, r17	;
	rjmp u4		;
u3:	clc		;
	mov r16, r18	;
	mov r17, r19	;
u6:	sbci r16, 0x0a	;
	sbci r17, 0x00	;10d
	brcs u5		;
	inc r9		;+10d
        mov r18, r16	;
	mov r19, r17	;
	rjmp u6		;
u5:	clc		;
	mov r16, r18	;
	mov r17, r19	;
        mov r8, r16	;+1d
	clr r27		;
	ldi r26, 0x61	;начальный адрес озу индикаторов
	clr r31		;
	ldi r30, 0x70	;начальный адрес таблицы символов
	add r30, r8	;1d
	ld r16, Z	;
	st X+, r16	;запись 1d 
	ldi r30, 0x70	;
	add r30, r9	;10d
        ld r16, Z	;
	st X+, r16	;запись 10d 
	ldi r30, 0x70	;
	add r30, r10	;100d
        ld r16, Z	;
	st X+, r16	;запись 100d 
	ldi r30, 0x70	;
	add r30, r11	;1000d
        ld r16, Z	;
	clc		;	
	cpi r16, AN_0	;
	brne u7		;
	sbrc r25, 1	;
	ser r16		; 
u7:	st X, r16	;запись 1000d 
        bst r25, 2	;
	brts u8		;
	clr r16		;
	sts 0x0067, r16	;
	rjmp u9		;
u8:	lds r16, 0x0060	;
        sts 0x0067, r16	;
u9:	out SREG, r1	;	
	ret		;

	                ;окончание преобразования, захват
ADC1:	in r1, SREG	;
	push r8		;
	push r9		;
	push r10	;
	push r11	;
	push r16	;
	push r17	;
	push r18	;
	push r19	;
	push r20	;
	push r21	;
	push r26	;
	push r27	;
	push r30	;
	push r31	;
	clr r16		;
        out TCCR1B, r16	;остнановка счета
        out TCNT1H, r16	;очистка счетчика
	out TCNT1L, r16	;очистка счетчика
	ldi r16, 0x02	;
        out TIMSK, r16	;запрет прерываний Т1
	sbi PORTD, 5	;сброс интегратора
	ldi r16, 0x0c	;загрузка счетчика ацп
	sts 0x0068, r16	;запуск преобразования через каждые 98,3 мс 
;	ldi r16, 0xff	;
;ad20:	dec r16		;
;	tst r16		;
;	brne ad20	;
;	clr r16		;
;	out TIFR, r16	;
	in r16, ICR1L	;
	in r17, ICR1H	;
	bst r25, 1	;
	brts ad1	;если делитель включен
	                ;/делитель выключен/
	ldi r18, 0x0f   ;
	ldi r19, 0x27   ;9,999V
        clc		;
	sbc r18, r16	;
	sbc r19, r17	;
	brcs ad2	;если >9,999V
	                ;U<9,999V
	cbr r25, 0x04	;сброс флага переполнения
			;/компенсация погрешности/
	lds r18, 0x006b	;загрузка константы
	sbrs r18, 7	;
	rjmp ad7	;
	                ;отрицательное значение константы
	mov r20, r16	;
	mov r21, r17	;
	cbr r18, 0x80	;
	clc		;
	sbc r20, r18	;
	sbci r21, 0x00	;
	brcs ad8	;
	mov r16, r20	;
	mov r17, r21	;
	rjmp ad9	;
ad8:	clc		;
	clr r16		;
	clr r17		;
	rjmp ad9	;
                        ;положительное значение константы
ad7:	clc		;                
        add r16, r18	;
	clr r18		;
	adc r17, r18	;
	brcs ad2	;если сумма превысила 9,999V
        		;/компенсация погрешности/
ad9:	sts 0x0065, r16	;
	sts 0x0066, r17	;
	rcall UBCD	;
	rcall DOT	;
	rjmp adex	;
			;U>9,999V
ad2:	clc		;
	sbi PORTD, 4	;включение делителя
	sbr r25, 0x02	;установка флага делителя
	rjmp adex	;
			;/делитель включен/ 
ad1:	ldi r18, 0xd4   ;
	ldi r19, 0x03   ;09,80V
	clc		;
	sbc r18, r16	;
	sbc r19, r17	;
	brcs ad3	;если >09,80V
	                ;<09,80V
	cbi PORTD, 4	;отключение делителя
	cbr r25, 0x02	;сброс флага делителя
        cbr r25, 0x04	;сброс флага переполнения
        rjmp adex	;
			;>09,80V
ad3:	ldi r18, 0x0f   ;
	ldi r19, 0x27   ;99,99V
        clc		;
	sbc r18, r16	;
	sbc r19, r17	;
	brcs ad4	;если >99,99V
			;<99,99V
	cbr r25, 0x04	;сброс флага переполнения
	sbi PORTD, 4	;включение делителя
	sbr r25, 0x02	;установка флага делителя
			;/компенсация погрешности/
	lds r18, 0x006c	;загрузка константы
        sbrs r18, 7	;
	rjmp ad5	;
	                ;отрицательное значение константы
	mov r20, r16	;
	mov r21, r17	;
	cbr r18, 0x80	;
	clc		;
	sbc r20, r18	;
	sbci r21, 0x00	;
	brcs ad6	;
	mov r16, r20	;
	mov r17, r21	;
	rjmp ad10	;
ad6:	clc		;
	clr r16		;
	clr r17		;
	rjmp ad10	;
                        ;положительное значение константы
ad5:	clc		;                
        add r16, r18	;
	clr r18		;
	adc r17, r18	;
	brcs ad4	;если сумма превысила 99,99V
			;/компенсация погрешности/
ad10:	sts 0x0065, r16	;
	sts 0x0066, r17	;
	rcall UBCD	;
	rcall DOT	;
        rjmp adex	;
			;>99,99V
ad4:	clc		;
	sbr r25, 0x04	;установка флага переполнения
	ldi r16, 0x0f	;
	ldi r17, 0x27	;
        sts 0x0065, r16	;
	sts 0x0066, r17	;
	rcall UBCD	;
adex:	cbr r25, 0x01	;ацп остановлен
	pop r31		;
	pop r30		;
	pop r27		;
	pop r26		;
	pop r21		;
	pop r20		;
	pop r19		;
	pop r18		;
	pop r17		;
	pop r16		;
	pop r11		;
	pop r10		;
	pop r9		;
	pop r8		;
	out SREG, r1	;
	reti		;
        	
	                ;окончание преобразования, переполнение
ADC2:	in r1, SREG	;
	push r16	;
	clr r16		;
        out TCCR1B, r16	;остнановка счета
        out TCNT1H, r16	;
	out TCNT1L, r16	;
	sts 0x0065, r16	;младшая часть, binary
	sts 0x0066, r16	;старшая часть, binary
	ldi r16, 0x02	;запрет прерываний Т1
        out TIMSK, r16	;
	ldi r16, 0x0c	;загрузка счетчика ацп
	sts 0x0068, r16	;запуск преобразования через каждые 98,3 мс 
	sbi PORTD, 5	;сброс интегратора
;	ldi r16, 0xff	;
ac1:	dec r16		;
;	tst r16		;
;	brne ac1	;
;	clr r16		;
;	out TIFR, r16	;
	rcall UBCD	;
	cbr r25, 0x01	;ацп остановлен
	ldi r16, 0x0c	;загрузка счетчика ацп
	sts 0x0068, r16	;запуск преобразования через каждые 98,3 мс 
	pop r16		;
	out SREG, r1	;
	reti		;
    	
	                ;очистка озу индикаторов
CLRSCR:	push r20	;
	push r26        ;
	push r27        ;
	ser r20		;
	clr r27		;
	ldi r26, 0x61	;
	st X+, r20	;
	st X+, r20	;
	st X+, r20	;
	st X, r20	;
	pop r27         ;
	pop r26         ;
	pop r20		;
	ret		;
	
	                ;переключение децимальной точки
DOT:	bst r25, 1	;
	brts dl1	;
	lds r16, 0x0064	;
	cbr r16, 0x80	;
	sts 0x0064, r16	;
	rjmp dl2	;
dl1:	lds r16, 0x0063	;
	cbr r16, 0x80	;
	sts 0x0063, r16	;
dl2:	ret		;
	

        .EXIT
