; Radioded.ru - микроконтроллерам респект
; Свита Сергей sergey_svita@mail.ru
; Цифровой термометр на DS18B20
; !с датчиком DS1820 не работает

.include "2313def.inc"
		

.def	wreg		=R16

.def	ds_counter	=R17
.def 	duration	=R18
.def  	lbyte		=R19
.def	hbyte		=R20
.def	ds_command	=R21

.def   	digit1		=R22
.def   	digit2		=R23
.def   	digit3		=R24
.def   	digit4		=R25

.def	lcd_command	=R26
.def	lcd_data	=R27
.def	wr_counter	=R28


ldi	wreg,RAMEND             
out	SPL,wreg

rcall reset

rcall lcdinit
main:

rcall ds

rcall bcd_convert

ldi	lcd_command,$01		;стираем дисплей
rcall	lcdcmd

ldi wreg, 3
rcall ds_longdelay

rcall display

rjmp main

;************************************************
reset:

		ldi 	wreg, 142	
		rcall	ds_longdelay		; ожидание установления питания 100мс

		ldi		wreg,0x00		
		out		PORTD,wreg			; Запись 0 в порт

		ldi		wreg,0xff	
		out		DDRD,wreg			; Все ноги выходы

		ldi		wreg, 0x00			; input
		out		DDRB, wreg
		
ret


;*************************** LCD ************************
strob:
		sbi	PORTD, PD5		;строб 3мкс
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		cbi	PORTD, PD5
ret


lcdinit:

		ldi		wreg, 0b00000011	;посылка 0b00000011	
		out		PORTD,wreg	
		rcall	strob
		ldi 	wreg, 7			
		rcall	ds_longdelay		;задержка 5мс
		

		
		ldi		wreg, 0b00000011	;посылка 0b00000011	
		out		PORTD,wreg	
		rcall 	strob
		ldi 	wreg, 142			
		rcall	ds_delay			;задержка 100мкс
		


		ldi		wreg, 0b00000011	;посылка 0b00000011	
		out		PORTD,wreg	
		rcall 	strob
		ldi 	wreg, 1			
		rcall	ds_delay			;задержка 3 мкс

		
		ldi	wreg, 0b00000010		
		out	PORTD,wreg				;посылка 0b00000010 4 битный интерфейс
		rcall strob
		ldi 	wreg, 3			
		rcall	ds_longdelay			;задержка 3 мс
	
		; Выставление Опций Интерфейса


		ldi	lcd_command,$28		;4 бита, 2 строки, 5*7 точек
		rcall	lcdcmd

		ldi	lcd_command,$0C		;вкл. дисплей, курсор выключен
		rcall	lcdcmd

		ldi	lcd_command,$01		;стираем дисплей
		rcall	lcdcmd

		ldi wreg, 3
		rcall ds_longdelay

		ldi	lcd_command,$06		;перемещение курсора слева-направо инкр.
		rcall	lcdcmd

ret


lcdcmd:

		mov 	wreg, lcd_command
		swap 	wreg
		andi 	wreg, 0x0F
		out		PORTD, wreg
		rcall 	strob
		
		ldi 	wreg, 2			
		rcall 	ds_delay

		mov 	wreg, lcd_command
		andi	wreg, 0x0F
		out		PORTD, wreg
		rcall	strob
		
		ldi		wreg, 20		
		rcall	ds_delay

ret		

lcdput:

		ldi		wreg,0x00		
		out		PORTD,wreg			; Запись 0 в PORTD


		mov 	wreg, lcd_data
		swap 	wreg
		andi	wreg, 0x0F
		out 	PORTD, wreg
		
		sbi		PORTD, PD4			; строб+RS
		rcall	strob
		cbi		PORTD, PD4
		
		ldi 	wreg, 2				;***
		rcall 	ds_delay

		mov		wreg, lcd_data
		andi	wreg, 0x0F 
		out 	PORTD, wreg
		
		sbi		PORTD, PD4			; строб+RS
		rcall	strob
		cbi		PORTD, PD4

		ldi 	wreg, 20 			;***
		rcall 	ds_delay


		ldi		wreg,0x00		
		out		PORTD,wreg			; Запись 0 в порт ***

ret





;********************* DS1820 *******************

