LCDInfo.com http://forum.lcdinfo.com/ |
|
Programming with VisualBasic [T6963C] http://forum.lcdinfo.com/viewtopic.php?f=9&t=78 |
Page 1 of 4 |
Author: | floppes [ Sun Dec 29, 2002 13:32 ] |
Post subject: | Programming with VisualBasic [T6963C] |
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 |
Author: | Henri [ Sun Dec 29, 2002 20:19 ] |
Post subject: | |
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). |
Author: | floppes [ Mon Dec 30, 2002 18:15 ] |
Post subject: | |
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 |
Author: | Henri [ Mon Dec 30, 2002 19:25 ] |
Post subject: | |
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. |
Author: | floppes [ Mon Dec 30, 2002 19:46 ] |
Post subject: | |
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: |
Author: | floppes [ Mon Dec 30, 2002 20:01 ] |
Post subject: | |
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. |
Author: | Henri [ Mon Dec 30, 2002 23:24 ] |
Post subject: | |
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 |
Author: | Henri [ Mon Dec 30, 2002 23:53 ] |
Post subject: | |
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))); } |
Author: | floppes [ Tue Dec 31, 2002 13:30 ] |
Post subject: | |
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. |
Author: | Henri [ Tue Dec 31, 2002 14:18 ] |
Post subject: | |
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. |
Author: | floppes [ Tue Dec 31, 2002 15:02 ] |
Post subject: | |
Ok, that code works fine. Now when I run the initialization I get this picture: 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. |
Author: | floppes [ Tue Dec 31, 2002 15:29 ] |
Post subject: | |
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. |
Author: | floppes [ Tue Dec 31, 2002 16:30 ] |
Post subject: | |
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: 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 ). I draw the image from X axis to Y axis, which means from left to right. |
Author: | Henri [ Tue Dec 31, 2002 16:35 ] |
Post subject: | |
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. |
Author: | Henri [ Tue Dec 31, 2002 17:18 ] |
Post subject: | |
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); } |
Page 1 of 4 | All times are UTC + 2 hours |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |