Pascal Demo code to drive NEC uPD7228G

Here is some Turbo Pascal 6 code to drive the EA-N16025AR module via the printer port.

These modules use the NEC uPD7228G chips. A later form of the chip is uPD16434 in 10299e10.pdf currently downloadable as a 1.8Mb scanned in data sheet from NEC uPD7228G chips.

The NEC web page is NEC's Web Site at http://www.nec.de, but it does not have the Chip details any more

Thanks to michael.gaus@ngi.de , here is a scanned sheet for the modules: ea-x_series.pdf. ( 556k bytes). It does however have some interesting information about the EA-N series modules which use the NEC uPD7228G as well.

I brought some of these displays from or Greenweld Electronics .

Doug Rice, doug.h.rice@btinternet.com

Updated 6th June 1999 & 1st May 2000

Copyright 1999

 

{
| This demo program drives the LCD display via the LPT port.       
| The modules clock is driven by an external oscillator of about 100kHz
|
| This demo does not read the /BUSY line.
| This demo does not support reading from the Display module.
| This demo does not support the serial input mode.
|
| This code was written from the chip's data sheets.
| The module's pin connections have been reverse engineered.
| The data sheet for the module has yet to be located.

EA-N16025AR uses a pair of NEC D7228G LCD chips a 2 X 16 display
EA-N20016AR possibly also uses a pair of NEC D7228G chips. 1 x 20 display

EA-N16025AR uses a pair of NEC D7228G LCD chips
===============================================
A later form of the chip is uPD16434 in 10299e10.pdf currently downloadable
as a 1.8Mb scanned in data sheet. The NEC web page is  


NEC's Web Site at http://www.nec.de

Looking from the Display side, the connector has 14 pins. I will number them from right to left [ DISPLAY ] [ ] 14 13 12 11 10 9 8 7 6 5 4 3 2 1 LPT1 conn chip name db0 14 27 D0 SI I,O db1 13 28 D1 P/-S I,O Data 1 or Parrallel /serial mode db2 12 29 D2 CAE I,O db3 11 30 D3 S0 I,O NC 10 32 /BUSY O db5 9 35 /STB /SCK I Strobes each nibble into chip db6 8 36 C /D I Command /data 1 for command, 0 for data and reading db7 7 40 RESET I RESET db4 6 39 /CS I Selects the display clk 5 41 CLOCK I NC 4 CASE -ve 3 - Vlcd gnd 2 34 Vss GND +4.5V 1 33 Vdd +ve The D7228G can be programmed Parrallel or serially. | } program lcd_hack; USES crt; var G_CA :integer; { used to select which 7228 chip is addressed} MM :integer; try :integer; counter :integer; base :integer; dummy :char; const { Configure to the port address of the Printer port being used } LPT1 = $378; { LPT1 = $3BC; } { The Epson EA-N 16025AR uses 2 NEC D 7228G chip in a pair. } { data bits LTP+0} { during rising edge of Strobe input NSTRB } D0 = $01; { 0; } D1 = $02; { 1; } D2 = $04; { 2; } D3 = $08; { 3; } SI = $01; { 0; Serial Input } SO = $08; { 3; Serial Output } { during falling edge of RESET input } PNS = $02; { 1; select parrallel/-Serial on falling RESET } CAE = $04; { 2; Chip Address Enable ( for serial mode only ) } { during rising edge of Strobe input NSTRB } CA0 = $01; { 0; CA = chip select, CAE enabled or always during parrallel } CA1 = $02; { 1; if D0,D1 = CA0,CA1 pins as STRB goes low } { Strobe input, } { If parrallel mode,strobes in nibble } { If serial mode,strobes in each bit -see data sheet } NSTB = $20;{ 5;/Strobe } { hold at the same level for whole 8 bits } CND = $40; { 6; selects if 8 bits are Command or /DATA, } RESET= $80; { 4; Reset, active high } NCS = $10; { 7; /Chip Select, active low } { cntl bits LTP+2 } CLOCK = $04; { 3; } { Commands } { | Chip commands:- | ======================================== } { Set Frame Frequency, Divides the CLOCK input } SFF_0 = $10; { div 2^14 } SFF_1 = $11; SFF_2 = $12; SFF_3 = $13; SFF_4 = $14; { div 2^10 } { Set Multiplexing Mode } { | The two chips work together. | They are only joined by the sync pins which are joined together. | Configure sync as output on one chip, and an inputs on the other. | | Commands need to be sent to each chip seperately. | | Select the Chip by putting the CA on DB0,DB1 | during falling edge of NSTRB. | | The nibbles of the data are read in on rising edge of NSTRB. | The most significant nibble is written in first. | | | The display forms four segments. | R0-R7 [ ][ ] LDPI = 39 to 0 | R8-R15 [ ][ ] LDPI = 39 to 0 +$40 | C0-C49 C0-C49 for 10 char display. | C0-C40 C0-C40 for 8 char display. | CA=0, CA=3, | | Row pins are either R0 to R7 or R8 to R15. | Col pins 42 to 49 can be configured to be R8 to R15 | The SMM command configures these. | } SMM = $18; { See Data Sheet } { SMM_8_R07_C42_ip_mem0 = $18+0; SMM_8_R07_C42_ip_mem1 = $18+1; SMM_8_R07_C42_op_mem0 = $18+2; SMM_8_R07_C42_op_mem1 = $18+3; SMM_16_R815_C42_ip_mem0 = $18+4; SMM_16_R815_C42_ip_mem1 = $18+5; SMM_16_R07_C42_op_mem0 = $18+6; SMM_16_R07_R158_op_mem1 = $18+7; { Display On } DISP_ON = $09; { Display Off } DISP_OFF = $08; { Load Data Pointer Immediate } LDPI = $80; { There are two banks, add $40 for Bank 1 } { In Char mode the pointer increments by 5} SRM = $60; { Set Read Mode } { Set Write Mode - The LSB is top pixel, the MSB is pixel in cursor } SWM = $64; { Set Write mode - replace } SORM = $68; { Set OR mode - OR new bits with those present } SANDM = $6C; { Set AND mode - AND new bits with those present } { Add to SWM,SORM,SANDM,BRESET,BSET, to change Data Pointer } INC = 0; DEC = 1; EQU = 3; { Character Commands - The data causes a Char to be copied to screen } SCML = $71; { Set Char mode, copy Char from Char rom } SCMR = $72; { Bit Commands, BIT to be set needs to be x 4 then added } BRESET = $20; BSET = $40; { When in Char mode the cursor is set or cleared } CLCURS = $7C; WRCURS = $7D; { put the display into sleep mode } STOP = $01; var CNT,cnt2 : byte; procedure wlcd( cmd:byte ); begin port[ LPT1 ] := cmd; delay(10); { 50 works } end; procedure wlcdc( cmd:byte ); begin port[ LPT1+2 ] := cmd; delay(10); { 50 works } end; procedure wlcdReset; begin { { Select Parrallel mode RESET -----______ When RESET is goes low sample line P/-S ----------- CAE ----------- only used in serial mode. } wlcd( NSTB OR D1 OR CAE OR NCS ); delay(2); wlcd( NSTB OR D1 OR CAE ); delay(2); wlcd( RESET OR NSTB OR D1 OR CAE ); delay(2); wlcd( NSTB OR D1 OR CAE ); delay(2); end; procedure wlcdByte( cmd:byte; cnd:byte ); var CA : integer; begin CA := g_ca; { CS ---___________________-- Chip Select D0,D3----CA---DDD--CA--DDD--- Data Lines or CA lines STRB -----_____-----____----- Strobe CND ===x==================x= Command/ not data RESET________________________ Reset 0 123 45 67 89 A } {0:} wlcd( NCS OR NSTB OR CA OR cnd ); delay(2); {1:} wlcd( NSTB OR CA OR cnd ); delay(2); {2:} wlcd( CA OR cnd ); delay(2); {4:} wlcd( ( (cmd shr 4) AND $0F ) or cnd ); delay(2); {5:} wlcd( NSTB OR ( (cmd shr 4) AND $0F ) or cnd ); delay(2); {6: start the next nibble } wlcd( NSTB OR CA OR cnd ); delay(2); {7:} wlcd( CA OR cnd ); delay(2); {8:} wlcd( ( cmd AND $0F ) or cnd ); delay(2); {9:} wlcd( NSTB OR ( cmd AND $0F ) or cnd ); delay(2); {A:} wlcd( NCS OR NSTB OR ( cmd AND $0F ) or cnd ); delay(2); end; procedure wlcdCMD( cmd:byte ); begin wlcdByte( cmd,CND); end; procedure wlcdDATA( cmd:byte ); begin wlcdByte( cmd,0); end; procedure wlcdInit; begin wlcdReset; { Configure left chip as the master, sync is output } g_ca := 0; wlcdCMD( SMM + 7 ); { set Sync to output } wlcdCMD( SFF_4 ); wlcdCMD( DISP_ON ); g_ca := 3; wlcdCMD( SMM + 5 ); { set Sync to input } wlcdCMD( SFF_4 ); wlcdCMD( DISP_ON ); end; BEGIN g_ca := 0; MM := 0; try := 0; base := $20; while ( 1= 1 ) do begin try := try + 1 ; mm := ( try SHR 3 ) and 7 ; G_CA := try and 3; mm := 3; { when trying to find out what worked mm was added to the SMM cmd } g_ca := 0; { Write commands and data to Left chip } writeln(try:4,mm:4,g_ca:4); wlcdInit; g_ca := 3; { Write commands and data to Right chip } { Write directly to pixels } wlcdCMD( SWM ); wlcdCMD( LDPI ); for counter := 0 to 4 do begin wlcdDATA( counter ); end; wlcdDATA( $14 ); wlcdDATA( $22 ); wlcdDATA( $41 ); wlcdDATA( $22 ); wlcdDATA( $14 ); wlcdCMD( SORM ); wlcdDATA( $14 ); wlcdDATA( $22 ); wlcdDATA( $41 ); wlcdDATA( $22 ); wlcdDATA( $14 ); wlcdCMD( SANDM ); wlcdDATA( $14 ); wlcdDATA( $22 ); wlcdDATA( $41 ); wlcdDATA( $22 ); wlcdDATA( $14 ); wlcdDATA( $AA ); wlcdDATA( $55 ); wlcdDATA( $AA ); wlcdDATA( $55 ); wlcdDATA( $AA ); wlcdCMD( LDPI +$40); { for counter := 0 to 255 do begin wlcdDATA( counter ); end; } wlcdCMD( SCMR ); wlcdCMD( LDPI + $0 + 5*8-1 ); wlcdDATA( $30 ); wlcdDATA( $31 ); wlcdDATA( $32 ); wlcdDATA( $33 ); g_ca := 3; wlcdCMD( LDPI ); wlcdDATA( $30 ); wlcdDATA( $31 ); wlcdDATA( $32 ); wlcdDATA( $33 ); wlcdDATA( $34 ); wlcdDATA( $35 ); wlcdDATA( $36 ); wlcdDATA( $37 ); wlcdCMD( LDPI + +$40 + 39); wlcdCMD( SCML ); for counter := 0 to 7 do begin wlcdCMD( CLCURS ); end; { Position Cursor to the bottom left } wlcdCMD( LDPI + 39 ); wlcdCMD( SCML ); wlcdDATA( ORD(' ')); wlcdDATA( ORD('H')); wlcdDATA( ORD('e')); wlcdDATA( ORD('l')); wlcdDATA( ORD('l')); wlcdDATA( ORD('o')); wlcdDATA( ORD(' ')); wlcdDATA( ORD(' ')); wlcdCMD( LDPI + $40 + 39 ); wlcdCMD( SCML ); wlcdDATA( ORD(' ')); wlcdDATA( ORD('W')); wlcdDATA( ORD('o')); wlcdDATA( ORD('r')); wlcdDATA( ORD('l')); wlcdDATA( ORD('d')); wlcdDATA( ORD(' ')); wlcdDATA( ORD(' ')); g_ca := 3; wlcdCMD( LDPI ); wlcdDATA( $30 ); wlcdDATA( $31 ); wlcdDATA( $32 ); wlcdDATA( $33 ); wlcdDATA( $34 ); wlcdDATA( $35 ); wlcdDATA( $36 ); wlcdDATA( $37 ); wlcdDATA( $38 ); wlcdDATA( $39 ); wlcdDATA( $41 ); wlcdDATA( $42 ); wlcdCMD( LDPI + $40 ); wlcdCMD( SCML ); wlcdDATA( $40 ); wlcdDATA( $41 ); wlcdDATA( $42 ); wlcdDATA( $43 ); wlcdDATA( $44 ); wlcdDATA( $45 ); wlcdDATA( $46 ); wlcdDATA( $47 ); wlcdDATA( $48 ); wlcdDATA( $49 ); { now address each quarter in turn } g_ca:=3; wlcdCMD( SCML ); wlcdCMD( LDPI + 39); for counter := 0 to 7 do begin wlcdDATA( base + counter ); end; wlcdCMD( LDPI + 39); for counter := 0 to 7 do begin wlcdCMD( CLCURS ); end; g_ca:=0; wlcdCMD( SCML ); wlcdCMD( LDPI + 39); for counter := 8 to 15 do begin wlcdDATA( base + counter ); end; wlcdCMD( LDPI + 39); for counter := 0 to 7 do begin wlcdCMD( CLCURS ); end; g_ca:=3; wlcdCMD( SCML ); wlcdCMD( LDPI + $40 + 39); for counter := 16 to 23 do begin wlcdDATA( base + counter ); end; wlcdCMD( LDPI + $40 + 39); for counter := 0 to 7 do begin wlcdCMD( CLCURS ); end; g_ca:=0; wlcdCMD( SCML ); wlcdCMD( LDPI + $40 + 39); for counter := 24 to 31 do begin wlcdDATA( base + counter ); end; wlcdCMD( LDPI + $40 + 39); for counter := 0 to 7 do begin wlcdCMD( CLCURS ); end; base := base + 32; g_ca:=0; wlcdCMD( STOP ); g_ca:=3; wlcdCMD( STOP ); writeln('++++++++++++++++'); end; END.

Last Modified: