;*************************************************************************           
;                          ESEMPIO 4
;                    Prova del modulo LCD
;                   Autore: Mikel Etxebarria
;*************************************************************************
;
;Il programma che si presenta di seguito consiste nell'ottenere dei messaggi
;di presentazione del sistema di valutazione Micro'PIC Trainer attraverso il modulo
;LCD di visualizzazione
           
           list p=16c84      ;Processore PIC16c84  
           list c=132        ;Elenco a 132 caratteri

TIMER0     equ 01            ;Registro del TIMER0
OPCION     equ 0x1           ;Registro di opzioni,pagina 1
PCL        equ 0x2           ;Registro PC
PCLATH     equ 0xa           ;Registro alto del PC
STATUS     equ 03            ;Registro di stato
RA         equ 05            ;Porta A
RB         equ 06            ;Porta B
TRISA      equ 0x5           ;Reg. di programmazione della porta A, p gina 1
TRISB      equ 0x6           ;Reg. di programmazione della porta B, p gina 1 
INTCON     equ 0xb           ;Registro di controllo di interrupt
DATO_A     equ 0xc           ;Registro del dato A
DATO_B     equ 0xd           ;Registro del dato B
RESUL      equ 0xe           ;Registro di resultati
TEMPO1     equ 0xf           ;Registro temporale 1
TEMPO2     equ 0x10          ;Registro temporale 2
TEMPO3	   equ 0x11          ;Registro temporale 3
OFFSET     equ 0x12          ;Variabile di spostamenti di messaggi

           org 0             ;Vettore di RESET
           goto INIZIO

           org 5

INIZIO     bsf STATUS,5      ;Seleziona banco 1 di dati 
           clrf TRISB        ;RB si programma come uscita     
           movlw b'00011000' ;RA<4:3> si programmano come entrate
           movwf TRISA       ;RA<2:0> si programmano come uscite
           movlw b'10000111'
           movwf OPCION      ;Assegna prescaler al TMR0

           bcf STATUS,5      ;Seleziona banco 0 di dati

           movlw b'00000000'
           movwf INTCON      ;Disattiva interrupt
           bcf RA,0          ;Disattiva RS del modulo LCD
           bcf RA,2          ;Disattiva E del modulo LCD
           goto START

DATII      addwf PCL,1
           retlw '*'         ;OFFSET = 0
           retlw '*'
           retlw ' '
           retlw 'P'
           retlw 'R'
           retlw 'E'
           retlw 'S'
           retlw 'E'
           retlw 'N'
           retlw 'T'
           retlw 'A'
           retlw ' '
           retlw '*'
           retlw '*'
           retlw 0x0

           retlw '"'         ;OFFSET 0xf
           retlw 0xe4        ;
           retlw 'P'
           retlw 'I'
           retlw 'C'
           retlw ' '
           retlw 'T'
           retlw 'r'
           retlw 'a'
           retlw 'i'
           retlw 'n'
           retlw 'e'
           retlw 'r'
           retlw '"'
           retlw 0

           retlw 'I'         ;OFFSET 0x1e
           retlw 's'
           retlw 't'
           retlw 'r'
           retlw 'u'
           retlw 't'
           retlw 't'
           retlw 'o'
           retlw 'r'
           retlw 'e'
           retlw ' '
           retlw 'p'
           retlw 'e'
           retlw 'r'
           retlw ' '
           retlw 0

           retlw 'P'         ;OFFSET 0x2e
           retlw 'I'
           retlw 'C'
           retlw ' '
           retlw '1'
           retlw '6'
           retlw 'c'
           retlw '7'
           retlw 'x'
           retlw '/'
           retlw 'c'
           retlw '8'
           retlw '4'
           retlw 0
           
           retlw 'C'         ;OFFSET 0x3c
           retlw 'O'
           retlw 'N'
           retlw 'S'
           retlw 'T'
           retlw 'A'
           retlw ' '
           retlw 'D'
           retlw 'I'
           retlw ':'   
	   retlw 0

           retlw 'F'         ;OFFSET 0x47
           retlw '.'
           retlw 'A'
           retlw 'l'
           retlw 'i'
           retlw 'm'
           retlw 'e'
           retlw 'n'
           retlw 't'
           retlw 'a'
           retlw 'z'
           retlw 'i'
           retlw 'o'
           retlw 'n'
           retlw 'e'
           retlw 0

           retlw 'M'         ;OFFSET 0x57
           retlw 'o'
           retlw 'd'
           retlw '.'
           retlw 'R'
           retlw 'e'
           retlw 'g'
           retlw 'i'
           retlw 's'
           retlw 't'
           retlw 'r'
           retlw 'a'
           retlw 't'
           retlw 'o'
	   retlw 'r'           
           retlw 'e'
           retlw 0

           retlw '5'         ;OFFSET 0x68
           retlw ' '
           retlw 'E'
           retlw 'n'
           retlw 't'
           retlw 'r'
           retlw 'a'
           retlw 't'
           retlw 'e'
           retlw ' '
           retlw 'd'
           retlw 'i'
           retlw 'g'
           retlw 'i'
           retlw '-'
           retlw 0

           retlw 't'         ;OFFSET 0x78
           retlw 'a'
           retlw 'l'
           retlw 'i'
           retlw ' '
           retlw 0

           retlw '4'         ;OFFSET 0x7e
           retlw ' '
           retlw 'E'
           retlw 'n'
           retlw 't'
           retlw 'r'
           retlw 'a'
           retlw 't'
           retlw 'e'
           retlw ' '
           retlw ' '
           retlw 'a'
           retlw 'n'
           retlw 'a'
           retlw '-'
           retlw 0

           retlw 'l'         ;OFFSET 0x8e
           retlw 'o'
           retlw 'g'
           retlw 'i'
           retlw 'c'
           retlw 'h'
           retlw 'e'
           retlw 0

           retlw '8'         ;OFFSET 0x96
           retlw ' '
           retlw 'U'
           retlw 's'
           retlw 'c'
           retlw 'i'
           retlw 't'
           retlw 'e'
           retlw ' '
           retlw 'a'
           retlw ' '
           retlw 'L'
           retlw 'E'
           retlw 'D'
           retlw 's'
           retlw 0

           retlw 'e'         ;OFFSET 0xA6
           retlw ' '          
           retlw 'a'
	   retlw ' '
           retlw 'D'
           retlw 'i'
           retlw 's'
           retlw 'p'
           retlw 'l'
           retlw 'a'
           retlw 'y'
           retlw ' '
           retlw 0
           
           retlw '*'         ;OFFSET 0xb3
           retlw '*'
           retlw '*'
	   retlw ' '
           retlw 'P'
           retlw 'R'
           retlw 'O'
           retlw 'V'
           retlw 'A'
           retlw 'L'
           retlw 'O'
           retlw ' '
           retlw '*'
           retlw '*'
           retlw '*'
           retlw 0

