Connect a LCD display to the parallel port of PC

Started by colormyworld, December 27, 2011, 12:27:25 PM

Previous topic - Next topic

dedndave

colormyworld,

the basic first questions is:
is the program to be 16-bit or 32-bit

if you want to write 32 bit code, the I/O ports are not directly available to you
although, i think it can be done, in the case of parallel or serial ports

if you want to write 16-bit code (such as that posted by Steve), the port is directly accessible
however, the software will not run under 64-bit operating systems without some virtual environment like DosBox

colormyworld


dedndave


dedndave

i see that the link i previously posted was moved...
http://retired.beyondlogic.org/parlcd/parlcd.htm

the I/O port base addresses are in the BIOS data (segment at 40h)
the first parallel port is at offset 8 - the others follow at 0Ah, 0Ch
if the value is 0, the port does not exist
once you have the port base address, it is a pretty simple interface


jj2007

For 32-bit code, the InpOut32 freeware dll is available at Logix4U.

Other options include writing a driver for rep outsb, plus StartDocPrinter and WriteFile...

dedndave

that's a cool option - and i see they have a 64-bit version, as well
but - i was under the impression that you could enable I/O with DeviceIoCtl
not that i've tried it or had any success with it   :P


NoCforMe

Don't know how much it'll help you, but I can post some working code that drives a small LCD (16 X 2) from a microcontroller (SX-28). It could be pretty easily done in '86 assembly language. Anyway, here it is:


;********  LCD stuff:  ********
LCD_CMD_FUNC_SET EQU $28 ;4 bit mode/2 lines/5x7 font
LCD_CMD_ENTRY_MODE EQU 6 ;Increment cursor/no shift
LCD_CMD_DISPLAY_ON EQU $0C ;Display on/cursor off/no blink
LCD_CMD_DISPLAY_CLR EQU 1 ;Wipe that display!

;********  LCD initialization:  ********

; Wait for 15 ms:
MOV W, #DELAY_15mS_H
MOV TimerHigh, W
MOV W, #DELAY_15mS_L
MOV TimerLow, W
CALL LongDelay

; Send "Function Set" command:
MOV W, #LCD_CMD_FUNC_SET
CALL WriteLCD_CMD

; Send "Function Set" command again:
MOV W, #LCD_CMD_FUNC_SET
CALL WriteLCD_CMD

; Send "Function Set" command yet again:
MOV W, #LCD_CMD_FUNC_SET
CALL WriteLCD_CMD

; Send "Function Set" command yet again:
MOV W, #LCD_CMD_FUNC_SET
CALL WriteLCD_CMD

; Send "Entry Mode Set" command:
MOV W, #LCD_CMD_ENTRY_MODE
CALL WriteLCD_CMD

; Send "Display On/Off" command:
MOV W, #LCD_CMD_DISPLAY_ON
CALL WriteLCD_CMD

; Send "Display Clear" command:
MOV W, #LCD_CMD_DISPLAY_CLR
CALL WriteLCD_CMD


;*******************************************************
; Write to LCD routines
;
; WriteLCD_CMD & WriteLCD_Data do the respective thangs.
; (Only difference is the initial setting of the register
; select [RS] line.)
;
; On entry:
; Data/command byte is in W
;*******************************************************

WriteLCD_CMD
CLRB LCD_RS ;RS = CMD
JMP WriteLCD

WriteLCD_Data
SETB LCD_RS ;RS = data

WriteLCD
MOV Temp, W ;Save a copy of data/command byte.
MOV W, <>Temp ;Swap high <--> low nybbles & get them.
AND W, #$0F ;Mask off low (actually high) nybble.

;*** Output 1st nybble: ***
MOV LCD_DATA_PORT, W ;Write data/command byte
; Set write mode, then strobe enable line:
CLRB LCD_RW ;RW = write
SETB LCD_E ;Strobe E: first high,
NOP ; (grace period)
CLRB LCD_E ; then back low

;*** Output 2nd nybble: ***
MOV W, Temp ;Get original byte back.
AND W, #$0F ;Mask off low nybble
MOV LCD_DATA_PORT, W
; Strobe enable line:
SETB LCD_E ;Strobe E: first high,
NOP ; (grace period)
CLRB LCD_E ; then back low

