; -------------------------------
;| Набор процедур для управления |
;| LCD16S2D               ----------
; -----------------------| By Pa5ha |
;                         ----------

.include "D:\avr\avrasm\appnotes\2313def.inc"

.def     Temp=R16
.def     Temp1=R17
.def     Temp2=R18
.def     Temp3=R19
.def     Temp4=R20

.cseg
.org 0

rjmp Reset	  ;вектора прерываний
rjmp INT_0
rjmp INT_1
rjmp Timer1_capt1
rjmp Timer1_comp1
rjmp Timer1_OVF1
rjmp Timer0_OVF0
rjmp UART_RX
rjmp UART_UDRE
rjmp UART_TX
rjmp ANA_COMP




;Reset:
INT_0:
INT_1:
Timer1_capt1:
;Timer1_comp1:
Timer1_OVF1:
Timer0_OVF0:
UART_RX:
UART_UDRE:
UART_TX:
ANA_COMP:
	reti
;****************************************************
; ИНИЦИАЛИЗАЦИЯ
;****************************************************
Reset:
	ldi Temp,0b11111111	; настройка портов
	out DDRB,Temp
	out DDRD,Temp
	ldi Temp,0
	out PortD,Temp

	ldi Temp,RamEnd		; установка указателя стека
	out SPL,Temp
;*********************
;Работа с LCD

	rcall Delay40mks	; Пауза перед включением
	rcall Init_LCD16s2d	; Инициализация дисплея

	rcall Write_CGRAM	; Создание собственного символа

	ldi Temp,0b10000000
	rcall WriteCmd		; Установка курсора
	ldi ZL,Low(Text01*2) 
	ldi ZH,High(Text01*2)
	rcall WriteLn		; Вывод строки

	ldi Temp,0b11000001
	rcall WriteCmd		; Установка курсора
	ldi ZL,Low(Text02*2) 
	ldi ZH,High(Text02*2)
	rcall WriteLn		; Вывод строки
;*********************

	ldi Temp,0b01000000   ;разрешить прерывание компаратора
	out TIMSK,Temp

	ldi Temp,0b00000011   ;тактовый сигнал = CK/64
	out TCCR1B,Temp

	ldi Temp,0x4C         ;инициализация компаратора
	out OCR1AH,Temp
	ldi Temp,0x4B
	out OCR1AL,Temp

	ldi Temp1,0b00000001  ;инициализация индикатора

	ldi Temp,0	  ;обнуление таймера
	out TCNT1H,Temp
	out TCNT1L,Temp

	sei	         ;разрешить прерывания


;****************************************************
; ОСНОВНОЙ ЦИКЛ
;****************************************************
Inf:
	rjmp Inf	    ;бесконечный цикл


;****************************************************
; ОБРАБОТЧИК ПРЕРЫВАНИЯ КОМПАРАТОРА
;****************************************************

Timer1_comp1:
         ldi Temp,0		;обнуление таймера
         out TCNT1H,Temp
         out TCNT1L,Temp


Shift:   cpi Temp1,0b10000000	;сравнить с крайним знач.
         breq Init		;если равно - загрузка нач. знач.

         lsl Temp1		;иначе - сдвиг влево
         rjmp Output		;перейти на вывод в порт

Init:    ldi Temp1,0b00000001	;загрузить нач. значение
Output:  out PortB,Temp1	;вывод в порт

         reti			;выход из обработчика


;****************************************************
; Пауза
;****************************************************
Delay40mks:
	push Temp

	ldi Temp,0
Loop:
	dec Temp
	brne Loop

	pop Temp

	ret

;****************************************************
; Пауза
;****************************************************
Delay1500mks:
	push Temp
	push Temp1

	ldi Temp,0
	ldi Temp1,20
Loop3:
	dec Temp
	brne Loop3
	dec Temp1
	brne Loop3

	pop Temp1
	pop Temp

	ret

;****************************************************
; Инициализация LCD
;****************************************************
;команды sbi, cbi  - установка/сброс бита
;a0	pd6
;r/w	pd5
;e	pd4
;db4	pd0
;db5	pd1
;db6	pd2
;db7	pd3

INIT_LCD16S2D: 
	ldi R16,0 
	out PortD,R16 
	rcall Delay40mks 
	ldi Temp1,16
	ldi ZL,Low(LCD_INIT_DATA*2) 
	ldi ZH,High(LCD_INIT_DATA*2) 
Init_next0: 
	lpm
	out PortD,r0;Temp
	adiw ZL,1			; AddImmedaiate to Word. Инкрементится слово.
	nop				;Не менее 40нс
	nop
	sbi PortD,4 
	nop				;Не менее 230нс 
	nop
	nop 
	nop 
	nop 
	nop
	cbi PortD,4 
	rcall Delay40mks 
	dec Temp1 
	brne Init_next0 

	rcall Delay1500mks