DATO_1     addwf PCL,1
           retlw 'M'
           retlw 'i'
           retlw 'c'
           retlw 'r'
           retlw 'o'
           retlw 'S'
           retlw 'y'
           retlw 's'
           retlw 't'
           retlw 'e'
           retlw 'm'
           retlw 's'
           retlw ' '
           retlw ' '
           retlw ' '
           retlw 0x0

DATO_2     addwf PCL,1
           retlw 'E'
           retlw 'n'
           retlw 'g'
           retlw 'i'
           retlw 'n'
           retlw 'e'
           retlw 'e'
           retlw 'r'
           retlw 'i'
           retlw 'n'
           retlw 'g'
           retlw 0x0

;LCD_BUSY Controlla lo stato del flag Busy dell'LCD e aspetta che termini
;qualche comando precedente prima di ritornare

LCD_BUSY   bsf RA,1          ;Metti l'LCD in modo RD
           bsf STATUS,5      ;Seleziona banco 1
           movlw 0xff
           movwf TRISB       ;Porta B è entrata
           bcf STATUS,5      ;Seleziona banco 0
           bsf RA,2          ;Attiva l'LCD (E)
           nop
L_BUSY     btfsc RB,7        ;Controlla il bit busy
           goto L_BUSY
           bcf RA,2          ;Disattiva l'LCD (E)
           bsf STATUS,5      ;Seleziona banco 1
           clrf TRISB        ;Porta B uscita
           bcf STATUS,5      ;Seleziona banco 0
           bcf RA,1          ;Metti l'LCD in modo WR
           return


;LCE_E Genera un impulso nel segnale E di 1 uS di durata. Ciò è possibile
;grazie alla NOP e al fatto che il PIC lavora a 4MHz. Per velocità superiori
;bisognerà inserire qualche NOP aggiuntiva per non superare la durata minima
;dell'LCD

LCD_E      bsf RA,2          ;Attiva E
           nop               ;pausa
           bcf RA,2          ;Disattiva E
        	movlw	.14
		movwf	TEMPO3
LCD_E_1		decfsz	TEMPO3,F	;Perdi 40 uS per la costante di tempo Tc
		goto	LCD_E_1		;dei nuovi moduli LCD di winteck
		return   

;LCD_DATO  Deposita il codice ASCII presente in W, su RB. Aspetta che l'
;LCD esegua l'ultima operazione e genera l'impulso E.

