Tutorials - Elettronica

 
 

Caratteri CGRAM nei display LCD
 a matrice


Come scrivere in CGRAM.

Scrivere in CGRAM fa capo allo stesso protocollo generale utilizzato dal controller per la scrittura in RAM, ovvero occorre:

  1. puntare l' indirizzo sull'area CGRAM richiesta

  2. effettuare la scrittura del byte

In dettaglio:

  1. Portare a 0 le linee RS e RW per preparare il controller ad accettare comandi
  2. Selezionare l'indirizzo CGRAM voluto inviando un byte compreso tra 40h e 7Fh (64 e 127 decimali), corrispondenti alle celle 0-63 della CGRAM.
  3. Commutare la modalità da comandi a dati, portando il pin RS a 1
  4. Inviare il byte che si vuole scrivere a quel dato indirizzo di CGRAM. Il controller automaticamente incrementa il contatore di indirizzi in modo da non dover effettuare questa manovra manualmente per una possibile successiva scrittura.
  5. Se la stringa da scrivere comprende più bytes, basta ripetere il passo precedente

Si dovrà, ovviamente, far coincidere l' inizio di un simbolo con l' inizio di un blocco di celle di CGRAM.

E' possibile scrivere:

  • tutti e 8 i simboli disponibili, trasferendo 64 bytes consecutivi a partire dall' indirizzo CGRAM 00h.
  • più simboli, posizionando il contatore di indirizzi di CGRAM nella posizione di inizio del primo simbolo che si trasferisce e scrivendo gruppi di 8 bytes
  • un solo simbolo, posizionando il contatore di indirizzi di CGRAM nella posizione di inizio del simbolo e trasferendo un gruppo di 8 bytes
  • una parte di un simbolo, scrivendo uno o più bytes agli indirizzi voluti.

Dal punto di vista delle istruzioni ecco, ad esempio, una procedura per scrivere una tabella di 64 bytes (tutti e 8 i simboli disponibili) nella CGRAM (Assembly PIC18F):

LCDCGADR 0            ; set CGRAM address to 0
call     LCDLd8CGram  ; write 8 chars (64 bytes)to CGRAM

dove:

;*************************************************************
; LCDCGADR - Call a specified CGRam address
; Use : LCDCGADR xx with xx any valid CGRam address
; if out of range, error
;*************************************************************

LCDCGADR macro CGRamAdr

Local value = CGRamAdr | b'01000000' ; mask command
 #if (CGRamAdr > b'00111111')
 ERROR "CGRAM Address over range in LCDCGAdr"
#else
 movlw   value
 call    LCDWrCmd                    ; write address to CGRAM
#endif
         endm

e

;********************************************************************
; LCDLd8CGram - Subroutine
; Move 8 user-defined chars to the CGRAM
; Chars are stored on LCDSCtable 8 x 8bytes = 64 bytes
;********************************************************************

LCDLd8CGram
; set pointer to table in program memory
  #if PROGMEMSIZE > 32    ; only if prog. memory >32K
 movlw  UPPER LCDSCtable  ; bits 16 - 21 of target
 movwf  TBLPTRU           ; to pointer UPPER
  #endif
 movlw  low LCDSCtable
 movwf  TBLPTRL
 movlw  high LCDSCtable
 movwf  TBLPTRH

;entry point for an external table setup
llcg0:   
 clrf   LCDtemp           ; start from row 0
 movf   LCDtemp, w        ; row counter in W
 iorlw  b'01000000'       ; convert to CG address
 call   LCDWrCmd          ; send CGRamAddress

llcg1   tblrd *+          ; read table entry into TABLAT
 movf   TABLAT,w          ; move row value to WREG
 call   LCDWrDat          ; write to LCD
 incf   LCDtemp, f        ; rowcounter + 1
 btfss  LCDtemp, 6        ; cntr >64 if bit 6 = 1
 bra    llcg1             ; n - pick up next row
 return

Come detto precedentemente, tra una scrittura e la successiva non occorre riposizionare il contatore di indirizzi, che viene automaticamente aggiornato dal controller.

La LCDSCtable potrà avere questo aspetto:

LCDSCTable         ; 8 chars for CGRAM - 5x7
; arrow up
 db 04,0x0E,0x15,04,04,04,04,00
;0x04 ; . . # . .
;0x0E ; . # # # .
;0x15, ; # . # . #
;0x04, ; . . # . .
;0x04, ; . . # . .
;0x04, ; . . # . .
;0x04, ; . . # . .
;0x00 ; . . . . . cursor row

; arrow down
 db 04,04,04,04,0x15,0x0E,04,00
;0x04 ; . . # . .
;0x04 ; . . # . .
;0x0E ; . . # . .
;0x15 ; # . # . #
;0x0E, ; . # # # .
;0x04 ; . . # . .
;0x00 ; . . . . . cursor row
; arrow right

 db 00,04,02,0x1F,02,04,00,00
;0x00, ; . . . . .
;0x04 ; . . # . .
;0x02 ; . . . #
;0x1F ; # # # # #
;0x02 ; . . . # .
;0x04, ; . . # . .
;0x00 ; . . . . .
;0x00 ; . . . . . cursor row
; arrow left

 db 00,04,08,0x1F,08,04,00,00
