;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
; Мега 328p
; кварц 16мгц внутренний делитьель отключен.
;
;
;
;
;**************************************************************************************************************
; подключаемые модули
;**************************************************************************************************************

.include 	"m328Pdef.inc"		; используем ATMega328p


;==============================================================================================================
; Настройка ОЗУ // RAM
;==============================================================================================================
;
;******************************************************************************
; настройка регистров
;******************************************************************************

.def	Temp =R16
.def	Temp1=R17
.def	Temp2=R18
.def	Temp3=R19
.def	Temp4=R20			; регистр для сохранения/чтения регистра SREG
.def	Temp5=R21 			; регисто для чтения/записи ЕЕПРОМ
.def	Temp6=R22			; 		
.def	Temp7=R23			; 		
.def	Temp8=R24			;



;******************************************************************************
; переменные
;******************************************************************************


 .dseg	; оперативка 

curr_ch: .byte 1			; номер текущего канала АЦП ( всего три канала 0,1,2 )





;******************************************************************************
; константы
;******************************************************************************


.equ	ADC_ADMUX = (1<<REFS0)|(0<<MUX0)			; константа для выбора канала АЦП

.equ	ADC_ADCSRA= (1<<ADEN)|(1<<ADSC)|(1<<ADIF)|(7<<ADPS0)	; константа для запуска АЦП ( запуск одиночного преобазования )



;==============================================================================================================
; программный сегмент // FLASH // 
;==============================================================================================================

.cseg	


;******************************************************************************
; прерывания 
;******************************************************************************	
	

.org 0					; External Pin, Power-on Reset, Brown-out Reset, and Watchdog Reset
rjmp reset				; старт программы
				


.org INT_VECTORS_SIZE			; конец векторов прерываний


;******************************************************************************
; старт
;******************************************************************************

reset:					; включение микроконтроллера


;******************************************************************************
; глобальный запрет прерываний
;******************************************************************************


	cli				; глобальный запрет на прерывания


;******************************************************************************
; стек, инициализация
;******************************************************************************

	ldi Temp, low(RAMEND)		; Инициализация СТЕКа
	out SPL, Temp
	ldi Temp, high(RAMEND)
	out SPH, Temp




;******************************************************************************
; настройка портов
;******************************************************************************



; настраиваем порт "B"

	ldi Temp,0b00000010		; настроили порт "b" (0-ввод, 1-вывод)
	out DDRB,Temp			; 000000х0 - топливный насос
					 
		
			

	ldi Temp,0b00000000		; выводим лог_0 в Порт "b" ( низкий уровень ) топливный насос.
	out PortB,Temp			; 




; настраиваем порт "D"

	ldi Temp,0b01010000		; настроили порт "D" (0-ввод, 1-вывод)
	out DDRD,Temp			; 0х000000 - вентилятор
					; 000x0000 - высоковольтный генератор 					 
		
			

	ldi Temp,0b01000000		; выводим данные в Порт "D" / ШИМ воздушного нагнетателя и вв генератор
	out PortD,Temp			; 



				
;******************************************************************************
;  настройка таймеров
;******************************************************************************


; Таймер_0 ( делитель 1024 )
; 8 бит
; Шим для вентилятора ( 3 режима: выключено, стартовая мощность и максимальная )



					

	ldi Temp,(1<<COM0A1)|(1<<COM0A0)|(1<<WGM01)|(1<<WGM00)
	out TCCR0A, Temp	
				
					; быстрый ШИМ  // установить по совпадению, очистить при сбросе ( инвертированный )
					; 
					; 


					; COM0A1  / поведение вывода OC1A // 
					; COM0A0  / поведение вывода OC1A // 
					; COM0B1  / поведение вывода OC1B // 
					; COM0B0  / поведение вывода OC1B //  
					; WGM01=1 / режим *
					; WGM00=1 / режим *





	ldi Temp,(0<<WGM02)|(1<<cs02)|(1<<cs00)	
	out TCCR0B, Temp					


					; тактовый сигнал = CK 1:1024 
					; таймер начал считать!!!


					; WGM02=0 / режим * 
					; CS02=1  / тактовый сигнал
					; CS01=0  / тактовый сигнал 
					; CS00=0  / тактовый сигнал = CK 1:1024 (16МГц/1024=15625Гц) 1 тик таймера = 0,000064 сек



					; 16000000:1024=15625 Гц
					; 1:15625=0,000064 сек

					; 0,000064*256=0,016384 сек
					; 0,000064*1=0,000064 сек



	ldi Temp, 0x1E			; диапазон от 0 до 255
	out OCR0A, Temp			; зададим 30 ( 0x1E ) минимум ( задаем стартовую мощность )
					; если 255 ( 0xFF ) максимум











