;;
.include "tn2313def.inc"								;Используемый контроллер - ATTiny2313;
										;константы - для удобства;
.equ vol_addr= 0b00000000;;
;;
.equ lr_addr = 0b11000000;;
.equ rr_addr = 0b11100000;;
.equ lf_addr = 0b10000000;;
.equ rf_addr = 0b10100000;;
;;
.equ treb_addr = 0b01110000;;
.equ bass_addr = 0b01100000;;
.equ audio_addr= 0b01000000;;
;;
;=================					; Константы I2C
.equ	SCLP	= 5										; SCL вывод (порт D);
.equ	SDAP	= 4										; SDA вывод (порт D);
.equ	b_dir	= 0										
.equ	i2crd	= 1;;
.equ	i2cwr	= 0;;
; Регистры I2C
.def	i2cdelay= r22									; Задержка цикла;
.def	i2cdata	= r23									; Регистр данных
.def	i2cadr	= r24									; Регистр адреса и направления
.def	i2cstat	= r27									; Регистр сатуса
;;
;=================;		Константы и регистры RC5 
;00110000 - TV											;таблица кодов со стандартного пульта 
;10110000 - Mute;
;01100100 - Sleep;
;00001000 - Volume up;
;10001000 - Volume down;
;00000100 - Channel up;
;10000100 - Channel down;
;=================;
.equ	INPUT	=0					    				;PD0 - вывод, куда приходит сигнал
.equ	SYS_ADDR=0										;Системный адрес устройства (не используется. =0);
.def	S		=R0;;
.def	inttemp	=R1;;
.def	ref1	=R2;;
.def	ref2	=R3;;
.def	temp	=R16;;
.def	timerL	=R17;;
.def	timerH	=R16;;
.def	system	=R19;;
.def	command	=R20									;Регистр, в который сохраняется принятый сигнал пульта;
.def	bitcnt	=R21;;
;=================;Остальные регистры
.def	data		=r29;регистр данных для передачи по I2C
.def	addr		=r25;регистр адреса для передачи по I2C
.def	lcd_count	=r24;счётчик символов ЖКИ
.def	vol_left_rear	=r9;левая громкость тыла
.def	vol_right_rear	=r8;правая громкость тыла
.def	vol_left_front	=r7;левая громкость фронта
.def	vol_right_front	=r7;правая громкость фронта
.def	vol_treble		=r6;тембр высоких частот
.def	vol_bass		=r5;тембр низких частот
.def	audio			=r4;состояние
.def	vol_all			=r10;общая громкость
;;
.org    0											;;
rjmp reset									; переход на начало программы;
;;
;=================;Инициализация таймера;
.org OVF0addr;;
TIM0_OVF:	;;
		in	S,sreg;;
		inc	timerL					;;
		inc	inttemp;;
		brne	TIM0_OVF_exit;;
		inc	timerH;;
;=================
TIM0_OVF_exit:;;
		out	sreg,S;;
		reti;;
;=================; Инициализация ЖКИ;
initlcd:;;
	rcall ddelay;;
	rcall ddelay;;
	ldi addr,$30 		
	rcall icom_2313 		;;
	rcall delay;;
	ldi addr,$30 		
	rcall icom_2313 		;;
	rcall delay;;
	ldi addr,$30 		
	rcall icom_2313 		;;
	rcall ddelay;;
;;
	ldi	addr,0b00101000 	
	rcall icom_2313 		
;;
	ldi addr,0b00001100		
	rcall icom_2313;;
		;;
	ldi addr,0b00000110 	
	rcall icom_2313		;;
;;
	ldi addr,0b00000010 	   ;
	rcall icom_2313;;
;;
ret							
;=================; Инициализация ;
reset:;;
	ldi temp,low(RAMEND)					 ;инициализация стека;
	out	SPL,temp			;;
	ldi	temp,1								 ;Таймер/счетчик 0 в режиме счётчика;
	out	TCCR0,temp;;
	ldi	temp,1<<TOIE0						 ;Разрашение прерывания по переполнению счётчика;
	out	TIMSK,temp;;
