;************************************************************************** ;* lcd8bf_l018.asm ;* Driver per display LCD a caratteri basato su Hitachi 44780 o equivalenti. ;************************************************************************** NOLIST ;************************************************************************** ; Modalità hardware; - interfaccia a 8 bit dati ; - controllo RW, RS, EN. ; ; Sono gestiti display a una o più linee. ; Nota: i display 40 x 4 H44780 compatibili sono ralizzati con un doppio ; controller che richiede un segnale addizionale non gestito da questo ; driver. ; ; Le caratteristiche principali del driver sono : ; - linee dati su 8 bit consecutivi di un qualsiasi port (Rx0=D0:Rx7=D7) ; - linee di controllo RS, RW e EN su qualsiasi bit di qualsiasi port ; ; Assembly standard Microchip con opzione per processori della famiglia ; Enhanced (PIC18F). ; Frequenza di clock 4 MHz ; ; Questo package fornisce una serie di subroutines che possono essere ; chiamate nel programma ospite per comandare il display: ; ; LCDioini - Inizializza I/O necessari alla gestione ; dell' LCD ; LCDswini - Inizializzazione software del display ; LCDWrCmd - Invia un comando in W al display. ; Esce dopo il test di BF ; LCDWrDat - Invia un dato in W al display ; Esce dopo il test di BF ; LCDrdram - Legge contenuto RAM e ritorna con questo ; in WREG ; LCDrdbfa - Legge BF + AC e ritorna con questo in WREG. ; Esce dopo il test di BF ; LCDDDAdr - porta il cursore all' indirizzo in W ; LCDline1 - porta il cursore all' inizio della linea 1 ; LCDline2 - porta il cursore all' inizio della linea 2 ; ;************************************************************** ;************************************************************** ;---> La dichiarazione degli I/O utilizzati va aggiunta al ; programma principale. Copiare il blococ e decommentare. ; Le assegnazioni VANNO CAMBIATE se l' hardware è diverso. ;*************************************************************** ;*************************************************************** ;; Assegnazioni I/O ;; ================ ;;LCD - linee dati ;LCDtris equ TRISC ; direzione LCD data port ;LCDportr equ PORTC ; LCD data port - lettura ;LCDportw equ LATC ; LCD data port - scrittura ;;LCD - linee di controllo ; #define LCD_RStris TRISB,0x00 ; RS on portB,0 ; #define LCD_RSw LATB, 0x00 ; #define LCD_RSr PORTB,0x00 ; #define LCD_RWtris TRISB,0x01 ; RW on portB,1 ; #define LCD_RWw LATB, 0x01 ; #define LCD_RWr PORTB,0x01 ; #define LCD_Etris TRISB,0x02 ; E su portB,2 ; #define LCD_Ew LATB, 0x02 ; #define LCD_Er PORTB,0x02 ; ;; fine assegnazioni I/O PAGE ;************************************************************** ;********************** Inizio driver ************************* ;************************************************************** ;*** Set standard comandi del controller Hitachi 44780 ******** ; ; RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 ; == === === === === === === === === === ;Clear Display 0 0 0 0 0 0 0 0 0 1 ;Return Home 0 0 0 0 0 0 0 0 1 * ;Entry Mode Set 0 0 0 0 0 0 0 1 I/D S ;Display ON/OFF 0 0 0 0 0 0 1 D C B ;Cursor & Display Shift 0 0 0 0 0 1 S/C R/L * * ;Function Set 0 0 0 0 1 DL N F * * ;Set CG RAM address 0 0 0 1 A A A A A A ;Set DD RAM address 0 0 1 A A A A A A A ;Read BF & AC 0 1 BF A A A A A A A ;Write to CG or DD RAM 1 0 D D D D D D D D ;Read from CG or DD RAM 1 1 D D D D D D D D ; Comandi come constanti - Esepio di uso: LCDCMD LCDCLR ; Clear and home - richiede un lungo tempo di esecuzione CONSTANT LCD_CLR = b'00000001' ;clear display & cursor home CONSTANT LCD_CH = b'00000010' ;cursor home CONSTANT LCD_CR = b'00000110' ;cursor l -> r, shift off CONSTANT LCD_OFF = b'00001000' ;display off CONSTANT LCD_ONC = b'00001110' ;disp.on, curs. on, blink off CONSTANT LCD_2L = b'00111000' ;8 bit mode, 2 lines, 5x7 dots ;Costanti di selezione inizio linea CONSTANT LCDL1 = 0x00 ; 0x00, selects line 1 CONSTANT LCDL2 = 0x40 ; 0x40, selects line 2 LIST ;********************************************************** ;**********//* ENTRY POINTS - SUBROUTINES ***************** ;********************************************************** ; ;********************************************************** ; LCDioini ; Questa routine inizializa i pin di controllo dell' LCD ;********************************************************** LCDioini: ; set I/O per LCD     bcf LCD_Ew ; E pin clear bcf LCD_RSw ; RS pin clear bcf LCD_RWw ; RW pin clear clrf LCDportw ; data port clear clrf LCDtris ; set bus port come uscita bcf LCD_Etris ; set linee comando come uscite bcf LCD_RStris bcf LCD_RWtris return ;********************************************************** ; LCDswini ; Inizializzazione per istruzioni. ;********************************************************** LCDswini rcall Delay15ms ; Delay iniziale >= 15 ms ; ; Per le prime scritture non è possibile utilizzare il flag ; di busy, ma si impiega un ritardo fisso movlw 0x30 ; comando 30h movwf LCDportw ; sul bus rcall LCDclk ; primo clock rcall Delay4ms ; primo ritardo rcall LCDclk ; secondo clock rcall Delay100us ; secondo ritardo rcall LCDclk ; terzo clock ; Da ora in poi è possibile usare il test del flag busy. ; Invia i comandi di definizione del modo di funzionamento ; standard con: ; - display on ; - carattere 5x7 ; - cursore on, non lampeggiante ; - movimento cursore da sinistra a destra ; Per altre modalità modificare gli ultimi due comandi rcall LCDrdbfa ;check per Busy movlw LCD_2L ;8 bit/2 linee/ font 5x7 rcall LCDwrcmd rcall LCDrdbfa ;check per Busy movlw LCD_OFF ;display off rcall LCDwrcmd rcall LCDrdbfa ;check per Busy movlw LCD_CLR ;Clear & Home rcall LCDwrcmd rcall LCDrdbfa ;check per Busy movlw LCD_CR ;cursor move l->r rcall LCDwrcmd rcall LCDrdbfa ;check per Busy movlw LCD_ONC ;display on/cursor off/blink off rcall LCDwrcmd return ;********************************************************** ; LCDwrcmd - LCDwrdat ; Trasmette un dato o un comando al display: ; Dato o comando sono in WREG. ;********************************************************** ; Trasmette un comando. Comando in WREG LCDwrcmd: bcf LCD_RSw ; RS=0 per comando bra lcwr ; Trasmette un dato. Dato in WREG LCDwrdat: bsf LCD_RSw ; RS=1 per dati lcwr movwf LCDportw ; byte sul PORT bcf LCD_RWw ; RW=0 per scrittura rcall LCDclk ; clock E ; reset LCD bus e controlli clrf LCDportw ; clear PORT bcf LCD_RWw ; clear RW bcf LCD_RSw ; clear RS return ;********************************************************** ; LCDclk ; Impulso di clock positivo sul pin EN per accettare dati ; o comandi ;********************************************************** LCDclk bsf LCD_Ew ; E = 1 ; inserire NOP per rispettare i tempi previsti dal ; costruttore nop nop bcf LCD_Ew ; E = 0 nop return ;********************************************************** ; LCDrdram - LCDrdbfa ; Legge contenuto RAM o BF+AC ; Dato letto ritorna in WREG. ;********************************************************** ; Leggi RAM dall' LCD LCDrdram: bsf LCD_RSw ;RS=1 per la RAM bra lcdr0 ;salta avanti ; Leggi BF + AC dall' LCD LCDrdbfa: bcf LCD_RSw ;RS=0 per BF+AC lcdr0 setf LCDtris ;data port = input bsf LCD_RWw ;RW=1 per leggere nop ;stabilizzazione lcdr1 bsf LCD_Ew ;E=1 - Abilita LCD btfsc LCD_RSr ;RS=0 ? bra notbusy ;n - legge RAM ;s - test busy dall' LCD btfss LCDportr, 7 ;se 1 = busy bra notbusy ;se = 0 busy end bcf LCD_Ew ;E = 0 - disabilita LCD nop ;aggiungere nop per nop ;ottenere cicli da 1 us bra lcdr1 ;tra un enable e il succesivo notbusy movf LCDportr, w ;salva il dato letto nop bcf LCD_Ew ;E = 0 - disabilita nop nop ; reset LCD bus e controlli clrf LCDportw ;clear PORT bcf LCD_RWw ;clear RW bcf LCD_RSw ;clear RS bcf LCD_RWw ;clear RW bcf LCD_RSw ;clear RS clrf LCDtris ;set port = output return ;********************************************************** ; LCDWrCmd - LCDWrDat ; Trasmette un dato o un comando al display: ; Dato o comando sono in WREG. ; La routine viene rilasciata dopo il test per BF=0 ;********************************************************** ; Trasmette un comando. Comando in WREG LCDWrCmd: rcall LCDwrcmd bra LCDrdbfa ; check busy ; Trasmette un dato. Dato in WREG LCDWrDat: rcall LCDwrdat ; RS = 1 per dati bra LCDrdbfa ; check busy ;********************************************************** ; LCDLINE - porta il cursore all' inizo della linea ; specificata ; Avvertenza: la linea chiamata deve esistere nel display ;********************************************************** LCDLine1 movlw LCDL1 ; linea 1 bra LCDDDAdr LCDLine2 movlw LCDL2 ; linea 2 ;********************************************************** ; LCDDDADR - Richiama una specifica posizione in DDRAM ; Entrare con l' indirizzo da richiamare in WREG ; Avvertenza: la RAM chiamata deve esistere nel display ;********************************************************** LCDDDAdr iorlw b'10000000' ; bit7 = 1 per il comando bra LCDWrCmd ;return ; end of the module