LCD_DATII  bcf RA,0          ;Disattiva RS (modo comando)
           movwf RB          ;Valore ASCII da togliere per RB
           call LCD_BUSY     ;Aspetta che si liberi l'LCD
           bsf RA,0          ;Attiva RS (modo dato)
           goto LCD_E        ;Genera impulso nel segnale E

;LCD_REG Deposita il codice del comando presente in W, su RB. Aspetta che
;l'LCD esegua l'ultima operazione e genera l'impulso E.

LCD_REG    bcf RA,0          ;Disattiva RS (Modo comando)
           movwf RB          ;Codice del comando
           call LCD_BUSY     ;Aspetta che si liberi l'LCD
           goto LCD_E        ;Genera pulsazione nel segnale E

;LCD_INI Realizza l'inizializzazione dell'LCD secondo i tempi segnati dal
;fabbricante. Si inizia con una interfaccia di 8 bits, 2 linee di visualizzazione,
;e caratteri di 5 * 7. Si temporizza 15 mS.

LCD_INI    movlw b'00111000'
           call LCD_REG
           call DELAY_5MS
           movlw b'00111000'
           call LCD_REG
           call DELAY_5MS
           movlw b'00111000'
           call LCD_REG
           call DELAY_5MS
           return

;DELAY_5MS genera una temporizzazione di 5mS necessaria per la sequenza di
;inizio dell'LCD

DELAY_5MS  movlw 0x1a       
           movwf DATO_B
           clrf DATO_A
DELAY_1    decfsz DATO_A,1
           goto DELAY_1
           decfsz DATO_B,1
           goto DELAY_1
           return

;DELAY10 genera, con l'aiuto del TMR0 e il prescaler, una temporizzazione di 
;10 ms che si ripete tante volte quante ne indica la variabile TEMPO1

DELAY10    bcf INTCON,2      ;Cancella flag del TMR0
           movlw 0xd8
           movwf TIMER0      ;Carica TMR0 affinché conti 39
DELAY10_1  btfss INTCON,2    ;Aspetta overflow del TMR0
           goto DELAY10_1
           decfsz TEMPO1,1   ;Ripeti 10 volte
           goto DELAY10
           return

;DELAY1S temporizza 1 secondo


DELAY1S    movlw 0x64        ;Ripeti la procedura DELAY10 (de 10 mS) 100
           movwf TEMPO1      ;volte
           call DELAY10
           return

;BLINK mantiene l'LCD attivato durante 2 seg. e in seguito genera 
;un'intermittenza di 6 volte dell'accensione e spegnimeto dell'LCD, di 1/4 di secondo 
;ognuna

BLINK      movlw 0xc8
           movwf TEMPO1
           call DELAY10      ;Temporizza 2 secondi con il messaggio
           movlw 6
           movwf TEMPO2      ;6 volte di intermittenza
BLINK_1    movlw b'00001000'
           call LCD_REG      ;Spegni LCD
           movlw 25
           movwf TEMPO1
           call DELAY10      ;Temporizza 1/2 secondo
           movlw b'00001100'
           call LCD_REG      ;Accendi LCD
           movlw 25
           movwf TEMPO1 
           call DELAY10      ;Temporizza 1/2 segundo
           decfsz TEMPO2,1
           goto BLINK_1
           return


MENS_1     clrf RESUL
MENS_1_1   movf RESUL,0      ;Avvia contatore di caratteri     
           call DATO_1       ;Togli carattere
           iorlw 0
           btfsc STATUS,2    ;¨E' l'ultimo?
           return            ;Sì
           call LCD_DATII    ;Visualizza carattere
           incf RESUL,1      ;Aumenta contatore di caratteri
           movlw 10
           movwf TEMPO1      ;Temporizza 100mS
           call DELAY10
           movlw b'00011000' ;Spostamento a sinra.
           call LCD_REG
           goto MENS_1_1

MENS_2     clrf RESUL        ;Avvia contatore di caratteri
MENS_2_1   movf RESUL,0           
           call DATO_2       ;Prendi il carattere
           iorlw 0
           btfsc STATUS,2    ;¨E' l'ultimo?
           return            ;Sì
           call LCD_DATII    ;Visualizza carattere
           incf RESUL,1      ;Aumenta contatore di caratteri
           movlw 10
           movwf TEMPO1      ;Temporizza 100mS
           call DELAY10
           goto MENS_2_1

MENS       clrf RESUL        ;Avvia contatore di caratteri
MENS1      movf OFFSET,0     ;Trova lo Spostamento
           addwf RESUL,0           
           call DATII        ;Trova il carattere
           iorlw 0
           btfsc STATUS,2    ;¨E' l'ultimo?
           return            ;Sì
           call LCD_DATII    ;Visualizza carattere
           incf RESUL,1      ;Aumenta contatore di caratteri
           movlw 10
           movwf TEMPO1      ;Temporizza 100mS
           call DELAY10
           goto MENS1