;;
    ser data            				 	 ;настроить порт B на вывод;
    out ddrb,data;;
  	ldi data,0b01111110	;;
    out ddrd,data 						     ;настроить порт D на вывод (1,2,3,6 выводы);
 	ldi data,0b01001110						 ;настроить порт D на вывод (1,2,3,6 выводы);
    out portd,data;;
    rcall initlcd							 ;вызов подпрограммы инициализации ЖКИ;
sei	;Глобальное разрешение прерываний
;=================; Запись в регистры начальных значений громкости, тембра, состояния и т.д.
	ldi temp,0b01011000;;
	mov audio,temp
	ldi temp,0b00000111;;
	mov vol_left_rear,temp;;
	mov vol_right_rear,temp;;
	mov vol_left_front,temp;;
	mov vol_right_front,temp;;
	ldi temp,0b00000100;;
	mov vol_bass,temp;;
	mov vol_treble,temp;;
	ldi temp,0b00111000;;
	mov vol_all,temp;;
; Запись этих значений в регистры TDA7313
	ldi data,audio_addr;;
	or data,audio;;
	rcall i2c_trance;;
	ldi data,lr_addr;;
	or data,vol_left_rear;;
	rcall i2c_trance;;
	ldi data,rr_addr;;
	or data,vol_right_rear;
	rcall i2c_trance;;
	ldi data,lf_addr;;
	or data,vol_left_front;;
	rcall i2c_trance;;
	ldi data,rf_addr;;
	or data,vol_right_front;;
	rcall i2c_trance;;
	ldi data,treb_addr;;
	or data,vol_treble;;
	rcall i2c_trance;;
	ldi data,bass_addr;;
	or data,vol_bass;;
	rcall i2c_trance;;
	ldi data,vol_addr;;
	or data,vol_all;;
	rcall i2c_trance;;
;=================	 ;Начало основной программы;
	rcall clean				;очистка экрана;
	ldi r30,low(l_intro1*2)	;установить указатель Z на начало буфера l_intro1;
    ldi r31,high(l_intro1*2);для вывода 1 строки заставки ;
    ldi lcd_count,16 ;;
	rcall ddram;;
	ldi addr,0b11000000      ;данные записываются в DDRAM с начала второй строки;
    rcall icom_2313	;;
	ldi lcd_count,16 ;;
	ldi r30,low(l_intro2*2)  ;установить указатель Z на начало буфера l_intro2;
    ldi r31,high(l_intro2*2) ;для вывода 2 строки заставки;
    rcall ddram;;
	rcall ddelay;;
;================= Основной цикл;
;=================;Общая громкость
volume_all:								; общая громкость - вывод надписи на ЖКИ;
	rcall clean				
	ldi r30,low(l_volume*2) 
    ldi r31,high(l_volume*2)			
    ldi lcd_count,10 ;;
	rcall ddram;;
	rcall delay				
;
volume_all_nc:				; общая громкость - вывод полоски значения на ЖКИ;
	rcall clean_2;;
    mov temp,vol_all;;
	ldi data,0b00111111;;
	sub data,temp;;
	mov temp,data;;
cont:	;;
	cpi temp,0b00000100;;
	brlo volume_all_l;;
	asr temp;;
	asr temp;;
	brcc nmax_vol;;
	inc temp;;
nmax_vol:;;
mov lcd_count,temp;;
ldi r30,low(l_bar*2)    						
ldi r31,high(l_bar*2);;
rcall ddram;;
;
volume_all_l:;Общая громкость - приём и анлиз данных, принятых с пульта или клавиш
rcall scan								;;
cpi command,0b00010000;;
breq vol_all_down;;
cpi command,0b00010001;;
breq vol_all_up;;
cpi command,0b00001100;;
breq treble;;
cpi command,0b00100000;;
breq vol_all_channel_up;;
cpi command,0b00100001;;
breq vol_all_channel_down;;
rjmp volume_all_l
;
vol_all_channel_up:;Следующий канал
	rcall channel_up;
	rjmp volume_all;;
vol_all_channel_down:;Предыдущий канал
	rcall channel_down;;
	rjmp volume_all;;
