APLICANDO UM LCD 16X02 À PLACA Z80 BY ARNE


O programa a seguir foi utilizado para demonstrar o recurso de inserção de um programa binário na RAM da placa Z80 by Arne sem o uso do teclado, usando para isso a porta RS-232 presente na placa (CI UART 8250) e o protocolo XMODEM 128.


Código do programa teste_LCD.asm
;******************************************************************************
; Projeto - LCD_drZ80
; Arquivo - LCD_drZ80.asm
; Desenv. - Eng. Márcio José Soares
; Versão  - 1.0
; Data    - 27/10/2021
;
; Controle de LCD 16x2 através da placa drZ80_uP via PPI8255
;
; Compilador: pasmo -d -v teste_LCD.asm teste_LCD.bin
;
; Pinos:
; LCD       PPI8255
; ------------------
; RS(4)     PB0
; EN(6)     PA0
; D4(11)    PB4
; D5(12)    PB5
; D6(13)    PB6
; D7(14)    PB7
;
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Declara funções necessárias na placa drZ80_uP
;
wrB8255A        equ     0085H           ;escreve A no portB 
wrA8255A        equ     0088H           ;escreve A no portA
t_50us          equ     0094H           ;temporiza 50us
t_50ms          equ     00A3H           ;temporiza 50ms
t_500ms         equ     00A9H           ;temporiza 500ms
wrzerodisp      equ     007CH           ;limpa display 7 segmentos - coloca zeros

;-------------------------------------------------------------------------------
; Declara constantes
;
CR              equ     0DH             ;ENTER
LF              equ     0AH             ;Line Feed
RS_ON           equ     01H             ;bit de controle RS do LCD
RS_OFF          equ     0FEH            ;bit de controle RS do LCD invertido

;-------------------------------------------------------------------------------
; Declara constantes
;
                org     8000H           ;endereço inicial da RAM e programa do usuário
                jr      main            ;desvia para main
 
myout           db      1               ;var de saida para dados
mydata          db      1               ;var para colocar dados no LCD
myaux3          db      1

;-------------------------------------------------------------------------------
; Subrotina principal
;
main:           call    initLCD         ;configura LCD
                call    clearLCD
                call    snd2SPC
                
main_lc:        call    clearLCD
                ld      hl,msgLCD
                call    sendmsg         ;envia mensagem para LCD    
                
                call    t_500ms         ;aguarda
                call    t_500ms         ;
                
                call    clearLCD
                ld      hl,msgTranq
                call    sendmsg
                
                call    t_500ms         ;aguarda
                call    t_500ms         ;
                
                call    clearLCD
                ld      hl,msg2022
                call    sendmsg
                
                ld      b,4
main_lc2:       call    t_500ms
                djnz    main_lc2
                
                jr      main_lc         ;laço eterno
                
                halt                    ;trava aqui se passar ... never!
                
;-------------------------------------------------------------------------------
; subrotina para enviar msg para a LCD
; ponteiro da mensagem em HL
;
sendmsg:        ld      a,(hl)          ;pega conteudo
                ld      b,a             ;salva em b
                cp      00H             ;compara com final
                ret     z               ;retorna se chegou ao fim
                
                cp      LF              ;compara com LF
                jp      nz,sndcont      ;se nao, continua
                call    lin2LCD         ;muda para linha 2 do LCD
                inc     hl
                jr      sndcontLF       ;pula para não enviar o LF
                
sndcont:        ld      de,mydata       ;pega end da var de envio
                ld      a,b             ;restaura a com b
                ld      (de),a          ;coloca conteúdo da mensagem em a
                inc     hl              ;incrementa a posição de hl
                
                call    schLCD          ;envia char para LCD
sndcontLF:      call    t_50ms          ;aguarda
                
fsndstrlc:      jr      sendmsg        ;continua ate o fim

;-------------------------------------------------------------------------------
; Subrotina para mudar para linha 2 do LCD
;
lin2LCD:        push    hl

                ld      hl,mydata       ;coloca na var o char a ser escrito
                ld      a,0C0H          ;apaga LCD e coloca na coluna 1
                ld      (hl),a
                call    scomLCD         ;muda de linha no LCD
                
                pop     hl
                
                ret

;-------------------------------------------------------------------------------
; Subrotina para apagar o LCD
;
clearLCD:       ld      hl,mydata       ;coloca na var o char a ser escrito
                ld      a,01H           ;apaga LCD e coloca na coluna 1
                ld      (hl),a
                call    scomLCD         ;muda de linha no LCD

                ret
                
;-------------------------------------------------------------------------------
; Envia dois caracteres dummies antes de enviar uma string
;
snd2SPC:        ld      hl,mydata
                ld      a,' '
                ld      (hl),a
                call    schLCD
                call    t_50ms
                
                ld      hl,mydata
                ld      a,' '
                ld      (hl),a
                call    schLCD
                call    t_50ms

                ret