;******************************************************************************

; таймер_1 ( делитель 1/64 )
; 16 бит
; ШИМ для топливного насоса с регулируемой частотой ( от 1 до 3 Герц )





	LDI Temp, 0x00						; зададим длину импульса 
	sts OCR1AH, Temp					; 0,03 сек - 1875 тиков ( 0x0753 ) 
	LDI Temp, 0x00						; 0.00 сек - 0 тиков ( 0x0000 ) стоп насос!					
	sts OCR1AL,Temp  					; нет ------------------------------------ если 0,10 сек, то 6250 тиков ( 0x186A )
								; нет ------------------------------------ если 0,05 сек, то 3125 тиков ( 0x0C35 )




	ldi Temp, (1<<COM1A1)|(0<<COM1A0)|(1<<wgm11)|(0<<wgm10)	; быстрый ШИМ с регулируемой частотой ( fast pwm - top = icr )
	sts TCCR1A, Temp					; 

								; COM1A1 / поведение вывода OC1A
								; COM1A0 / поведение вывода OC1A 
								; COM1B1 / поведение вывода OC1B 
								; COM1B0 / поведение вывода OC1B
								; резерв
								; резерв
								; WGM11=1 / режим таймера
								; WGM10=0 / режим таймера


	ldi Temp, (1<<WGM13)|(1<<WGM12)|(1<<cs12)|(0<<cs10)	;  
	sts TCCR1B, Temp					; и установили тактовый сигнал = CK 1:256
								; таймер начал считать!!!

								; ICNC1=0 / 
								; ICES1=0 / 
								; WGM13=1 / режим таймера
								; WGM12=1 / режим таймера
								; CS12=0
								; CS11=1 / тактовый сигнал = CK 1:256 (16МГц/256=62500Гц) 1 тик таймера = 0,000016 сек
								; CS10=0 





	LDI Temp, 0xF4						; зададим Частоту ШИМ  
	sts ICR1H, Temp						; и выведем ее в порт сравнения
	LDI Temp, 0x24						; 1:1Герц=1сек // 1сек:0,000016сек=62500 тиков - стартовая мощность ( 0xF424 )
	sts ICR1L, Temp						; 1:3Герц=0,33Сек // 0,33сек:0,000016сек=20625 тиков - максимальная мощность ( 0x5091 )
								; 
								; 
								; 
 								; нет---------------------- 1:7Герц=~0,14сек // 0,14сек:0,000016сек=8750 тиков ( 0x222E )
								; нет---------------------- 1:10Герц=0,1сек // 0,1сек:0,000016сек=6250 тиков ( 0x186A )
								





	ldi Temp, 0						; обнуление таймера 
	sts TCNT1H, Temp
	sts TCNT1L, Temp






;******************************************************************************
; настройка переменных ( запись данных в переменные )
;******************************************************************************


	ldi Temp, 0			; номер текущего канала = 0
	STS curr_ch, Temp		;







;******************************************************************************
; инициализация дисплея
;******************************************************************************			

	RCALL	LCD_INIT		; инициализация дисплея ( метка "LCD_INIT" находится в файле драйвера )




;*******************************************************************************
; главный цикл *****************************************************************
;*******************************************************************************

main_cicle:



; позиционирование печати на 1-строку

																
	LDI R18, 0			;(Y) 1 строка (отсчет с 0)	
	LDI R17, 0			;(X) 0 линия по горизонтали	
	RCALL LCD_POS			


; печатьслова "СТАРТ"

	LDI R16, 54			; печать символа 'С'
	RCALL LCD_CHAR	

	LDI R16, 55			; печать символа 'Т'
	RCALL LCD_CHAR	
					
			
	LDI R16, 37			; печать символа 'А'
	RCALL LCD_CHAR
						
			
	LDI R16, 53			; печать символа 'Р'
	RCALL LCD_CHAR	
			

	LDI R16, 55			; печать символа 'Т'
	RCALL LCD_CHAR			
		

	LDI R16, 78			; печать символа '.'
	RCALL LCD_CHAR						
			


; задержка времени

	rcall Loop0			; задержка ( 2 секунды )
	rcall Loop0






;*******************************************************************************************************************************
; продувка 
;
; дуем воздухом на полной мощности без подачи топлива ( 5 секунд )

PRODUVKA:



; дуем вентилятором на полной мощности

	ldi Temp, 0xFF			; вентилятор на максимум 255 ( диапазон от 0 до 255 )
	out OCR0A, Temp			; 
					 