vol_all_up:	;;Громкость вверх
	ldi temp,0b00111111;;
	cp vol_all,temp;;
	breq vol_all_trance;;
	inc vol_all;;
	rjmp vol_all_trance;;
vol_all_down:;Громкость вниз
	ldi temp,0b00000000;;
	cp vol_all,temp;;
	breq vol_all_trance	;;
	dec vol_all;;
	rjmp vol_all_trance;;
vol_all_trance:	;Запись громкости в TDA7313
	ldi data,vol_addr;;
	or data,vol_all;;
	rcall i2c_trance;;
;;
rjmp volume_all_nc;;
;=================; вывод надписи "тембр "
wtembr:
	ldi r30,low(l_tembr*2) 
    ldi r31,high(l_tembr*2)				;;
    ldi lcd_count,6 ;;
	rcall ddram;;
ret;;
;=================;Тембр высоких частот
treble:						;тембр высоких - вывод надписи на ЖКИ
	rcall clean				
	rcall wtembr			
	ldi r30,low(l_treble*2) 
    ldi r31,high(l_treble*2)				;;
    ldi lcd_count,7 ;;
	rcall ddram;;
	rcall delay				
							
treble_nc:					;тембр высоких - вывод полоски значения на ЖКИ
	rcall clean_2;;
 	mov temp,vol_treble;;
;;
	ldi data,0b00001111;;
	sub data,temp;
	mov temp,data;
;;
	cpi temp,0;
	breq treble_l;
	mov lcd_count,temp
	ldi r30,low(l_bar*2) 
    ldi r31,high(l_bar*2);
	rcall ddram;;
;
treble_l:;Тембр высоких - приём и анлиз данных, принятых с пульта или клавиш
	rcall scan	;;
	cpi command,0b00010000;;
	breq treble_down;;
	cpi command,0b00010001;;
	breq treble_up;;
	cpi command,0b00001100;;
	breq bass;;
    cpi command,0b00100000;;
	breq treble_channel_up;;
    cpi command,0b00100001;;
	breq treble_channel_down;;
;
rjmp treble_l;;
;
treble_channel_up:;Тембр высоких - следующий канал
	rcall channel_up;;
	rjmp treble;;
treble_channel_down:;предыдущий канал
	rcall channel_down;;
	rjmp treble;;
;;
treble_up:	;;Тембр высоких - вверх
	ldi temp,0b00001111;;
	cp vol_treble,temp;;
	breq treble_trance;;
	inc vol_treble;;
	rjmp treble_trance;;
;;
treble_down:;;Тембр высоких - вниз
	ldi temp,0b00000000;;
	cp vol_treble,temp;;
	breq treble_trance	;;
	dec vol_treble;;
	rjmp treble_trance;;
;;
treble_trance:;	Тембр высоких - сохранение в TDA7313
	ldi data,treb_addr;;
	or data,vol_treble;;
	rcall i2c_trance;;
;;
rjmp treble_nc;;
;=================; Промежуточная метка - переход к началу - регулировке общей громкости
volume_all_to:
rjmp volume_all
;=================; Тембр низких частот
bass:								;тембр низких - вывд надписи на ЖКИ
	rcall clean				
	rcall wtembr;;
	ldi r30,low(l_bass*2) 
    ldi r31,high(l_bass*2)		
    ldi lcd_count,7 ;;
	rcall ddram;;
	rcall delay			
						;;
bass_nc:	;тембр низких - вывод полоски значения на ЖКИ
	rcall clean_2;;
	mov temp,vol_bass;;
;;
	ldi data,0b00001111;;
	sub data,temp;;
	mov temp,data;;
;;
	cpi temp,0;;
	breq bass_l;;
	mov lcd_count,temp;;
	ldi r30,low(l_bar*2)    
    ldi r31,high(l_bar*2);;
	rcall ddram;;
;;
bass_l:;тембр низких - приём и анлиз данных, принятых с пульта или клавиш
	rcall scan								;;
	cpi command,0b00010000;;
	breq bass_down;;
	cpi command,0b00010001;;
	breq bass_up;;
	cpi command,0b00001100;;
	breq volume_all_to;;
    cpi command,0b00100000;;
	breq bass_channel_up;;
    cpi command,0b00100001;;
	breq bass_channel_down;;