;0x00, ; . . . . .
;0x04 ; . . # . .
;0x0F ; . # . . .
;0x1F ; # # # # #
;0x0F ; . # . . .
;0x04 ; . . # . .
;0x00 ; . . . . .
;0x00 ; . . . . . cursor row
; right turn

 04,02,0x1F,0x12,0x14,0x10,0x10,00
;0x04 ; . . # . .
;0x02 ; . . . # .
;0x1F ; # # # # #
;0x12 ; # . . # .
;0x14 ; # . # . .
;0x10 ; # . . . .
;0x10 ; # . . . .
;0x00 ; . . . . .
; left turn

 db 04,08,0x1F,09,05,01,01,00
;0x04 ; . . # . .
;0x02 ; . # . . .
;0x1F ; # # # # #
;0x12 ; . # . . #
;0x14 ; . . # . #
;0x10 ; . . . . #
;0x10 ; . . . . #
;0x00 ; . . . . .
; arrow big up

 db 04,0x0E,0x1F,0x15,04,04,04,04
;0x04 ; . . # . .
;0x0E ; . # # # .
;0x1F, ; # # # # #
;0x15, ; # . # . #.
;0x04, ; . . # . .
;0x04, ; . . # . .
;0x04, ; . . # . .
;0x04 ; . . # . . cursor row
; arrow big down

 db 04,04,04,04,0x15,0x1F,0x0E,04
;0x04 ; . . # . .
;0x04 ; . . # . .
;0x04 ; . . # . .
;0x04 ; . . # . .
;0x15 ; # . # . #
;0x1F, ; # # # # #
;0x0E ; . # # # .
;0x00 ; . # . . cursor row

 

Se volessimo caricare un solo carattere, basterà puntare la CGRAM alla cella voluta, indi scrivere gli 8 bytes consecutivi. Ad esempio, per il sesto simbolo:

LCDCGADR 0x28         ; set CGRAM address to symbol 6
call     LCDLdCGram   ; write 8 bytes to CGRAM

dove

;********************************************************************
; LCDLdCGRAM - Subroutine
; Move 1 user-defined chars to the a CGRAM location
; Chars are stored in a table called by SETTABLE macro
;********************************************************************

LCDLdCGRAM:

; set pointer to table in program memory

  #if PROGMEMSIZE > 32    ; only if prog. memory >32K
  movlw  UPPER LCDSctable  ; bits 16 - 21 of target
  movwf  TBLPTRU           ; to pointer UPPER
  #endif
  movlw  low LCDSctable
  movwf  TBLPTRL
  movlw  high LCDSctable
  movwf  TBLPTRH
 
 movlw  8             ; set counter
 movwf  LCDtemp       ; for 8 bytes
llcg1   tblrd *+      ; read table entry into TABLAT
 movf   TABLAT,w     
; move row value to WREG
 call   LCDWrDat      ; write to LCD
 decfsz LCDtemp, f    ; rowcounter + 1
  bra   llcg1         ; n - pick up next row
 return

La LCDSctable sarà composta da 8 soli bytes. Ad esempio

LCDSctable:           ; 1 char. 5x7 for CGRAM
; plug
 db 0x0A,0x0A,0x1F,0x11,0x0E,04,04,00
;0x0A, ; . # . # .
;0x0A, ; . # . # .
;0x1F, ; # # # # #
;0x11, ; # . . . #
;0x0E, ; . # # # .
;0x04, ; . . # . .
;0x04, ; . . # . .
;0x00 ; . . . . . cursor row

Anche qui, tra un byte ed il successivo, il controller provvede automaticamente all' aggiornamento del contatore di indirizzi.

E' possibile scrivere anche solo una parte di un simbolo, puntando l' indirizzo di CGRAM alla cella voluta e sovra scrivendone il contenuto con il nuovo byte.


Scrittura di indirizzi e scrittura di dati.

Da osservare che, negli esempi sopra riportati, sono utilizzate due diverse routines per scrivere l' indirizzo (LCDWrCmd) e i dati in CGRAM (LCDWrDat).
Infatti l' indirizzo è inviato come un comando, mentre i successivi dati sono inviati come dati; la differenza è stabilita dal pin RS.

Comando

Controllo

 

Dato

Funzione
Write data to CGRAM RS RW   D7 D6 D5 D4 D3 D2 D1 D0

Invia un dato alla CGRAM

1 0   dato alla CGRAM
Comando

Controllo

 

Dato

Funzione
Write address to CGRAM RS RW   D7 D6 D5 D4 D3 D2 D1 D0

Fissa un indirizzo della CGRAM per la successiva scrittura o lettura

0 0   0 1 indirizzo della CGRAM

Ogni operazione di scrittura in CGRAM richiede da 37 a 100 us per byte a seconda delle caratteristiche del controller. Quindi è possibile scrivere e sovrascrivere dinamicamente la CGRAM per ottenere effetti di movimento sul display.


 

 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 04/12/12.