START      call LCD_INI      ;Avvia LCD
START_1    movlw b'00000001' ;Cancellare LCD e Home
           call LCD_REG
           movlw b'00000110' ;
           call LCD_REG
           movlw b'00001100' ;LCD On, cursore Off
           call LCD_REG
           movlw 0x8f        ;Indirizzo ultimo carattere 1¦ linea
           call LCD_REG
           call MENS_1       ;Messaggio "MicroSystems"
           movlw 0xd4        ;Indirizzo 2¦ linea
           call LCD_REG
           call MENS_2       ;Messaggio "Engenering"
           call BLINK        ;Intermittenza
           movlw b'00000001'
           call LCD_REG      ;Cancella LCD e Home
           call DELAY1S      ;Temporizza 1 sec.
           movlw 0x81
           call LCD_REG      ;Posizione 1¦ fila
           clrf OFFSET
           call MENS         ;Messaggio "** PRESENTA **"
           call DELAY1S      ;Temporizza 1 sec.
           movlw 0xc1
           call LCD_REG      ;Posizione 2¦ fila
           movlw 0x0f
           movwf OFFSET
           call MENS         ;Messaggio "PIC Trainer"
           call DELAY1S      ;Temporizza 1 sec.
           movlw b'00000001'
           call LCD_REG      ;Cancella LCD e Home
           call DELAY1S      ;Temporizza 1 sec.
           movlw 0x1e
           movwf OFFSET
           call MENS         ;Messaggio "Addestratore per"
           movlw 0xc0
           call LCD_REG      ;Posizione 2¦ fila
           movlw 0x2e
           movwf OFFSET
           call MENS         ;Messaggio "PIC 16c7x/84"
           call DELAY1S      ;Temporizza 1 sec.
           movlw b'00000001'
           call LCD_REG      ;Cancella LCD e home
           call DELAY1S      ;Temporizza 1 sec.
           movlw 0x3c
           movwf OFFSET
           movlw 0x83
           call LCD_REG      ;Posizione 1¦ linea
           call MENS         ;Messaggio "CONSTA DI:
           call BLINK        ;Intermittenza
           movlw b'00000001'
           call LCD_REG      ;Cancella LCD e home
           call DELAY1S      ;Temporizza 1 sec.
           movlw 0x47
           movwf OFFSET
           call MENS         ;Messaggio "F. Alimentazione
           movlw 0xc0
           call LCD_REG      ;Posizione 2¦ linea
           call DELAY1S      ;Temporizza 1 seg.
           movlw 0x57
           movwf OFFSET
           call MENS         ;Messaggio "Modulo registratore"
           call DELAY1S      ;Delay 1 sec
           movlw b'00000001'
           call LCD_REG      ;Cancella LCD e Home
           call DELAY1S      ;Temporizza 1 sec
           movlw 0x68
           movwf OFFSET
           call MENS         ;Messaggio "5 entrate digi-"
           movlw 0xc0
           call LCD_REG      ;Posizione 2¦ linea
           movlw 0x78
           movwf OFFSET
           call MENS         ;Messaggio "tali"
           call DELAY1S      ;Temporizzazione di 1 sec.
           movlw b'00000001'
           call LCD_REG      ;Cancella LCD e home
           call DELAY1S      ;Temporizza 1 sec.
           movlw 0x7e
           movwf OFFSET
           call MENS         ;Messaggio "4 Entrate ana-"
           movlw 0xc0
           call LCD_REG      ;Posizione 2¦ linea
           movlw 0x8e
           movwf OFFSET
           call MENS         ;Messaggio "logiche"
           call DELAY1S      ;Temporizza 1 sec
           movlw b'00000001'
           call LCD_REG      ;Cancella LCD e Home
           call DELAY1S      ;Temporizza 1 sec
           movlw 0x96
           movwf OFFSET
           call MENS         ;Messaggio "8 Uscite a LED"
           movlw 0xc0
           call LCD_REG      ;Posizione 2¦ linea
           movlw 0xa6
           movwf OFFSET
           call MENS         ;Messaggio "e a Display"
           call DELAY1S      ;Temporizza 1 sec.
           movlw b'00000001'
           call LCD_REG      ;Cancella LCD e home
           call DELAY1S      ;Temporizza 1 sec.
           movlw 0x81
           call LCD_REG      ;Posizione 1¦ linea
           movlw 0xb3
           movwf OFFSET
           call MENS         ;Uscita di "­­ PROVALO ­­"
           call BLINK        ;Intermittenza
           call DELAY1S      ;Temporizza 1 sec.
           goto START_1
           
           end