rjmp bass_l;;
;;
bass_channel_up:; тембр низких - следующий канал
	rcall channel_up;;
	rjmp bass;;
bass_channel_down:; тембр низких - предыдущий канал
	rcall channel_down;;
	rjmp bass;;
;
bass_up:	;;тембр низких - вверх
	ldi temp,0b00001111;;
	cp vol_bass,temp;;
	breq bass_trance;;
	inc vol_bass;;
	rjmp bass_trance;;
bass_down:; тембр низких - вниз
	ldi temp,0b00000000;;
	cp vol_bass,temp;;
	breq bass_trance	;;
	dec vol_bass;;
	rjmp bass_trance;;
bass_trance:; тембр низких - сохранение в TDA7313
	ldi data,bass_addr;;
	or data,vol_bass;;
	rcall i2c_trance;;
rjmp bass_nc;;
;=================; подпрограмма - Вывод надписи "КАНАЛ"
wchannel:;;
	rcall clean;;
    ldi r30,low(l_channel*2)    					
    ldi r31,high(l_channel*2)					
    ldi lcd_count,6 ;;
	rcall ddram;;
ret;;
;=================; Переключение каналов
channel_up:	;Переключение на следующий канал
	rcall wchannel;;
	ldi temp,0b01011000;;
	or	temp,audio;;
	cpi temp,0b01011011;;
	breq up_to_zero;;
	inc audio;;
	rjmp channel;;
	up_to_zero:;;
	ldi temp,0b01011000;;
	and audio,temp	;;
	rjmp channel;;
channel_down:; Переключение на предыдущий канал
	rcall wchannel;;
	ldi temp,0b01011000;;
	or	temp,audio;;
	cpi temp,0b01011000;;
	breq dec_to_zero;;
	dec audio;;
	rjmp channel;;
	dec_to_zero:;;
	ldi temp,0b01000011	;;
	or audio,temp;;
	rjmp channel;;
channel:;Вывод на ЖКИ номера канала
	ldi temp,0b01011000;;
	or	temp,audio;;
	cpi temp,0b01011000;;
	breq to1;;
	cpi temp,0b01011001;;
	breq to2;;
	cpi temp,0b01011010;;
	breq to3;;
	cpi temp,0b01011011;;
	breq to4;;
	rjmp to1
to4:;;
	ldi addr,$34					;4;
	rcall idat_2313;;
	rjmp channel_end;;
to3:;;
	ldi addr,$33					;3;
	rcall idat_2313;;
	rjmp channel_end;;
to2:;;
	ldi addr,$32					;2;
	rcall idat_2313;;
	rjmp channel_end;;
to1:;;
	ldi addr,$31					;1;
	rcall idat_2313;;
	rjmp channel_end;;
;;
channel_end:; Запись данных в TDA7313
	ldi data,audio_addr;;
	or data,audio;;
	rcall i2c_trance;;
	rcall ddelay
	ret												;
;=================;;Подпрограммs очистки памяти ЖКИ;
clean:										; Очистка памяти и экрана ЖКИ	
	ldi addr,0b10000000      				;;
    rcall icom_2313 ;;
	ldi lcd_count,16;;
	ldi r30,low(l_cln*2)    						
    ldi r31,high(l_cln*2)			;;
	rcall ddram;;
	ldi addr,0b10000000      				;;
    rcall icom_2313 	;;
	ret;;
;
clean_2:;; Очистка пасями и экрана ЖКИ для второй строки
	ldi addr,0b11000000           				
    rcall icom_2313								
	ldi lcd_count,16;;
	ldi r30,low(l_cln*2)    						
    ldi r31,high(l_cln*2);;
	rcall ddram;;
	ldi addr,0b11000000           				
    rcall icom_2313	;;
	ret;;
;=================;		;Подпрограммы для работы протокола из стандартного файла библиотеки ATMEL
;(…\Atmel\AVR Tools\AvrAssembler\Appnotes\avr410.asm)
detect:	clr	inttemp;;
		clr	timerH;;
