LCDInfo.com

http://www.lcdinfo.com
It is currently Fri Nov 22, 2024 9:17

All times are UTC + 2 hours




Post new topic Reply to topic  [ 46 posts ]  Go to page 1, 2, 3, 4  Next
Author Message
PostPosted: Sun Dec 29, 2002 13:32 
Hi!

I'd like to know if anyone of you already has some experience in programming an LCD with VisualBasic. I don't know much about the protocol I have to use with the display. But I am quite a pro in VB ;)

Flo


Top
  
 
 Post subject:
PostPosted: Sun Dec 29, 2002 20:19 
Offline

Joined: Sun May 05, 2002 22:05
Posts: 2063
Location: Lappeenranta, Finland
I don't have any experience with visual basic but maybe I could help.

Have you checked the DLPortIO driver package ? There are some examples how to program ports in visual basic. When you have the driver working in your program controlling the LCD should be pretty much the same as in C/C++.

What kind LCD would you like to control ? I can give you examples how it is initialized and used (if i know how to use that particular controller).


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 30, 2002 18:15 
Offline

Joined: Mon Dec 30, 2002 18:10
Posts: 27
Location: Darmstadt, Germany
The controller is a t6963c. It is a 128*128 pixel LCD.

I understand the DLPortIO driver example. But I don't have much experience in programming hardware. With this example I can write an app that writes something to ports. But I don't know what that does on the display ;)

I know a little C/C++. It would be nice if you could give me some hints or example code how to show anything on the display :)

Flo

_________________
The answer to all questions is 42


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 30, 2002 19:25 
Offline

Joined: Sun May 05, 2002 22:05
Posts: 2063
Location: Lappeenranta, Finland
Ok, I can give you some hints. As I don't know visual basic these examples will be in C but if you have any questions just let me know.

Some information about parallel port:
http://www.phm.lu/Documentation/Connectors/Parallel.asp
http://ra2modding.virtualave.net/lpt.html
http://www.doc.ic.ac.uk/~ih/doc/par/doc/regpins.html

When you write a value to the parallel port register the pins are set like this for example:
value -> pins/bits (every bit corresponds to a pin in parallel port)
0 -> 00000000
1 -> 00000001
2 -> 00000010
3 -> 00000011
4 -> 00000100
5 -> 00000101
6 -> 00000110
7 -> 00000111
8 -> 00001000
and so on...
I wrote this in quite a hurry so please let me know if you notice something strange in this.

First some definitions used in the code:
Code:
#define G_BASE 0x0200   // base address of T6963C graphics memory (for 240x64 display)
#define T_BASE 0x0000   // base address of T6963C text memory
#define BYTES_PER_ROW 40 // characters per row for 6x8 font
#define BASE 0x378      // lpt port base address

How do you have the font select set ? 6x8 or 8x8 font ? If it's 8x8 font then BYTES_PER_ROW will be 30.

Function to write a data byte to the LCD. This is for the Pollin wiring shown here: http://www.skippari.net/lcd/t6963c_schem.html
It uses the timing sequence described in the T6963C datasheet. (1,5MB)

Code:
void WriteData(USHORT Data)
{

    // WaitDisplayReady(); // waits for the display to be ready before writing to it. this can be added if needed.
    DlPortWritePortUshort(BASE + 2, 0); // C/D = L (Data)
    DlPortWritePortUshort(BASE + 2, 2); // CE
    DlPortWritePortUshort(BASE, Data); // put data byte to D0...D7 pins of LCD
    DlPortWritePortUshort(BASE + 2, 3); // CE+WR
    DlPortWritePortUshort(BASE + 2, 2); // CE
    DlPortWritePortUshort(BASE + 2, 0);
}


Write control byte to the LCD. Also uses timing sequence from datasheet.

Code:
void WriteCtrl(USHORT Command)
{

    // WaitDisplayReady();
    DlPortWritePortUshort(BASE, Command); // put control byte to D0...D7 pins of LCD
    DlPortWritePortUshort(BASE + 2, 4); // C/D = H (ctrl)
    DlPortWritePortUshort(BASE + 2, 4+2); // CE
    DlPortWritePortUshort(BASE + 2, 4+3); // CE+WR
    DlPortWritePortUshort(BASE + 2, 4+2); // CE
    DlPortWritePortUshort(BASE + 2, 0);
}