;	ldi Temp,0
;	out PortD,Temp

	ret 
LCD_INIT_DATA:
;      are3210    are3210
;8bit
.db 0b00000011,0b00000011 ; 30h Установка разрядности
.db 0b00000011,0b00000010 ; 20h Установка разрядности

;4bit
.db 0b00000010,0b00001000 ; 28h Установка разрядности

.db 0b00000000,0b00001000 ; 0Ch Выглючение дисплея

.db 0b00000000,0b00000110 ; 06h Установка направления и разрешения сдвига

.db 0b00000000,0b00001111 ; 0Fh Включить индикатор и мигающий курсор

.db 0b00001000,0b00000000 ; Курсор домой

.db 0b00000000,0b00000001 ; 01h Очистка, курсор домой

;****************************************************
; Установка адреса для последующих операции и 
;  выбор оласти DDRAM.
; Входные данные: R16(Temp) - адрес DDRAM + 0x80.
; Изменяется регистр R16(Temp).
;****************************************************
WriteCmd:
	push Temp
	;Swap Temp
	lsr Temp
	lsr Temp
	lsr Temp
	lsr Temp
	andi Temp,0b00001111
	out PortD,Temp
	nop			;Не менее 40нс
	nop
	sbi PortD,4 
	nop			;Не менее 230нс 
	nop
	nop 
	nop 
	nop 
	nop
	cbi PortD,4 
	nop			;Не менее 270нс
	nop
	nop
	nop
	nop
	nop
	nop

	pop Temp
	andi Temp,0b00001111
	out PortD,Temp
	nop			;Не менее 40нс
	nop
	sbi PortD,4 
	nop			;Не менее 230нс 
	nop
	nop 
	nop 
	nop 
	nop
	cbi PortD,4 
	rcall Delay40mks 
	
	ret

;****************************************************
; Вывод текстовой строки на дисплей.
; Входные данные: регистр Z - адрес строки в 
;  программной памяти. '$' - конец строки.
; Изменяется регистр R16(Temp), Z.
;****************************************************
WriteLn:
	lpm
	mov Temp,r0
	cpi Temp,'$'
	breq WriteLnEnd

	adiw ZL,1

	push Temp
	Swap Temp
	andi Temp,0b00001111
	ori Temp,0b01000000
	out PortD,Temp
	nop			;Не менее 40нс
	nop
	sbi PortD,4 
	nop			;Не менее 230нс 
	nop
	nop 
	nop 
	nop 
	nop
	cbi PortD,4 
	nop			;Не менее 270нс 
	nop
	nop
	nop
	nop
	nop
	nop

	pop Temp
	andi Temp,0b00001111
	ori Temp,0b01000000
	out PortD,Temp
	nop ;Не менее 40нс
	nop
	sbi PortD,4 
	nop			;Не менее 230нс 
	nop
	nop 
	nop 
	nop 
	nop
	cbi PortD,4 
	rcall Delay40mks 

	rjmp WriteLn
WriteLnEnd:
	ret

;****************************************************
; Всякие тексты, чтоб выводить
;****************************************************
Text01:
.db 'I',0,0x4b,0x50,0xA5,0x43,0x54,0xB0,0xAC,0x41,0x20,0x26,'$'
Text02:
.db "radiokot.ru :)$"

;****************************************************
; Запись своих символов в CGRAM
;****************************************************

Write_CGRAM:
	ldi Temp,0b01000000 		; Выбор области памяти CGRAM
	rcall WriteCmd
	 
;	ldi R16,0 
;	out PortD,R16 
;	rcall Delay40mks 
;	ldi Temp1,8
	ldi ZL,Low(Symbol_data*2) 
	ldi ZH,High(Symbol_data*2) 
;Init_next0: 

;	brne Init_next0 
rcall WriteLn
;	rcall Delay1500mks

;	ldi Temp,0
;	out PortD,Temp

	ret 
Symbol_data:
;      are3210    are3210
.db 0b00000000,0b00000000
.db 0b00001010,0b00011111
.db 0b00001110,0b00000100
.db 0b00000000,0b00000000
.db '$'






.EXIT
Подключение индикатора к порту D по варианту 4-х битного интерфейса:
a0	(4)	(11)	pd6
r/w	(5)	(9)	pd5
e	(6)	(8)	pd4
db4	(11)	(2)	pd0
db5	(12)	(3)	pd1
db6	(13)	(6)	pd2
db7	(14)	(7)	pd3