Ds:

		rcall 	ds_reset 				; вызов обнуления линии

		ldi 	ds_command, 0xCC		; пропуск идентификации
		rcall 	ds_write

		ldi 	ds_command, 0x44 		; начало преобразования
		rcall 	ds_write


		ldi 	wreg, 255
		rcall 	ds_longdelay			; ожидание 178мс
		ldi 	wreg, 255
		rcall 	ds_longdelay			; ожидание 178мс
		ldi 	wreg, 255
		rcall 	ds_longdelay			; ожидание 178мс
		ldi 	wreg, 255
		rcall 	ds_longdelay			; ожидание 178мс
		ldi 	wreg, 60
		rcall 	ds_longdelay			; ожидание 40мс


		rcall 	ds_reset 				; вызов обнуления линии
	
		ldi 	ds_command, 0xCC
		rcall 	ds_write

		ldi 	ds_command, 0xBE 		;чтение блокнота, получение результата
		rcall 	ds_write

		ldi		wreg, 5
		rcall	ds_delay

		rcall 	ds_read					; принять 8 бит

ret
		
ds_delay:

		ldi 	duration, 2				; 2,75uS*wreg
		cycle:
		nop
		dec 	duration
		brne	cycle
		dec 	wreg
		brne	ds_delay
ret

			
ds_longdelay:

		mov 	ds_counter, wreg		; 0,7ms*wreg
		Label:
		ldi 	wreg,0xff
		rcall 	ds_delay
		dec 	ds_counter
		brne 	Label
ret

ds_reset:

		cbi	 	PORTB,	PB0

		ldi		wreg, 0xFF				; Portb выход
		out		DDRB, wreg

		ldi 	wreg, 	220				; обнуление 600мкс
		rcall 	ds_delay
		
		ldi		wreg, 0xFE				; Portb.0 вход
		out		DDRB, wreg
		
		ldi 	wreg, 	220 			; принятие импульса присутствия 600мкс
		rcall 	ds_delay
ret


ds_write:
		
		ldi 	wr_counter,8
		Label1:
		lsr 	ds_command			; лог сдвиг 0 бит -> CF
		brcs 	one_wr				; пререход если CF=1
		rjmp 	zero_wr

	
	one_wr:

		cbi 	PORTB, PB0
		
		ldi 	wreg, 0xff
		out		DDRB, wreg			; PORTB - выход
			
		ldi 	wreg, 1				; 2,7мкс
		rcall 	ds_delay 
		
		ldi		wreg, 0xFE			; PORTB - вход
		out		DDRB, wreg

		ldi 	wreg,20 			; 60мкс - продление "1"
		rcall 	ds_delay	
		rjmp 	Label2

	zero_wr:
		
		cbi 	PORTB, PB0
		
		ldi 	wreg, 0xff
		out		DDRB, wreg			; PORTB - выход
			
		ldi 	wreg, 26			; 70мкс
		rcall 	ds_delay 
			
		ldi		wreg, 0xFE			; PORTB - вход
		out		DDRB, wreg

	Label2:
	ldi 	wreg, 1				; задержки между посылками битов 2,7мкс
	rcall 	ds_delay
	dec 	wr_counter
	brne 	Label1				; проверка счетчика
ret