;-------------------------------------------------------------------------------
; Envia um char para o LCD - usa modo 4 bits
;
schLCD:         push    hl
                push    bc

                ld      hl,mydata       ;pega endereco da var
                ld      a,(hl)          ;pega o conteudo
                and     0F0H            ;limpa a parte menos significativa
                or      RS_ON           ;liga o pino de RS

                call    wrB8255A        ;envia A para portB
                call    EN_on           ;liga o pino EN - pulsa EN
                call    t_50us          ;aguarda
                call    EN_off          ;desliga o pino EN

                ld      hl,mydata       ;volta a pegar o end da var
                ld      a,(hl)          ;pega o conteudo
                sla     a               ;posiciona o LSB no MSB
                sla     a
                sla     a
                sla     a
                and     0F0H            ;limpa o LSB
                or      RS_ON           ;liga o RS

                call    wrB8255A        ;envia A para portB
                call    EN_on           ;liga o pino EN - pulsa EN
                call    t_50us          ;aguarda
                call    EN_off          ;desliga o pino EN

                pop     bc
                pop     hl
                
                ret

;-------------------------------------------------------------------------------
; Envia um comando para o LCD - usa modo 4 bits de dados
;
scomLCD:        ld      hl,mydata       ;pega endereco da var
                ld      a,(hl)          ;pega o conteudo
                and     0F0H            ;limpa a parte menos significativa
                and     RS_OFF          ;desliga o pino de RS

                call    wrB8255A        ;envia A para portB
                
                call    EN_on           ;liga o pino EN - pulsa EN
                call    t_50us          ;aguarda
                call    EN_off          ;desliga o pino EN

                ld      hl,mydata       ;volta a pegar o end da var
                ld      a,(hl)          ;pega o conteudo
                sla     a               ;posiciona o LSB no MSB
                sla     a
                sla     a
                sla     a
                and     0F0H            ;limpa o LSB
                and     RS_OFF          ;desliga o RS

                call    wrB8255A        ;envia A para portB
                call    EN_on           ;liga o pino EN - pulsa EN
                call    t_50us          ;aguarda
                call    EN_off          ;desliga o EN de strobe

                ret

;-------------------------------------------------------------------------------
; Subrotina para configurar/iniciar o LCD  - RS=0 e WR=0
; Le bytes em _initlcd e envia via porta paralela
; Configuracao adotada: modo 4 bits de dados, 2 linhas, caracter 5x7, cursor piscando
;
initLCD:        ld      a,00H           ;sao 5 bytes a enviar, comecando por zero
                ld      hl,myaux3       ;carrega endereco
                ld      (hl),a          ;guarda

initLCDloop:    ld      de,myaux3       ;pega o endereco da var
                ld      b,00H           ;zera a var
                ld      a,(de)          ;pega o conteudo de myaux3
                ld      c,a             ;carrega em c

                ld      hl,_inilcd      ;carrega endereco da var de configuracao
                add     hl,bc           ;posiciona o ponteiro
                ld      a,(hl)          ;pega primeiro byte
                ld      hl,mydata       ;pega endereco da var
                ld      (hl),a          ;coloca valor na var

                call    scomLCD         ;envia o comando para o LCD

                ld      hl,myaux3       ;carrega endereco
                ld      a,(hl)          ;pega conteudo
                inc     a               ;decrementa a
                ld      (hl),a          ;guarda conteudo
                cp      05H             ;compara com final - sao 7 comandos agora
                jp      nz,initLCDloop  ;se nao eh ainda o valor

                ret                     ;detectado fim, retorna!
                
;-------------------------------------------------------------------------------
; Subrotina strobe_on - liga pino de strobe
;
EN_on:          ld      hl,myEN         ;carrega end da var
                ld      a,01H           ;carrega valor ON
                jr      myEN            ;desvia

;-------------------------------------------------------------------------------
; Subrotina strobe_off - desliga pino de strobe
;
EN_off:         ld      hl,myEN         ;carrega end da var
                ld      a,00H           ;carrega valor OFF

;-------------------------------------------------------------------------------
; Subrotina mystrobe - liga/desliga pino de strobe
;
myEN:           call    wrA8255A        ;envia dado para portA
                ret                     ;retorna
                
;-------------------------------------------------------------------------------
; Dados para LCD - inicializacao
; comandos para inicializar o LCD - modo 4 bits
_inilcd:        db       02H, 28H, 06H, 0FH, 01H

;-------------------------------------------------------------------------------
; Mensagem para LCD_drZ80
;
msgDummie:      db      '  ',00H

msgLCD:         db      '  PLACA drZ80_uP',LF
                db      '   TESTE LCD    ',00H
                
msgTranq:       db      '  Bem-vindo ao  ',LF
                db      '  LAB do Arne   ',00H 
                
msg2022:        db      '     FELIZ      ',LF
                db      '     2022       ',00H 
                
;-------------------------------------------------------------------------------
; Fim do programa
;
                end

	


Copyright deste conteúdo reservado para Márcio José Soares e protegido pela Lei de Direitos Autorais LEI N° 9.610, de 19 de Fevereiro de 1998. É estritamente proibida a reprodução total ou parcial do conteúdo desta página em outros pontos da internet, livros ou outros tipos de publicações comerciais ou não, sem a prévia autorização por escrito do autor.