detect1:clr	timerL;;
detect2:cpi	timerH,8					;If line not idle within 131ms;
		brlo	dl1;;
		rjmp	fault					;then exit;
dl1:	cpi	timerL,55					;If line low for 3.5ms;
		brge	start1					;then wait for start bit;
		sbis	PIND,INPUT				;If line is;
		rjmp	detect1					;low  - jump to detect1;
		rjmp	detect2					;high - jump to detect2;
start1:	cpi	timerH,8					;If no start bit detected;
		brge	fault					;within 130ms then exit;
		sbic	PIND,INPUT				;Wait for start bit;
		rjmp	start1;;
		clr	timerL					;Measure length of start bit;
start2:	cpi	timerL,17					;If startbit longer than 1.1ms,;
		brge	fault					;exit;
		sbis	PIND,INPUT;;
		rjmp	start2;;
								;Positive edge of 1st start bit;
		mov	temp,timerL				;timer is 1/2 bit time;
		clr	timerL;;
		mov	ref1,temp;;
		lsr	ref1;;
		mov	ref2,ref1;;
		add	ref1,temp				;ref1 = 3/4 bit time;
		lsl	temp;;
		add	ref2,temp				;ref2 = 5/4 bit time;
start3:	cp	timerL,ref1					;If high periode St2 &gt; 3/4 bit time
		brge	fault					;exit;
		sbic	PIND,INPUT				;Wait for falling edge start bit 2;
		rjmp	start3;;
		clr	timerL;;
		ldi	bitcnt,12					;Receive 12 bits;
		clr	command;;
		clr	system;;
sample:	cp	timerL,ref1					;Sample INPUT at 1/4 bit time;
		brlo	sample;;
		sbic	PIND,INPUT	;;
		rjmp	bit_is_a_1				;Jump if line high;
bit_is_a_0:	clc						;Store a '0';
		rol	command;;
		rol	system;;
								;Synchronize timing;
bit_is_a_0a:	cp	timerL,ref2				;If no edge within 3/4 bit time;
		brge	fault					;exit;
		sbis	PIND,INPUT				;Wait for rising edge;
		rjmp	bit_is_a_0a				;in the middle of the bit;
		clr	timerL;;
		rjmp	nextbit;;
bit_is_a_1:	sec						;Store a '1';
		rol	command;;
		rol	system;;
 	 							;Synchronize timing;
bit_is_a_1a:cp	timerL,ref2					;If no edge within 3/4 bit time;
		brge	fault					;exit;
		sbic	PIND,INPUT				;Wait for falling edge;
		rjmp	bit_is_a_1a				;in the middle of the bit;
		clr	timerL;;
nextbit:dec	bitcnt						;If bitcnt &gt; 0
		brne	sample					;get next bit;
								;All bits sucessfully received!;
		mov	temp,command				;Place system bits in "system";
		rol	temp		;;
		rol	system;;
		rol	temp;;
		rol	system;;
		bst	system,5					;Move toggle bit;
		bld	command,6				;to "command";
								;Clear remaining bits;
		andi	command,0b01111111;;
		andi	system,0x1F;;
		ret;;
fault:	ser	command					;Both "command" and "system";
		ser	system					;0xFF indicates failure;
		ret;;
;=================; Подпрограммы приёма данных
scan:	;;с клавиатуры
	ldi command,0;;
	sbis pind,1;;
	ldi command,0b00100110 ;;
	sbis pind,2;;
	ldi command,0b00010000  ;;
	sbis pind,3;;
	ldi command,0b00010001 ;;
	sbis pind,6;;
	ldi command,0b00001100 ;;
	cpi command,0;;
	breq scan_rc5;;
	rcall delay;;
ret;;
;
scan_rc5:;; с пульта RC5
	rcall detect;;
	andi command,0x3F					
	cpi command,0x3f;;
	breq scan;;
ret	;;
;=================; Подпрограммы пауз
ddelay:;длинная пауза
        ldi r19,5;;
dd:		rcall delay;;
        dec r19;;
        brne dd;;
        ret	;;
del:	;малая пауза
        ldi r18,50            			