; отключаем топливный насос


	LDI Temp, 0x00			; зададим длину импульса 
	sts OCR1AH, Temp		; (нет) --------------------------------------0,03 сек - 1875 тиков ( 0x0753 ) 
	LDI Temp, 0x00			; (да) 0.00 сек - 0 тиков ( 0x0000 ) стоп насос!					
	sts OCR1AL,Temp  					




; очистка дисплея


	RCALL	LCD_INIT		; инициализация дисплея ( метка "LCD_INIT" находится в файле драйвера )



; позиционирование печати на 1-строку

																
	LDI R18, 0			;(Y) 1 строка (отсчет с 0)	
	LDI R17, 0			;(X) 0 линия по горизонтали	
	RCALL LCD_POS			


; печать

	LDI R16, 52			; печать символа 'П'
	RCALL LCD_CHAR	

	LDI R16, 53			; печать символа 'Р'
	RCALL LCD_CHAR	
					
			
	LDI R16, 51			; печать символа 'О'
	RCALL LCD_CHAR
						
			
	LDI R16, 41			; печать символа 'Д'
	RCALL LCD_CHAR	
			

	LDI R16, 56			; печать символа 'У'
	RCALL LCD_CHAR			
		

	LDI R16, 39			; печать символа 'В'
	RCALL LCD_CHAR	
					

	LDI R16, 47			; печать символа 'К'
	RCALL LCD_CHAR			
		

	LDI R16, 37			; печать символа 'А'
	RCALL LCD_CHAR						


			

; задержка времени


	rcall Loop0			; задержка ( 5 секунд )
	rcall Loop0
	rcall Loop0
	rcall Loop0
	rcall Loop0



;*******************************************************************************************************************************
; зажигание
; 
; включаем высоковольтный генератор 
; подаем топливо на стартовой мощности


ZAGIGANIE:



; очистка дисплея


	RCALL	LCD_INIT		; инициализация дисплея ( метка "LCD_INIT" находится в файле драйвера )




; позиционирование печати на 1-строку

																
	LDI R18, 0			;(Y) 1 строка (отсчет с 0)	
	LDI R17, 0			;(X) 0 линия по горизонтали	
	RCALL LCD_POS			



; печать слова "ЗАЖИГАНИЕ"


	LDI R16, 44			; печать символа 'З'
	RCALL LCD_CHAR	


	LDI R16, 37			; печать символа 'А'
	RCALL LCD_CHAR	
					
			
	LDI R16, 43			; печать символа 'Ж'
	RCALL LCD_CHAR
						
			
	LDI R16, 45			; печать символа 'И'
	RCALL LCD_CHAR	
			

	LDI R16, 40			; печать символа 'Г'
	RCALL LCD_CHAR			
		

	LDI R16, 37			; печать символа 'А'
	RCALL LCD_CHAR						
			

	LDI R16, 50			; печать символа 'Н'
	RCALL LCD_CHAR						


	LDI R16, 45			; печать символа 'И'
	RCALL LCD_CHAR	
	

	LDI R16, 42			; печать символа 'Е'
	RCALL LCD_CHAR	
								




; крутим вентилятор с минимальной скоростью


	ldi Temp, 0x1E			; вентилятор на минимум 30 ( диапазон от 0 до 255 )
	out OCR0A, Temp			; 
					 


	LDI Temp, 0x07			; зададим длину импульса 
	sts OCR1AH, Temp		; 0,03 сек - 1875 тиков ( 0x0753 ) 
	LDI Temp, 0x53			; насос начал качать!					
	sts OCR1AL,Temp  					



	LDI Temp, 0xF4			; зададим Частоту топливного насоса  ( стартовая мощность )
	sts ICR1H, Temp			; 
	LDI Temp, 0x24			; 1:1Герц=1сек // 1сек:0,000016сек=62500 тиков - стартовая мощность ( 0xF424 )
	sts ICR1L, Temp			; 1:3Герц=0,33Сек // 0,33сек:0,000016сек=20625 тиков - максимальная мощность ( 0x5091 )
					
					 
					 


; поджиг топлива ( включаем высоковольтный генератор )

; первая серия импульсов

	sbi PortD, 4			; РD4 - включаем высоковольтный генератор ( ON )
					

	rcall Loop0			; задержка ( 2 секунд )
	rcall Loop0


	cbi PortD, 4			; РD4 - выключаем высоковольтный генератор ( OFF )


	rcall Loop0			; задержка ( 1 секунду )


; вторая серия импульсов

	sbi PortD, 4			; РD4 - включаем высоковольтный генератор ( ON )
					

	rcall Loop0			; задержка ( 2 секунд )
	rcall Loop0


	cbi PortD, 4			; РD4 - выключаем высоковольтный генератор ( OFF )


	rcall Loop0			; задержка ( 1 секунду )


