;******************************************************************** ;==================================================================== ; Program: custom.asm ; programmer(s): Dincer Aydin ; function:Demonstrates how custom characters are defined and used ;==================================================================== ;******************************************************************** ; This code requires a 2*16 LCD connected to a 8255 with base address of 00h ; routines sendcomA & sendcom & sendcharA & sendchar have been tested on ; >> 2*16 Hitachi LCD with HD44780 chip ; >> Samsung 1*16 LCD with a KS0062F00 chip ; >> 2*16 Epson LCD marked P300020400 SANTIS 1 ,and ; >> noname 1*16 HD44780 based LCD. ; The Z80 was clocked at 2 MHz and 4,9152 MHz for each display.This was done ; because the routines mentioned above take many t states and in most cases ; that will be longer that the time a HD44780 will need to execute a command. ; ; Connections: ; LCD data bus(pins #14-#7) connected to Port A of a 8255 with 00h base address ; LCD Enable pin(#6) connected to Port C bit #7 ; LCD R/W pin(#5) connected to Port C bit #6 ; LCD RS pin(#4) connected to Port C bit #5 ;8255 port address(base 00h): paadr equ 00h ; Address of PortA pbadr equ 01h ; Address of PortB pcadr equ 02h ; Address of PortC cwadr equ 03h ; Address of Control Word ;stuff to be written into the control word of the 8255: ;Some of the change the state of the ports and some manipulate ;bits on port C allpsin equ 9bh ; set all ports to input mode paincout equ 90h ; A input,C output,B output pandcout equ 80h ; set all ports to output mode pacoutbin equ 82h ; A output,C output,B input ;bit set/reset commands.These bits are the control signals for the LCD enable equ 0fh ; set portC bit #6 disable equ 0eh ; reset portC bit #6 read equ 0dh ; set portC bit #5 write equ 0ch ; reset portC bit #5 command equ 0ah ; reset portC bit #4 data equ 0bh ; set portC bit #4 ; Define number of commands and length of string data numofc equ 4h ; number of commands ; initialization: ld sp,200h ; Set stack pointer ld c,cwadr ld a,pacoutbin ; Ports A&C output,B input out (c),a ; *********It all begins here**********: ; This part sends commands to initialize the LCD call delay ld a,38h ; function set command ld b,4 again: ld c,cwadr ld d,command out (c),d ; select the instruction register ld d,write out (c),d ; reset RW pin for writing to LCD out (paadr),a ; place the command into portA ld d,enable out (c),d ; enable the LCD ld d,disable out (c),d ; disable the LCD call delay ; wait for a while djnz again ; loop till the command is sent 4 times ; send commands to set input mode, cursor,number of lines ,and etc. ld hl,combegadr ; set HL to point the first command ld b,numofc ; put the number of commands to be sent in B nextcom: call sendcom ; send (HL) as a command inc hl ; point the next command djnz nextcom ; loop till all commands are sent ; The code below will modify CG RAM contents to define 8 custom characters ld hl,custom_data ; make (HL) point custom character data ld a,40h call sendcomA ; Set CG RAM address to 00h by sendind 40h as a command ld b,40h ; use B to count number of bytes to be written to CG RAM ; 8 characters * 8 bytes = 64 bytes (40h) in this example next_byte: call sendchar ; write (HL) to CG RAM inc hl ; point the next byte to be written to CG RAM djnz next_byte ; loop till all bytes are sent ; Now that custom characters are defined , let's see them on the LCD screen ; The code below will print characters 0-7 (the ones we defined) to LCD screen ld b,8h ; use B to count the number of bytes to be written to DD RAM ld a,80h call sendcomA ; Set DD RAM adres to 00h by sending 80h as a command xor a ; clear a next_char: call sendcharA ; print ASCII character corresponding to the value in A inc a djnz next_char ; loop till ASCII characters 0-7 are sent to the LCD halt ; ==================================================================== ; Subroutine name:sendcomA & sendcom & sendcharA & sendchar ; programmer:Caner Buyuktuna & Dincer Aydin ; input:A or (HL) ; output: ; Registers altered:A ; function: sendcharA sends the data in A to the LCD ; sendchar sends the data in (HL) to the LCD ; sendcomA sends the command in A to the LCD ; sendcom sends the command in (HL) to the LCD ; ==================================================================== sendchar: ld a,(hl) ; put the data to be sent to the LCD in A sendcharA: push bc ; save BC push de ; save DE ld e,data ; jp common sendcom: ld a,(hl) sendcomA: push bc ; save BC push de ; save DE ld e,command common: call bfcheck ; See if the LCD is busy. If it is busy wait,till it is not. out (c),e ; Set/reset RS accoring to the content of register E ld d,write out (c),d ; reset RW pin for writing to LCD out (paadr),a ; place data/instrucrtion to be written into portA ld d,enable out (c),d ; enable the LCD ld d,disable out (c),d ; disable the LCD pop de ; restore DE pop bc ; restore BC ret ; return ; ==================================================================== ; Subroutine name:bfcheck ; programmer:Dincer Aydin ; input: ; output: ; Registers altered:D ; function:Checks if the LCD is busy and waits until it is not busy ; ==================================================================== bfcheck: push af ; save AF ld c,cwadr ld d,paincout out (c),d ; make A input,C output,B output ld d,read out (c),d ; set RW pin for reading from LCD ld d,command out (c),d ; select the instruction register check_again: ld d,enable out (c),d ; enable the LCD in a,(paadr) ; read from LCD ld d,disable out (c),d ; disable the LCD rlca ; rotate A left through C flag to see if the busy flag is set jp c,check_again ; if busy check it again,else continue ld d,pandcout out (c),d ; set all ports to output mode pop af ; restore AF ret ;==================================================================== ; Subroutine name:DELAY and PDELAY ; programmer(s):Dincer Aydin ; input:the value in HL (for PDELAY only) ; output:- ; Registers altered:H,L ; function:delay ; for more delay you can add a few nops or or some junk commands using the index ; registers ; pdelay uses what you put into HL before you called the PDELAY routine ;==================================================================== delay: ld hl,1010h pdelay: dec l jp nz,pdelay dec h jp nz,pdelay ret ;==================================================================== ; commands and strings combegadr: db 01h,80h,0ch,06h ; clear display,set DD RAM adress, ; turn on display with cursor hidden,set entry mode custom_data: ; These are the values to create some custom characters db 0,4,2,31,2,4,0,0 ; right arrow db 0,4,8,31,8,4,0,0 ; left arrow db 4,14,21,4,4,0,0,0 ; up arrow db 0,0,0,4,4,21,14,4 ; down arrow db 8,20,20,8,5,6,5,5 ; single-character "OK" db 14,17,17,31,27,27,31,0 ; locked (padlock closed) db 14,16,16,31,27,27,31,0 ; unlocked (padlock open) db 17,18,23,9,19,4,7,0 ; single-character "1/2" ; The custom character data above is taken from "LCD Serial Backpack App Note No. 2" ; from Scott Edwards Electronics Inc. www.seetron.com