;************************************************************************ ;======================================================================== ; Program: Code template for using HD44780 based LCDs with Z80 and a 8255 ; programmer(s): ; function: ;======================================================================== ;************************************************************************ ; 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 ; Initialization is complete. ; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; ; ; ; Insert your code here. ; ; ; ; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; ==================================================================== ; 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