; третья серия импульсов

	sbi PortD, 4			; РD4 - включаем высоковольтный генератор ( ON )
					

	rcall Loop0			; задержка ( 2 секунд )
	rcall Loop0


	cbi PortD, 4			; РD4 - выключаем высоковольтный генератор ( OFF )




; разгоняем вентилятор


	ldi Temp, 0x64			; вентилятор увеличим до 100 ( диапазон от 0 до 255 )
	out OCR0A, Temp			; 
					 



; задержка времени


	rcall Loop0			; задержка ( 2 секунды )
	rcall Loop0			; 
					; подождем немного, что бы датчик пламени успел остыть в случае затухания пламени
					; или нагреться в случае если пламя горит.










;*******************************************************************************************************************************
; проверка пламени
; 
; тут проверяем наличие пламени
; если пламя есть увеличиваем мощность
; если пламени нет - прдуваем и начинаем сначала







; настройка АЦП 10 бит ( от 0 до 1023 ) ***************************************

	ldi Temp,(1<<REFS0)|(0<<MUX0)		
	sts ADMUX, Temp	
						; REFS0=1 / опорное напряжение 5V /
						; ADLAR=0 / справа налево 10 бит ( 8 бит в младшем и 2 бита в старшем )
						; MUX0=0  / включен аналоговый вход ADC0 (PA0)
						; MUX1=0 
						; MUX2=0 
						; MUX3=0 		
						; MUX4=0

	

	ldi Temp, (1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADIF)|(0<<ADIE)|(7<<ADPS0)
	sts ADCSRA, Temp
						; ADEN=1  / включаем АЦП
						; ADSC=1  / запускаем первое преобразование
						; ADATE=0 / отключаем автозапуск АЦП
						; ADIF=1  / бит устанавливается после завершения преобразования ( сбросим бит программно, записав единицу )
						; ADIE=0  / запретить прерывание для АЦП
						; ADPS2=1 / тактовая
						; ADPS1=1 / тактовая
						; ADPS0=1 / тактовая частота 1/128 ( 16 МГц / 128 = 125 кГц )



;	ldi Temp, (0<<ADTS0)
;	out ADCSRB,Temp


						; ACME=0  / включаем АЦП и отключаем аналоговый компатор // включено по умолчанию.
						; ADTS2=0
						; ADTS1=0
						; ADTS0=0 / свободный режим работы 
						; ( новое преобразование начинается по завершению текущего ) // включено по умолчанию.





						; *PUD=0 / отключает подтягивающие резисторы, даже если они подключены // функция отключена
						; *PSR10=0 / сбрсывает предделитель таймера_1 // функция отключена
						; *PSR2=0 / сбрсывает предделитель таймера_2 // функция отключена








; проверка готовности АЦП


ADIF_check_cycle:				; цикл проверки готовности АЦП

	lds Temp, ADCSRA			; читаем ADCSRA
	sbrs Temp, ADIF				; пропустить следующую команду, если ADIF установлен. (ADIF=4)
	rjmp ADIF_check_cycle			; если ADIF не установлен, то циклимся



; читаем АЦП


	lds XL, ADCL				; читаем значение канала АЦП в регистровую пару "X"
	lds XH, ADCH				; 
						; тут данные от 0 до 1023




; проверяем датчик пламени на целостность ( датчик пламени представляет из себя вольфрамовую нить )


	ldi YL, 0x00				; запишем число 0
	ldi YH, 0x00				; если данные в АЦП равны нулю, значит датчик перегорел


	rcall compare_XY16			; сравниваем...


	breq PEREGOREL_1			; переход на обработку когда X=Y 
	brcs PEREGOREL_1			; переход на обработку когда X<Y ( меньше нуля быть не может )
	rjmp ispraven				; переход на обработку когда X>Y 


PEREGOREL_1:

	rjmp PEREGOREL				; вне доягаемости адреса памяти


ispraven:

	ldi YL, 0xDB				; запишем число 987 ( 0x03DB ) 
	ldi YH, 0x03				; 
						; если данные в АЦП меньше этого числа, то значит ПЛАМЯ ГОРИТ
						; иначе потухло




	rcall compare_XY16			; сравниваем...



	breq MAX_Regim				; переход на обработку когда X=Y 
	brcs MAX_Regim				; переход на обработку когда X<Y
	rjmp PRODUVKA1				; переход на обработку когда X>Y 


PRODUVKA1:

	rjmp PRODUVKA				; относительная ссылка в недосягаемости, используем прямую ссылку