Display initialization. Again datasheet is great help. Steve Lawther's document may be easier to follow than Toshiba's original datasheet.

Code:
void InitLCD(void)
{
  // Display init
  WriteData(T_BASE & 0xFF);   // Data1: LowAddress
  WriteData(T_BASE >> 8);     // Data2: HighAddress
  WriteCtrl(0x40);            // Command: 0x40 -> 01000000

  WriteData(BYTES_PER_ROW);  // Data1: Colums
  WriteData(0);              // Data2: 0
  WriteCtrl(0x41);           // Command: 0x41 -> 01000001

  WriteData(G_BASE & 0xFF);  // Data1: LowAddress
  WriteData(G_BASE >> 8);    // Data2: HighAddress
  WriteCtrl(0x42);           // Command: 0x42 -> 01000010

  WriteData(BYTES_PER_ROW);  // Data1: Colums
  WriteData(0);              // Data2: 0
  WriteCtrl(0x43);           // Command: 0x43 -> 01000011

  // Internal CGROM Mode, OR Mode
  WriteCtrl(0x80); // OR Mode    // 80->10000000

  WriteCtrl(0xa7); // cursor is 8 lines high
  WriteData(0x00);
  WriteData(0x00);
  WriteCtrl(0x21); // put cursor at (x,y)

  // DisplayMode
  WriteCtrl(0x9D);

}


I don't have time to write more at the moment but let me know what needs more explanation and I'll get back to it later.


Last edited by Henri on Wed Jan 01, 2003 13:49, edited 2 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 30, 2002 19:46 
Offline

Joined: Mon Dec 30, 2002 18:10
Posts: 27
Location: Darmstadt, Germany
Thanks a lot for the information!
I am trying to get it work, but until now I had no success. But I will stick on it :)

My display is connected like this:
Image

_________________
The answer to all questions is 42


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 30, 2002 20:01 
Offline

Joined: Mon Dec 30, 2002 18:10
Posts: 27
Location: Darmstadt, Germany
Hmm, I don't really have an idea how to start my program...

How can I just change one pixel? In which order do I have to write which addresses?
And I don't know for sure, which the base address is. I let LCDInfo show some BMPs and used the VB sample to read out address 0x378. On some pictures the value was 36 (in decimal) and on others 192 (decimal). I then tried to change the value, but except for one time nothing happened. That time the lower part of the picture was moved a few pixels to the left.

p.s.: My font select set is 6x8.

_________________
The answer to all questions is 42


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 30, 2002 23:24 
Offline

Joined: Sun May 05, 2002 22:05
Posts: 2063
Location: Lappeenranta, Finland
That wiring seems to be from http://www.feegy.de/LCDFAQ/ so it's the tweakers.net one. I guess you are using that setting with LCDInfo ? Also what base address do you have set in LCDInfo ? That is the one used here also. I guess it's 0x378.

Base (0x378) is the register where data pins D0...D7 are connected
Base+2 is where WR, RD, CE, CD are connected

WRITEDATA for your wiring
Code:
   
   DlPortWritePortUshort(BASE + 2, 0x0c);   // 0111 C/D low
   DlPortWritePortUshort(BASE + 2, 0x08);   // 0011 WR low
   DlPortWritePortUshort(BASE, Data);
   DlPortWritePortUshort(BASE + 2, 0x09);   // 0010 CE low
   DlPortWritePortUshort(BASE + 2, 0x08);   // 0011 CE high
   DlPortWritePortUshort(BASE + 2, 0x0c);   // 0111 WR high


WRITECOMMAND

Code:
   DlPortWritePortUshort(BASE + 2, 0x04);      // 1111 C/D high
   DlPortWritePortUshort(BASE + 2, 0x00);      // 1011 WR low
   DlPortWritePortUshort(BASE, Command);
   DlPortWritePortUshort(BASE + 2, 0x01);      // 1010 CE low
   DlPortWritePortUshort(BASE + 2, 0x00);      // 1011 CE high
   DlPortWritePortUshort(BASE + 2, 0x0c);      // 0111 C/D low


To write something to the display you need to implement these WriteData and WriteCommand functions.

Then initialize your display with these commands:
Code:
// Text home address
WriteData(T_BASE & 0xFF); // Data1: LowAddress
WriteData(T_BASE >> 8 ) // Data2: HighAddress
WriteCtrl(0x40); // Command: 0x40 -> 01000000