;Both nybbles written: set up to read busy flag.
; First, set LCD data port (RC) as input on SX28:
MODE M_DIR ;Set I/O direction for port C
MOV W, #C_READ_BITS ;Set port as input
MOV !RC, W
busy1 SETB LCD_RW ;RW = read
CLRB LCD_RS ;RS = CMD
SETB LCD_E ;Strobe E again
NOP
MOV W, LCD_DATA_PORT ;Read LCD data (only need bit 7)
CLRB LCD_E

SETB LCD_E ;Pulse E again
NOP ;to read the other 4 bits out
CLRB LCD_E ;and just throw them away.

; Read busy flag & check it until it ain't busy:
AND W, #$8 ;Check bit 7 (of the LCD; bit 3 of the port)
SZ ;We're looking for it to be low
JMP busy1 ;Still busy

MODE M_DIR ;Set LCD port back to output
MOV W, #C_DIR_BITS
MOV !RC, W
CLRB LCD_RW ;LCD back to write mode.
RET


Notice the sequence of commands being written to the LCD at the top. I found that some of these commands have to be sent several times in order to "stick". Seems pretty dumb, but it works.

Also notice the item at the top that sets 4-bit mode. Turns out there are two ways to drive these little LCDs: you can send data (characters) 4 or 8 bits at a time. I opted for 4 bits, since it meant less wiring on the hardware side, but a little more code, since you have to send each character as 2 4-bit nybbles. Just something else you need to know about LCD programming.

farrier

These links are for parallel and serial communications--works with all win32 versions:

Assembly code using standard SDK calls, no extra .dll's or drivers needed:

http://www.masm32.com/board/index.php?topic=12488.msg96491#msg96491
works with Win 7 also

http://www.masm32.com/board/index.php?topic=4464.msg33340#msg33340

Serial port communications:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfiles/html/msdn_serial.asp


hth,

farrier
It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)

jj2007

Quote from: farrier on January 10, 2012, 08:01:51 AM
These links are for parallel and serial communications--works with all win32 versions:

Assembly code using standard SDK calls, no extra .dll's or drivers needed:

http://www.masm32.com/board/index.php?topic=12488.msg96491#msg96491
works with Win 7 also

Quote from: jj2007 on January 08, 2012, 10:20:22 PM
Other options include writing a driver for rep outsb, plus StartDocPrinter and WriteFile...

Hi farrier,
WriteFile to LPT1 sounds good indeed but I've read somewhere the problem is to keep signals "on" for a defined time, i.e. it's not just write & forget. Perhaps colormyworld could simply test if it works?

farrier

jj2007,

I'm not sure what you mean by, 'to keep signals "on" for a defined time'.  The routines I included, run everyday in many businesses.  Very few problems over many years.

farrier
It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)

jj2007

Hi farrier,
It might work perfectly, if the receiving interface allows it. But apparently that is not always the case, try googling "parallel port" signal level writefile...
:thumbu

dedndave

yah - for this type of thing, you need to be able to have absolute power over all the control lines

fortunately, this is an output device
for input devices, you may want to write an INT handler
i dunno how that might be done in 32-bit, but i suspect it would require a KMD, at least

some day, i'll have to figure it out, too
more than once, i have done that type of thing in 16-bit to run some client's "gadget"   :P
i used to use the serial port handshake lines for input all the time
because they can be set up to generate an INT and are easy to connect

dedndave

well - there are all kinds of things wrong with that code
don't feel bad, we all had to start someplace   :U

i was looking at the datasheet for the display
it has absolutely no description or "theory of operation" section
but, it does mention one thing that helps (other than the pinout)
that is that it uses a Samsung KS0066 or equiv controller

i managed to find a reasonable description for the controller...
http://www.4shared.com/zip/UzcW6DNo/KS0066.html
scroll down to the section named "FUNCTION DESCRIPTION"

you will also want this PDF...
http://retired.beyondlogic.org/spp/parallel.pdf

do you have it hooked up like this ????