l4:     dec r18                 			;;
        brne l4                 			;;
        ret;;
delay:; средняя пауза
        ldi r17,50             			
l:      ldi r18,255             			;;
l1:     dec r18                 ;;
        brne l1                 ;;
        dec r17                 ;;
        brne l                  ;;
        ret;;
;=================; ;Подпрограммы для работы с ЖКИ
; (Часть взята с официального сайта Atmel - www.atmel.ru)
ddram:	;;Запись в видеопамять ЖКИ
cli;;
	lpm		                     	
    mov addr,r0;;
    rcall idat_2313        					
    rcall del;;
    ld r1,z+               							
    dec lcd_count                 				
    brne ddram  ;;
sei	            							;;
ret    

icom_2313:;;Передача команды на ЖКИ
    swap addr               							
    mov r26,addr;;
    andi r26,$ef            							
    ori  r26,$e0            						
;;
	out portb,r26	;;
    cbi portb, 5            							
    swap addr                						
    mov r26,addr;;
    andi r26,$ef            						
    ori  r26,$e0            						
;;
    out portb,r26;;
    cbi portb, 5            						
	rcall del;;
    ret;;
;;
idat_2313:;Передача данных на ЖКИ
    swap addr  			     							
    mov r26,addr	;;
    ori  r26,$f0        	 		   				
;;
	out portb,r26           						
    cbi portb,5           							
    swap addr             	 		   			 	
    mov r26,addr		;;
    ori  r26,$f0       	 	 						
;;
    out portb,r26      		   						
    cbi portb,5             						
	rcall del		;;
    ret;;
;=================; ;Подпрограммы работы I2C	
;Взяты из стандартного файла библиотеки ATMEL
;(…\Atmel\AVR Tools\AvrAssembler\Appnotes\avr410.asm)
i2c_trance:; Передача данных
;;
	ldi	i2cadr,0b10001000;
	rcall	i2c_start				

	mov	i2cdata,data			
	rcall	i2c_do_transfer		
	rcall	i2c_stop			
ret;;
;=================;	;
i2c_hp_delay:;;
	ldi	i2cdelay,2;;
i2c_hp_delay_loop:;;
	dec	i2cdelay;;
	brne	i2c_hp_delay_loop;;
	ret;;
i2c_qp_delay:;;
	ldi	i2cdelay,1	;;
i2c_qp_delay_loop:;;
	dec	i2cdelay;;
	brne	i2c_qp_delay_loop;;
	ret;;
i2c_rep_start:;;
	sbi	DDRD,SCLP				; force SCL low;
	cbi	DDRD,SDAP				; release SDA;
	rcall	i2c_hp_delay		; half period delay;
	cbi	DDRD,SCLP				; release SCL;
	rcall	i2c_qp_delay		; quarter period delay;
i2c_start:				;;
	mov	i2cdata,i2cadr			; copy address to transmitt register;
	sbi	DDRD,SDAP				; force SDA low;
	rcall	i2c_qp_delay		; quarter period delay;
i2c_write:;;
	sec							; set carry flag;
	rol	i2cdata					; shift in carry and out bit one;
	rjmp	i2c_write_first;;
i2c_write_bit:;;
	lsl	i2cdata					; if transmit register empty;
i2c_write_first:;;
	breq	i2c_get_ack			; goto get acknowledge;
	sbi	DDRD,SCLP				; force SCL low;
	brcc	i2c_write_low		; if bit high;
	nop							; (equalize number of cycles);
	cbi	DDRD,SDAP				; release SDA;
	rjmp	i2c_write_high;;
i2c_write_low:					; else;
	sbi	DDRD,SDAP				; force SDA low;
	rjmp	i2c_write_high		; (equalize number of cycles);
i2c_write_high:;;
	rcall	i2c_hp_delay		; half period delay;
	cbi	DDRD,SCLP				; release SCL;
	rcall	i2c_hp_delay		; half period delay;
	rjmp	i2c_write_bit;;
i2c_get_ack:;;
	sbi	DDRD,SCLP				; force SCL low;
	cbi	DDRD,SDAP				; release SDA;
	rcall	i2c_hp_delay		; half period delay;
	cbi	DDRD,SCLP				; release SCL;