;*******************************************************************************************************************************
; максимальный режим
; 

MAX_Regim:


; очистка дисплея


	RCALL	LCD_INIT		; инициализация дисплея ( метка "LCD_INIT" находится в файле драйвера )




; позиционирование печати на 1-строку

																
	LDI R18, 0			;(Y) 1 строка (отсчет с 0)	
	LDI R17, 0			;(X) 0 линия по горизонтали	
	RCALL LCD_POS			


; печать текста "МАХ РЕЖИМ"



	LDI R16, 49			; печать символа 'М'
	RCALL LCD_CHAR	

	LDI R16, 37			; печать символа 'А'
	RCALL LCD_CHAR	
					
			
	LDI R16, 58			; печать символа 'Х'
	RCALL LCD_CHAR
						
			
	LDI R16, 16			; печать символа 'пробел'
	RCALL LCD_CHAR	
			

	LDI R16, 53			; печать символа 'Р'
	RCALL LCD_CHAR			
		

	LDI R16, 42			; печать символа 'Е'
	RCALL LCD_CHAR						
			

	LDI R16, 43			; печать символа 'Ж'
	RCALL LCD_CHAR						


	LDI R16, 45			; печать символа 'И'
	RCALL LCD_CHAR	
	
		
	LDI R16, 49			; печать символа 'М'
	RCALL LCD_CHAR	
			




; разгоняем вентилятор


	ldi Temp, 0xFF			; вентилятор увеличим до 255 ( диапазон от 0 до 255 )
	out OCR0A, Temp			; 
					 




; увеличиваем подачу топлива ( 2 Гц )


	LDI Temp, 0x7A			; зададим Частоту топливного насоса  ( стартовая мощность )
	sts ICR1H, Temp			; 
	LDI Temp, 0x12			; 1:1Герц=1сек // 1сек:0,000016сек=62500 тиков - стартовая мощность ( 0xF424 )
	sts ICR1L, Temp			; 1:3Герц=0,33Сек // 0,33сек:0,000016сек=20625 тиков - максимальная мощность ( 0x5091 )
					; 1:2Герц=0,5сек // 0,5:0,000016сек=31250 тиков - предмаксимальная мощность ( 0x7A12 )
					 



	rcall Loop0			; задержка ( 1 секунду )


;*******************************************************************************************************************************
; основной цикл_1



; очистка дисплея


	RCALL	LCD_INIT		; инициализация дисплея ( метка "LCD_INIT" находится в файле драйвера )


; позиционирование печати на 1-строку

																
	LDI R18, 0			;(Y) 1 строка (отсчет с 0)	
	LDI R17, 0			;(X) 0 линия по горизонтали	
	RCALL LCD_POS			


; печать


	LDI R16, 47			; печать символа 'К'
	RCALL LCD_CHAR	

	LDI R16, 51			; печать символа 'О'
	RCALL LCD_CHAR	
					
			
	LDI R16, 50			; печать символа 'Н'
	RCALL LCD_CHAR
						
			
	LDI R16, 55			; печать символа 'Т'
	RCALL LCD_CHAR	
			

	LDI R16, 53			; печать символа 'Р'
	RCALL LCD_CHAR			
		

	LDI R16, 51			; печать символа 'О'
	RCALL LCD_CHAR						
			

	LDI R16, 48			; печать символа 'Л'
	RCALL LCD_CHAR						


	LDI R16, 65			; печать символа 'ь'
	RCALL LCD_CHAR						








; нужно прочитать текущий канал АЦП 

          
setting_ADS:

	LDI Temp, ADC_ADMUX			; читаем настройки ADMUX ( константа )
	LDS Temp1, curr_ch			; читаем номер следующего канала ( переменная в ОЗУ )

	OR Temp, Temp1      			; накладываем номер канала АЦП для чтения ( побитовое "или" )
	STS ADMUX, Temp				; сохраняем настройки АЦП






; запускаем одиночное преобразование АЦП 
   
	LDI R16, ADC_ADCSRA
	STS ADCSRA, R16




; проверка готовности АЦП 



ADIF_check_cycle_1:				; цикл проверки готовности АЦП

	lds Temp, ADCSRA			; читаем ADCSRA
	sbrs Temp, ADIF				; пропустить следующую команду, если ADIF установлен. (ADIF=4)
	rjmp ADIF_check_cycle_1			; если ADIF не установлен, то циклимся




; читаем значение АЦП 



	lds XL, ADCL				; читаем значение текущего канала АЦП 
	lds XH, ADCH				; 