// Text area (how much to reserve memory for text)
WriteData(BYTES_PER_ROW); // Data1: Colums
WriteData(0); // Data2: 0
WriteCtrl(0x41); // Command: 0x41 -> 01000001

// Graphics home address
WriteData(G_BASE & 0xFF); // Data1: LowAddress
WriteData(G_BASE >> 8 ); // Data2: HighAddress
WriteCtrl(0x42); // Command: 0x42 -> 01000010

// Graphics area
WriteData(BYTES_PER_ROW); // Data1: Colums
WriteData(0); // Data2: 0
WriteCtrl(0x43); // Command: 0x43 -> 01000011

// Internal CGROM Mode, OR Mode
WriteCtrl(0x80); // OR Mode // 80->10000000

WriteCtrl(0xa7); // cursor is 8 lines high

WriteData(0x00); // cursor x
WriteData(0x00); // cursor y
WriteCtrl(0x21); // put cursor at (x,y)

// DisplayMode
WriteCtrl(0x9D);


Then to write a letter using the internal character generator:
Code:
 
// To set cursor position
void SetLCDXY(int x, int y)
{
  int addr;
  addr = T_BASE + (y * BYTES_PER_ROW) + x; // calculate place in memory
  WriteData(addr & 0xFF); // write calculated address
  WriteData(addr >> 8); // write calculated address
  WriteCtrl(0x24); // set cursor
}

// write character
WriteData(c); // c = HEX of character (T6963C characters are ASCII - 0x20)
WriteCtrl(0xc0); // write character and increment memory pointer


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 30, 2002 23:53 
Offline

Joined: Sun May 05, 2002 22:05
Posts: 2063
Location: Lappeenranta, Finland
Functions to clear text and graphics memory:
Code:
void ClearLCDText(void)
{
  int i;

  WriteData(T_BASE & 0xFF);
  WriteData(T_BASE >> 8);
  WriteCtrl(0x24);      // address pointer to T_BASE

  for (i=0;i<336;i++) {
        WriteData(0); WriteCtrl(0xc0); // write data and inc ptr
  }
}

void ClearLCDGraph(void)
{
  int i;

  WriteData(G_BASE & 0xFF);
  WriteData(G_BASE >> 8);
  WriteCtrl(0x24); // address pointer to G_BASE

  for (i=0;i<2731;i++){
        WriteData(0); WriteCtrl(0xc0); // write data and inc ptr
  }
}


Set pixel:
Code:
void SetLCDPixel(int x, int y)
{
  int addr;

  addr = G_BASE + (y*BYTES_PER_ROW) + (x/font_width);
  WriteData(addr & 0xFF);
  WriteData(addr >> 8);
  WriteCtrl(0x24);
  WriteCtrl(0xf8 | (font_width-1-(x % font_width)));
}


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 31, 2002 13:30 
Offline

Joined: Mon Dec 30, 2002 18:10
Posts: 27
Location: Darmstadt, Germany
Yes, I used http://www.feegy.de/LCDFAQ/ for wiring. In LCDInfo the port is 0x378.

I have implemented all the functions, but have one problem: I don't know what the >> operator does. I only know it from a few C++ examples where it was used with cin (cin >> variable). I have tried to find an equivalent for VB but had no success.

_________________
The answer to all questions is 42


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 31, 2002 14:18 
Offline

Joined: Sun May 05, 2002 22:05
Posts: 2063
Location: Lappeenranta, Finland
floppes wrote:
I have implemented all the functions, but have one problem: I don't know what the >> operator does. I only know it from a few C++ examples where it was used with cin (cin >> variable). I have tried to find an equivalent for VB but had no success.

>> is bitwise right shift.

I guess visual basic doesn't have these at all. This is what I found with google: http://www.freevbcode.com/ShowCode.Asp?ID=2045

I'm sure there is some solution but I don't have time to look for it just now.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 31, 2002 15:02 
Offline

Joined: Mon Dec 30, 2002 18:10
Posts: 27
Location: Darmstadt, Germany
Ok, that code works fine.

Now when I run the initialization I get this picture:

Image

Maybe I have to use the WaitDisplayReady() function. Could you post it here? :)

If you are busy, first do your stuff and then answer me. I don't want to hinder you doing your work. 8)