i2c_get_ack_wait:;;
	sbis	PIND,SCLP			; wait SCL high ;
								;(In case wait states are inserted);
	rjmp	i2c_get_ack_wait;;
	clc							; clear carry flag;
	sbic	PIND,SDAP			; if SDA is high;
	sec							; set carry flag;
	rcall	i2c_hp_delay		; half period delay;
	ret;;
i2c_do_transfer:;;
	sbrs	i2cadr,b_dir		; if dir = write;
	rjmp	i2c_write			;goto write data;
i2c_read:;;
	rol	i2cstat					; store acknowledge;
								; (used by i2c_put_ack);
	ldi	i2cdata,0x01			; data = 0x01;
i2c_read_bit:					; do;
	sbi	DDRD,SCLP				; force SCL low;
	rcall	i2c_hp_delay		; half period delay;
	cbi	DDRD,SCLP				; release SCL;
	rcall	i2c_hp_delay		; half period delay;
	clc							; clear carry flag;
	sbic	PIND,SDAP			; if SDA is high;
	sec							; set carry flag;
	rol	i2cdata					; store data bit;
	brcc	i2c_read_bit		; while receive register not full;
i2c_put_ack:;;
	sbi	DDRD,SCLP				; force SCL low;
	ror	i2cstat					; get status bit;
	brcc	i2c_put_ack_low		; if bit low goto assert low;
	cbi	DDRD,SDAP				; release SDA;
	rjmp	i2c_put_ack_high;;
i2c_put_ack_low:				; else;
	sbi	DDRD,SDAP				; force SDA low;
i2c_put_ack_high:;;
	rcall	i2c_hp_delay		; half period delay;
	cbi	DDRD,SCLP				; release SCL;
i2c_put_ack_wait:;;
	sbis	PIND,SCLP			; wait SCL high;
	rjmp	i2c_put_ack_wait;;
	rcall	i2c_hp_delay		; half period delay;
	ret;;
i2c_stop:;;
	sbi	DDRD,SCLP				; force SCL low;
	sbi	DDRD,SDAP				; force SDA low;
	rcall	i2c_hp_delay		; half period delay;
	cbi	DDRD,SCLP				; release SCL;
	rcall	i2c_qp_delay		; quarter period delay;
	cbi	DDRD,SDAP				; release SDA;
	rcall	i2c_hp_delay		; half period delay;
	ret;;
i2c_init:;;
;;
	ldi i2cstat,0b01111110;;
	out	DDRD,i2cstat;;
;;
	clr	i2cstat				;;
	out	PORTD,i2cstat		; set I2C pins to open colector;
;;
;;
	ret;;
;=================;;Постоянные данные (слова для вывода на ЖКИ)
.org $300;;
l_cln:		.DB ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ';; Пустая строка из 80 символов
			.DB ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ';;
			.DB ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ';;
			.DB ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ';;
			.DB ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ';;
;;
l_bar:		.DB '*','*','*','*','*','*','*','*','*','*','*','*','*','*','*','*';; Строка из 16 символов "*"
;;
l_intro1:	.DB '"','H','O','B','A',$b1,' ','T','E','X','H',$a5,'K','A','"',' ';;"НОВАЯ ТЕХНИКА"
l_intro2:	.DB 'C','T','E','P','E','O','T','E','M',$a0,'P','O',$a0,$a7,'O','K';;"СТЕРЕОТЕМБРОБЛОК"
			;;
l_volume:	.DB $a1,'P','O','M','K','O','C','T','b',' ',' ',' ',' ',' ',' ',' ';;"ГРОМКОСТЬ"
l_tembr	:	.DB 'T','E','M',$a0,'P',' ',' ',' ';;"ТЕМБР"
l_bass	:	.DB 'H',$a5,$a4,'K',$a5,'E',' ',' ';;"НИЗКИЕ"
l_treble:	.DB 'B',$ae,'C','O','K',$a5,'E',' ';;"ВЫСОКИЕ"
l_channel:  .DB 'K','A','H','A',$a7,' ',' ',' ';;"КАНАЛ"