; читаем номер текущего канала и выводим данные АЦП на дисплей



	LDS Temp, curr_ch			; читаем номер текущего канала


	CPI Temp, 0				; АЦП_0 ?
	breq ADC_CH_00				; если да, то идем на метку_0


	CPI Temp, 1				; АЦП_1 ?
	breq ADC_CH_10				; если да, то идем на метку_1
	rjmp ADC_CH_2				; иначе на метку_2



ADC_CH_00:

	rjmp ADC_CH_0				; вне досягаемости

ADC_CH_10:

	rjmp ADC_CH_1				; вне досягаемости



;****************

; показания датчика охлаждающей жидкости

ADC_CH_2:


; позиционирование печати на 4юю-строку

																
	LDI R18, 3			;(Y) 4ая строка (отсчет с 0)	
	LDI R17, 0			;(X) 0 линия по горизонтали	
	RCALL LCD_POS			


; печать ( t Охлаждающей жидкости )


	LDI R16, 55			; печать символа 't'
	RCALL LCD_CHAR
	

	LDI R16, 82			; печать символа 'градусы'
	RCALL LCD_CHAR	
					

	LDI R16, 51			; печать символа 'О'
	RCALL LCD_CHAR		
		
	LDI R16, 43			; печать символа 'Ж'
	RCALL LCD_CHAR

		
	LDI R16, 16			; печать символа 'ПРОБЕЛ'
	RCALL LCD_CHAR						
			


; данные АЦП находятся в (XH:XL) - ( значение от 0 до 1023 )


; печать 16ти битного числа в текущих координатах в HEX-виде
; число в регистре X (XH:XL)

	mov r16, XH
	rcall printhex
	mov r16, XL
	rcall printhex
 

; сравним температуру с максимальным значением


	ldi YH, 0x02			; запишем число 702 ( 70 градусов по Цельсию ) ( 0x2BE ) 
	ldi YL, 0xBE			; 
					


	rcall compare_XY16		; сравниваем...


	breq change_num_channel_0	; переход на обработку когда X=Y 
	brcs change_num_channel_0	; переход на обработку когда X<Y
	rjmp PEREGREV			; переход на обработку когда X>Y 





; *********************

; показания датчика перегрева камеры сгорания
ADC_CH_1:



; позиционирование печати на 3юю-строку

																
	LDI R18, 2			;(Y) 3-яя строка (отсчет с 0)	
	LDI R17, 0			;(X) 0 линия по горизонтали	
	RCALL LCD_POS			


; печать ( темпертура каперы сгорания )


	LDI R16, 55			; печать символа 't'
	RCALL LCD_CHAR
	

	LDI R16, 82			; печать символа 'градусы'
	RCALL LCD_CHAR	
					
			
	LDI R16, 47			; печать символа 'К'
	RCALL LCD_CHAR

		
	LDI R16, 54			; печать символа 'С'
	RCALL LCD_CHAR	
			
		
	LDI R16, 16			; печать символа 'ПРОБЕЛ'
	RCALL LCD_CHAR						
			



; данные АЦП находятся в (XH:XL) - ( значение от 0 до 1023 )


; печать 16ти битного числа в текущих координатах в HEX-виде
; число в регистре X (XH:XL)

	mov r16, XH
	rcall printhex
	mov r16, XL
	rcall printhex
 

; сравним температуру с максимальным значением


	ldi YH, 0x02			; запишем число 702 ( 70 градусов по Цельсию ) ( 0x02BE ) 
	ldi YL, 0xBE			; 
					


	rcall compare_XY16		; сравниваем...


	breq change_num_channel_0	; переход на обработку когда X=Y 
	brcs change_num_channel_0	; переход на обработку когда X<Y
	rjmp PEREGREV			; переход на обработку когда X>Y 


change_num_channel_0:

	rjmp change_num_channel		; вне досягаемости




;***************

; показания датчика пламени



ADC_CH_0:


; проверяем датчик пламени на целостность ( датчик пламени представляет из себя нить вольфрамовую нить )


	ldi YL, 0x00			; запишем число 0
	ldi YH, 0x00			; если данные в АЦП равны нулю, значит датчик перегорел
					; 
						

	rcall compare_XY16		; сравниваем...


	breq PEREGOREL_2		; переход на обработку когда X=Y 
	brcs PEREGOREL_2		; переход на обработку когда X<Y ( меньше нуля быть не может )
	rjmp ispraven_2			; переход на обработку когда X>Y 


PEREGOREL_2:

	rjmp PEREGOREL			; вне доягаемости адреса памяти


ispraven_2:

; позиционирование печати на 2ую-строку
			
	LDI R18, 1			;(Y) 2ая строка (отсчет с 0)	
	LDI R17, 0			;(X) 0 линия по горизонтали	
	RCALL LCD_POS			