_________________
The answer to all questions is 42


Last edited by floppes on Tue Dec 31, 2002 16:25, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 31, 2002 15:29 
Offline

Joined: Mon Dec 30, 2002 18:10
Posts: 27
Location: Darmstadt, Germany
Now I got the Clear functions to work! I had to change the loop in ClearLCDGraph to 16384 (128*128) and the in ClearLCDText to 315 (21*15).

But currently I have some problems with my display. Even the pictures LCDInfo shows, are crippled (but the text is ok). Can this be caused by wrong writings to the display? I have already restarted my computer and switched it off.

_________________
The answer to all questions is 42


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 31, 2002 16:30 
Offline

Joined: Mon Dec 30, 2002 18:10
Posts: 27
Location: Darmstadt, Germany
I am getting into it! :)

Now I can display text perfectly without any graphics errors.
I also wrote a function to display a BMP, but there I have some problems.
On this picture I tried to display a completely black image:

Image

As you see, some pixels are still not displayed and there are white lines from top to bottom. I think this is caused because I don't wait until the display is ready (because I don't know how :D).
I draw the image from X axis to Y axis, which means from left to right.

_________________
The answer to all questions is 42


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 31, 2002 16:35 
Offline

Joined: Sun May 05, 2002 22:05
Posts: 2063
Location: Lappeenranta, Finland
WaitDisplayReady() for Pollin wiring
Code:
void WaitDisplayReady(void)
// reads the display status byte and checks
// that the display is ready before writing

// doesn't have any check in case the status byte
// can't be read so this situation may cause a lockup

{
 
  int Tmp;

       Tmp = DlPortReadPortUshort(BASE + 0x402);
       Tmp = Tmp & 0x1F;
       Tmp = Tmp | 0x20;
       DlPortWritePortUshort(BASE + 0x402, Tmp);

       do{
             DlPortWritePortUshort(BASE + 2, 0x20 + 4 + 2);     //In, CD=1, CS=0, Wr=1
             DlPortWritePortUshort(BASE + 2, 0x20 + 4 + 2 + 8); //In, CD=1, CS=0, Wr=1, Rd=0
             Tmp = DlPortReadPortUshort(BASE);
             DlPortWritePortUshort(BASE + 2, 0x20 + 4 + 2);     //In, CD=1, CS=0, Wr=1

       }while ((Tmp & 3) != 3 );
       DlPortWritePortUshort(BASE + 2, 0);
   
}


In your wiring they are like this:
LCD - LPT
CE - 1 strobe
RD - 14 line
WR - 16 init
CD - 17 select

CE - 0001 - 1
RD - 0010 - 2
WR - 0100 - 4
CD - 1000 - 8

To make it more complicated LPT pins 1, 14 and 17 are inverted.


Last edited by Henri on Wed Jan 01, 2003 13:46, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 31, 2002 17:18 
Offline

Joined: Sun May 05, 2002 22:05
Posts: 2063
Location: Lappeenranta, Finland
WaitDisplayReady() for tweakers.net/powerlcd/what you want to call it wiring.

I just tried to change to code to reflect the different wiring and I also looked at the datasheet and this doesn't look right. But you can always try if it would work.

Code:
void WaitDisplayReady(void)
// reads the display status byte and checks
// that the display is ready before writing

// doesn't have any check in case the status byte
// can't be read so this situation may cause a lockup

{
 
  int Tmp;

       Tmp = DlPortReadPortUshort(BASE + 0x402);
       Tmp = Tmp & 0x1F;
       Tmp = Tmp | 0x20;
       DlPortWritePortUshort(BASE + 0x402, Tmp);

       do{
             DlPortWritePortUshort(BASE + 2, 0x20 + 2);     //In, CD=1, CS=0, Wr=1
             DlPortWritePortUshort(BASE + 2, 0x20 ); //In, CD=1, CS=0, Wr=1, Rd=0
             Tmp = DlPortReadPortUshort(BASE);
             DlPortWritePortUshort(BASE + 2, 0x20 + 2);     //In, CD=1, CS=0, Wr=1

       }while ((Tmp & 3) != 3 );
       DlPortWritePortUshort(BASE + 2, 0);
   
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 46 posts ]  Go to page 1, 2, 3, 4  Next

All times are UTC + 2 hours


Who is online

Users browsing this forum: No registered users and 32 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group