ds_read:

	ldi wr_counter, 9
	ldi lbyte, 0x00

	; new section
	

	cbi PORTB,PB0
	
	ldi wreg, 0xFF				; PB0 - output
	out DDRB, wreg

	ldi wreg,2
	rcall ds_delay				; синхроимпульс 2,7мкс
	
	
	ldi wreg, 0xFE 				; PB0 - input
	out DDRB, wreg 

	ldi wreg, 3
	rcall ds_delay				; проверка через 8мкс

	ldi wreg, 22				; 60мкс
	rcall ds_delay


	;2

	cbi PORTB,PB0
	
	ldi wreg, 0xFF				; PB0 - output
	out DDRB, wreg

	ldi wreg,2
	rcall ds_delay				; синхроимпульс 2,7мкс
	
	
	ldi wreg, 0xFE 				; PB0 - input
	out DDRB, wreg 

	ldi wreg, 3
	rcall ds_delay				; проверка через 8мкс

	ldi wreg, 22				; 60мкс
	rcall ds_delay

	;3

	cbi PORTB,PB0
	
	ldi wreg, 0xFF				; PB0 - output
	out DDRB, wreg

	ldi wreg,2
	rcall ds_delay				; синхроимпульс 2,7мкс
	
	
	ldi wreg, 0xFE 				; PB0 - input
	out DDRB, wreg 

	ldi wreg, 3
	rcall ds_delay				; проверка через 8мкс

	ldi wreg, 22				; 60мкс
	rcall ds_delay
	
	; end of section
	
	label3:
	

	cbi PORTB,PB0
	
	ldi wreg, 0xFF				; PB0 - output
	out DDRB, wreg

	ldi wreg,2
	rcall ds_delay				; синхроимпульс 2,7мкс
	
	
	ldi wreg, 0xFE 				; PB0 - input
	out DDRB, wreg 

	ldi wreg, 3
	rcall ds_delay				; проверка через 8мкс

	cpi wr_counter, 1
	breq sign

	sbis PINB, PB0				; проп. след ком если PB0=1
	rjmp zero_r

		one_r:
			lsr lbyte
			ori lbyte,0x80
			rjmp label4

		zero_r:
			lsr lbyte
			nop

	label4:
	ldi wreg, 22				; 60мкс
	rcall ds_delay

	dec wr_counter
	brne label3					; переход если ds_counter > 0
	
	
sign:

	ldi hbyte, 0xFF
	sbis PINB, PB0				; проп. след ком если PB0=1
	ldi hbyte, 0x00

	nop
	ldi wreg, 22				; 60мкс
	rcall ds_delay

	ldi digit1, -3				; отобразить "-"


ret

;************************** BCD ****************************

bcd_convert:

		clr digit1
		clr digit2
		clr digit3
		clr digit4


		cpi 	hbyte, 0x00
		breq 	plus
		
		com lbyte
		inc lbyte
		ldi digit1, -3

plus:
		mov wreg, lbyte
		lsr wreg

		M1:
		cpi wreg, 0b01100100   			; проверка на 100
		brge M2

		rjmp M3

		M2:
		inc digit1						;
		subi wreg,0b01100100		
		rjmp M1


		M3:
		cpi wreg, 0b00001010			; проверка на 10
		brge M4
		rjmp M5

		M4:
		inc digit2
		subi wreg, 0b00001010			;
		rjmp M3


		M5:
		cpi wreg, 0b00000001			; проверка на 1
		brge M6
		rjmp M7

		M6:
		inc digit3
		dec wreg
		rjmp M5

;********************  десятые    ********************

		M7:
		mov wreg, lbyte
		andi wreg, 0b00000001

		sbrs wreg, 0 					;проверка на 0,5
		rjmp M8
		subi digit4, -5					;прибавляем 5

;***************** преобразования    ******************
	
		M8:							
		cpi digit1, 0
		brne M9
		ldi digit1, 0x60				; не печатаем 0
		cpi digit2, 0
		brne M9
		ldi digit2, 0x60				; не печатаем 0
		
		M9:
		cpi digit1, -3
		brne M10
		cpi digit2, 0
		brne M10
		ldi digit2, 0x60				; не печатаем 0
		
		M10:
		subi digit1, -48				; подготовка к пересылке
		subi digit2, -48
		subi digit3, -48
		subi digit4, -48

ret

;******************************************************

display:

		ldi lcd_data, 0x54
		rcall lcdput

		ldi lcd_data, 0x65
		rcall lcdput

		ldi lcd_data, 0x6d
		rcall lcdput

		ldi lcd_data, 0x70
		rcall lcdput
		ldi lcd_data, 0x3d
		rcall lcdput

		mov lcd_data, digit1
		rcall lcdput

		mov lcd_data, digit2
		rcall lcdput

		mov lcd_data, digit3
		rcall lcdput
	
		ldi lcd_data, 0x2c
		rcall lcdput

		mov lcd_data, digit4
		rcall lcdput

		ldi lcd_data, 0x27
		rcall lcdput

		ldi lcd_data, 0x43
		rcall lcdput

		ldi 	wreg, 255
		rcall 	ds_longdelay			; ожидание 178мс
		ldi 	wreg, 100
		rcall 	ds_longdelay			; ожидание 70мс	(полный цикл 1секунда)		
ret