; печать

	LDI R16, 52			; печать символа 'П'
	RCALL LCD_CHAR	


	LDI R16, 48			; печать символа 'Л'
	RCALL LCD_CHAR	
					
			
	LDI R16, 37			; печать символа 'А'
	RCALL LCD_CHAR
						
			
	LDI R16, 49			; печать символа 'М'
	RCALL LCD_CHAR	
			

	LDI R16, 68			; печать символа 'Я'
	RCALL LCD_CHAR			
		

	LDI R16, 16			; печать символа 'ПРОБЕЛ'
	RCALL LCD_CHAR						
			


; определяем наличие пламени

; данные АЦП находятся в (XH:XL)


	ldi YL, 0xd7			; запишем число 983 ( 0x03d7 ) 
	ldi YH, 0x03			; 
					; если данные в АЦП меньше этого числа, то значит ПЛАМЯ ГОРИТ
					; иначе потухло


	rcall compare_XY16		; сравниваем...


	breq gorit			; переход на обработку когда X=Y 
	brcs gorit			; переход на обработку когда X<Y
	rjmp potuhlo			; переход на обработку когда X>Y 





gorit:


	LDI R16, 41			; печать символа 'Д'
	RCALL LCD_CHAR	
			

	LDI R16, 37			; печать символа 'А'
	RCALL LCD_CHAR			
		

	LDI R16, 16			; печать символа 'ПРОБЕЛ'
	RCALL LCD_CHAR						
			

	rjmp change_num_channel




potuhlo:




	LDI R16, 50			; печать символа 'Н'
	RCALL LCD_CHAR	
			

	LDI R16, 42			; печать символа 'Е'
	RCALL LCD_CHAR			
		

	LDI R16, 55			; печать символа 'Т'
	RCALL LCD_CHAR						
			

; тут нужно решть как быть в данной ситуации
; временно сделаю так
; глушу котел и жду действий от оператора



; очистка дисплея

	RCALL	LCD_INIT		; инициализация дисплея ( метка "LCD_INIT" находится в файле драйвера )


; позиционирование печати на 1-строку

																
	LDI R18, 0			;(Y) 1 строка (отсчет с 0)	
	LDI R17, 0			;(X) 0 линия по горизонтали	
	RCALL LCD_POS			


; печать


	LDI R16, 52			; печать символа 'П'
	RCALL LCD_CHAR	


	LDI R16, 51			; печать символа 'О'
	RCALL LCD_CHAR	
					
			
	LDI R16, 55			; печать символа 'Т'
	RCALL LCD_CHAR
						
			
	LDI R16, 56			; печать символа 'У'
	RCALL LCD_CHAR	
			

	LDI R16, 58			; печать символа 'Х'
	RCALL LCD_CHAR			
		



	rjmp STOP_nas_vent



;****************************************

change_num_channel:


; нужно изменить номер текущего канала АЦП 


	LDS Temp, curr_ch			; читаем номер текущего канала
            
	INC Temp				; увеличили его на 1

	CPI Temp, 3				; дошли до 3го канала ?
	brne SAVE_CURR_CH			; если нет, то идем на сохранение
	ldi Temp, 0				; если дошли, то сбросим на нулевой канал !

SAVE_CURR_CH:

	STS curr_ch, Temp			; сохраняем номер следующего канала







	rjmp setting_ADS			; идем читать следующий канал АЦП



;************************************************************************************

; перегрев

PEREGREV:



; очистка дисплея

	RCALL	LCD_INIT		; инициализация дисплея ( метка "LCD_INIT" находится в файле драйвера )




; позиционирование печати на 1-строку

																
	LDI R18, 0			;(Y) 1 строка (отсчет с 0)	
	LDI R17, 0			;(X) 0 линия по горизонтали	
	RCALL LCD_POS			




; печать


	LDI R16, 52			; печать символа 'П'
	RCALL LCD_CHAR	


	LDI R16, 42			; печать символа 'Е'
	RCALL LCD_CHAR	
					
			
	LDI R16, 53			; печать символа 'Р'
	RCALL LCD_CHAR
						
			
	LDI R16, 42			; печать символа 'Е'
	RCALL LCD_CHAR	
			

	LDI R16, 40			; печать символа 'Г'
	RCALL LCD_CHAR			
		

	LDI R16, 53			; печать символа 'Р'
	RCALL LCD_CHAR						


	LDI R16, 42			; печать символа 'Е'
	RCALL LCD_CHAR			
		

	LDI R16, 39			; печать символа 'В'
	RCALL LCD_CHAR						





	rjmp STOP_nas_vent



;************************************************************************************

; перегорел датчик пламени

PEREGOREL:




; очистка дисплея

	RCALL	LCD_INIT		; инициализация дисплея ( метка "LCD_INIT" находится в файле драйвера )




; позиционирование печати на 1-строку

																
	LDI R18, 0			;(Y) 1 строка (отсчет с 0)	
	LDI R17, 0			;(X) 0 линия по горизонтали	
	RCALL LCD_POS			




; печать


	LDI R16, 52			; печать символа 'П'
	RCALL LCD_CHAR	


	LDI R16, 42			; печать символа 'Е'
	RCALL LCD_CHAR	
					
			
	LDI R16, 53			; печать символа 'Р'
	RCALL LCD_CHAR
						
			
	LDI R16, 42			; печать символа 'Е'
	RCALL LCD_CHAR	
			

	LDI R16, 40			; печать символа 'Г'
	RCALL LCD_CHAR			
	

	LDI R16, 51			; печать символа 'О'
	RCALL LCD_CHAR						
	

	LDI R16, 53			; печать символа 'Р'
	RCALL LCD_CHAR						


	LDI R16, 42			; печать символа 'Е'
	RCALL LCD_CHAR			
		

	LDI R16, 48			; печать символа 'Л'
	RCALL LCD_CHAR						





	rjmp STOP_nas_vent



;*******************************************************************************

; отключение топливного насоса и вентилятора

STOP_nas_vent:


; отключаем топливный насос


	LDI Temp, 0x00			; зададим длину импульса 
	sts OCR1AH, Temp		; (нет) --------------------------------------0,03 сек - 1875 тиков ( 0x0753 ) 
	LDI Temp, 0x00			; (да) 0.00 сек - 0 тиков ( 0x0000 ) стоп насос!					
	sts OCR1AL,Temp  					


; тут можно добавить отключение ШИМ на таймер_1 и вывод на этот пин лог_0







; дуем вентилятором на полной мощности ( продувка )

	ldi Temp, 0xFF			; вентилятор на максимум 255 ( диапазон от 0 до 255 )
	out OCR0A, Temp			; 
					 


; задержка 1 секунду

	rcall Loop0



; отключаем вентилятор


	ldi Temp, 0x00			; вентилятор на минимум 0 ( диапазон от 0 до 255 )
	out OCR0A, Temp			; 
					 


; глушим ШИМ вентилятора, что-бы мотор не "гудел"


	ldi Temp, 0
	out TCCR0A, Temp

	ldi Temp, 0	
	out TCCR0B, Temp					




; выводим на ПИН вентилятора лог_1 ( на всякий случай ) ( invert )


	sbi PortD, 6			; РD6 - вентилятор ( лог_1 )



			
; зацикливание в ожидание действий оператора



Ojidanie_CICLE:

	rjmp Ojidanie_CICLE





;**************************************************************************************************************************
;***************************************************************************************************************************
;****************************************************************************************************************************
;
; ПодпрограммЫ



;*******************************************************************************
; Подпрограмма задержки ( примерно 1 секунда )
;*******************************************************************************



Loop0:

	ldi Temp1,0
	ldi Temp2,0
	ldi Temp3,0


Loop:     

	dec Temp1
	brne Loop

	dec Temp2
	brne Loop

	dec Temp3
	brne Loop


ret






;*******************************************************************************
; подпрограмма печати байта в hex виде, в текущих координатах. 
;*******************************************************************************

  
; в r16 число которое нужно напечатать

printhex: 
   
	push r16		; сохраним наше число на стеке (нужно для печати младшей тетрады)
	swap r16		; поменяем тетрады местами, на месте младшей тетрады теперь старшая
	rcall printhex1		; печать старшей тетрады    
	pop r16			; вспомним число для печати


printhex1: 
   
	andi r16, 0x0f		; обнулим старшие биты (старшую тетраду)
	rcall lcd_char		; печатаем число    
	ret    





;******************************************************************
; сравнение 16-ти битных чисел
;******************************************************************



compare_XY16:

	cp XH, YH			; сравниваем старшие части регистров
	breq xh_eq_yh			; значения старших регистров равны, нужно сравнить младшие xl и yl
					; флаг С - установлен когда X<Y
					; флаг С - сброшен когда X>Y
	ret



xh_eq_yh:

	cp XL, YL			; сравниваем младшие части регистров
					; флаг Z=1 когда X=Y
					; флаг С - установлен когда X<Y
					; флаг С - сброшен когда X>Y




	ret   



;*************************************************************    




;*******************************************************************************
; подключаемые модули
;*******************************************************************************

.include "lcd5110rus.asm"		; подключение драйвера дисплея	



