LCDInfo.com http://forum.lcdinfo.com/ |
|
C programmin 4 fun http://forum.lcdinfo.com/viewtopic.php?f=9&t=1316 |
Page 1 of 3 |
Author: | Kneego [ Mon Aug 22, 2005 15:52 ] |
Post subject: | C programmin 4 fun |
Hi all!!! New here and find this forum very informative. I recently bought my first LCD, 128x64 KS0108 and now playin with it. I want 2 make my own simple program using Borland C and DLportIO. I used the codes from the testprogram and the text-output works fine now. I figured out how the font-system works but how can I make it write chinese-font? Most fonts I saw is 8 pixels in height, because the parallelport can only write 8bits at once but in chinese-font u need more than 8 pixel in height. One solution is 2 write one chinese-character on 2 separate rows but it makes the font-system complex 2 recall one character, can some1 plz help me? Another problem i have is that I need a function 2 write ONE pixel on a spec. location. I want 2 convert my snake-game 2 show on the LCD-display Happy 4 any answers sry 4 my poor english Kneego Code: //this code is cutted
#include "font.h" //font 8x8 #include "font2.h" //font 5x7 #include "chinese.h" #include "dlportio.h" #include "needed_stuff.h" typedef unsigned char byte; #define SIZEBMP 1086 #define SIZELCD 1024 static int i; byte count, arrayLCD[SIZELCD], arrayBmp[SIZEBMP]; #define DISPLAY_ON 0x3f //0011 1111 #define DISPLAY_OFF 0x3e //0011 1110 #define DISPLAY_STARTLINE 0xc0 //1100 0000 <<<<< #define DISPLAY_PAGE_SET 0xb8 //1011 1000 #define DISPLAY_COLUMN_SET 0x40 //0100 0000 #define DATAREG 0x378 //lpt1 #define CONTROL 0x37A #define LCD_ENABLE 1 //0001 Inverted PIN !!! #define LCD_CS1 0 //0000 Inverted PIN !!! #define LCD_CS2 6 //0110 #define LCD_inst 8 //1000 Inverted PIN !!! di tai rs unsigned char CurrentColumn,DisplayData[8*128+1], CharacterTbl[256*32+1]; unsigned int a; void Delay(long microseconds) { //Delay -function } void OmaDelay(void) { unsigned int viive=1; Delay(viive); } void SendLCDCommand(unsigned char value, unsigned char CS) { OmaDelay(); DlPortWritePortUshort(CONTROL, LCD_ENABLE | CS | LCD_inst); OmaDelay(); DlPortWritePortUshort(DATAREG, value); OmaDelay(); DlPortWritePortUshort(CONTROL, CS | LCD_inst); OmaDelay(); DlPortWritePortUshort(CONTROL, LCD_ENABLE | CS | LCD_inst); OmaDelay(); DlPortWritePortUshort(DATAREG, 0); } void SetStartLine(unsigned char line) { SendLCDCommand(DISPLAY_STARTLINE | (line & 63), LCD_CS1); SendLCDCommand(DISPLAY_STARTLINE | (line & 63), LCD_CS2); } void SetPage(unsigned char x) { SendLCDCommand(DISPLAY_PAGE_SET | x, LCD_CS1); SendLCDCommand(DISPLAY_PAGE_SET | x, LCD_CS2); } void SetColumn(unsigned char y) { //assert(y < 128); CurrentColumn = y; if (y < 64) { SendLCDCommand(DISPLAY_COLUMN_SET | (y&63), LCD_CS1); SendLCDCommand(DISPLAY_COLUMN_SET | 0, LCD_CS2); } else { SendLCDCommand(DISPLAY_COLUMN_SET | 63, LCD_CS1); SendLCDCommand(DISPLAY_COLUMN_SET | ((y-64)&63), LCD_CS2); } } void SendLCDData(const unsigned char values[], unsigned int amount) { unsigned char cs; int counter; for (counter=0; counter < amount;counter++) { cs = CurrentColumn>63?LCD_CS2:LCD_CS1; OmaDelay(); DlPortWritePortUshort(CONTROL, LCD_ENABLE | cs); OmaDelay(); DlPortWritePortUshort(DATAREG, values[counter]); OmaDelay(); DlPortWritePortUshort(CONTROL, cs); OmaDelay(); DlPortWritePortUshort(CONTROL, LCD_ENABLE | cs); CurrentColumn++; if (CurrentColumn > 127) return; } } void SetLCDXY(int x, int y) { SetColumn(x*6); SetPage(y); } void PrintLCDText(char *string) { unsigned char n; unsigned char value = 0x0; for (n = 0;n < strlen(string);n++) { SendLCDData(&font5x7[((*(string+n)-32) * 5)],5); SendLCDData(&value,1); } } void InitLCD() { unsigned char value; int x, a; value = 0x0; SendLCDCommand(DISPLAY_ON, LCD_CS1); SendLCDCommand(DISPLAY_ON, LCD_CS2); SetStartLine(0); for (x=0;x < 8;x++) { SetPage(x);SetColumn(0); for (a = 0 ;a < 128; a++) SendLCDData(&value, 1); }//Clear Screen SetLCDXY(0,0); } void main(void) { InitLCD(); //ClearLCD(); //PrintLCDText("PrintLCDText"); SendLCDData(&chinesename[0],14); //first half, one character is 14x14 SendLCDData(&chinesename[28],14); SendLCDData(&chinesename[56],14); SetLCDXY(0,1); SendLCDData(&chinesename[14],14); //second half, first character SendLCDData(&chinesename[42],14); SendLCDData(&chinesename[70],14); printf("3 chinese-characters"); } |
Author: | Zee [ Mon Aug 22, 2005 18:32 ] |
Post subject: | |
To write single pixels it's good to have a framebuffer the size of your screen (128/8*64) where you can check if a certain address already has pixels drawn so they don't get erased. What I currently use for plotting single pixels is: Code: void Plot(int X, int Y, int mode)
{ if ((X>-1) && (X<128) && (Y>-1) && (Y<64)) { if (mode==0) frbuf[(X>>3)+(Y<<7)] = frbuf[(X>>3)+(Y<<7)] & (255-(1<<(7-(X&7)))); if (mode==1) frbuf[(X>>3)+(Y<<7)] = frbuf[(X>>3)+(Y<<7)] | 1<<(7-(X&7)); if (mode==2) frbuf[(X>>3)+(Y<<7)] = frbuf[(X>>3)+(Y<<7)] ^ 1<<(7-(X&7)); /* Replace this with the address set/write code of your display WriteData((GAREA+(X>>3)+(Y<<7)) & 255); WriteData((GAREA+(X>>3)+(Y<<7)) >> 8 & 255); WriteCommand(PTR_SET | 0x04); WriteData(frbuf[(X>>3)+(Y<<7)]); WriteCommand(DATA_RW | 0x04); */ } } Where mode 0 clears, 1 sets and 2 inverts the pixel. |
Author: | Kneego [ Mon Aug 22, 2005 18:59 ] |
Post subject: | |
Wow I got an answer so fast!!! so glad If I understand u right, Zee, I should put some code between the IF -statements, the set/write codes? What I don't really understand is why "(X>>3)+(Y<<7)]", I think it really works but I not quite really understand it LOL I'm newbie in this forum AND newbie in C too... BTW, is "frbuf" a bool or int, is it a single array? Many questions... Now I try your code and test it THX 4 answering Kneego |
Author: | Zee [ Mon Aug 22, 2005 19:33 ] |
Post subject: | |
You replace the part between the comments "/* xxx */" with the code that works for your setup (also remove /* & */). (X>>3)+(Y<<7) is the same as (X/8+Y*128) but is a lot faster. And you can propably use "arrayLCD" in place of "frbuf" in your code. |
Author: | Kneego [ Mon Aug 22, 2005 20:20 ] |
Post subject: | |
THX 4 ur reply. Have tested the code and right now I have: Code: void Plot(int X, int Y, int mode)
{ unsigned char pixel=0x04; if ((X>-1) && (X<128) && (Y>-1) && (Y<64)) { if (mode==0) arrayLCD[(X>>3)+(Y<<7)] = arrayLCD[(X>>3)+(Y<<7)] & (255-(1<<(7-(X&7)))); if (mode==1) arrayLCD[(X>>3)+(Y<<7)] = arrayLCD[(X>>3)+(Y<<7)] | 1<<(7-(X&7)); if (mode==2) arrayLCD[(X>>3)+(Y<<7)] = arrayLCD[(X>>3)+(Y<<7)] ^ 1<<(7-(X&7)); SendLCDData(&pixel,1); } } On your code u have 0x04, I belive that is what u write 2 your LCD. On main() I recall the function Plot(100,40,1); but the output on the LCD is one dot on left-upper-corner with the value 0x04. Shouldn't I also use the functions "SetPage" and SetColumn" to set the position for the pixel first? And yes I used arrayLCD |
Author: | Kneego [ Mon Aug 22, 2005 20:25 ] |
Post subject: | |
The outputed position on my LCD is x=0 y=1 where origo is the upper-left-corner (0,1) is exactlly 0x04 Kneego |
Author: | Zee [ Mon Aug 22, 2005 21:26 ] |
Post subject: | |
Yes you should set the position first according to X and Y and then write the byte from arrayLCD from the same position to the display. |
Author: | Michael [ Mon Aug 22, 2005 21:49 ] |
Post subject: | |
Kneego, I was wondering if I could have your chinese character headers (.h) and information? As I would like to implement some form of useful Chinese character selection in my own software, other than using a bitmap. Thankx |
Author: | Kneego [ Tue Aug 23, 2005 10:24 ] |
Post subject: | |
There's some problem with the code... To set position I need to use the functions "SetPage"=X and "Setcolumn"=Y. Now if i set the position (0,0) and use your function "Plot" to plot one pixel at the position (0,0), the result will be (0,1) on the LCD. Why? Because the function writes 0x04 which is only a dot second from top. The write value should then be 0x01 instead of 0x04. Conclusion: With this way I can not have a real "Plot"-function because of the write value, think if I want position (100,40) and the write value is 0x04 the result on LCD is the dot has shifted some pixels up. So PLEASE can someone post a REAL or better "plot"-function and help me? And the header: Code: unsigned char chinesename[] = { 0xFF, 0x01, 0x19, 0xEE, 0x02, 0xFA, 0xAA, 0xAA, 0xFF, 0xAA, 0xAA, 0xFA, 0x02, 0x00, 0x5F, 0x02, 0x42, 0x01, 0x48, 0x04, 0x42, 0x01, 0x5F, 0x01, 0x42, 0x04, 0x48, 0x00, 0x08, 0x11, 0x82, 0x04, 0xFC, 0x84, 0x00, 0xFE, 0xAA, 0xAB, 0xAA, 0XBE, 0xA0, 0x00, 0X58, 0x06, 0x41, 0X01, 0x41, 0x08, 0x46, 0x00, 0x46, 0x00, 0x56, 0x10, 0x4F, 0x00, 0x80, 0x82, 0x82, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0x82, 0x82, 0x80, 0x00, 0x44, 0x14, 0x52, 0x11, 0x54, 0x14, 0x5E, 0x14, 0x54, 0x11, 0x52, 0x14, 0X44, 0x00 }; Happy that some1 is intressted in chinese U should have a look at this :http://www.sitronix.com.tw/sitronix/product.nsf/Doc/ST7920?OpenDocument It is a LCD controller with a built in chinese font contains, I dunno, thousands of chinese characters The header only contains 3 chinese characters namely my chinese name First I wrote my name in mspaint and read the pixelvalues and put that in the header. YES it took time but I learned alot (I could draw the bitmap instead). To write a character u need 2 lines of text. So one character is almost 14x14 but you only can write 8x14 at the same time, 8 pixels in height and 14 pixels in width. Then jump to next line and write the other half of the character. So in main(): Code: SendLCDData(&chinesename[0],14);//first half SetLCDXY(0,1);//next line SendLCDData(&chinesename[14],14);//second half To write the second character you do this: Code: SendLCDData(&chinesename[0],14);//first character, first half
SendLCDData(&chinesename[28],14);//second character, first half SetLCDXY(0,1);//next line SendLCDData(&chinesename[14],14);//first character, second half SendLCDData(&chinesename[42],14);//second character, second half Hope it helps and u understand the idea, the easiest way 2 write your own chinese characters is 2 have characters in bitmap. If u know how to make a winamp skin using bitmap-font u will understand the idea. Kneego I still want a pixel-plot-function plz help |
Author: | Zee [ Tue Aug 23, 2005 10:32 ] |
Post subject: | |
Without knowing how the KS controller works I'm only guessing here... Code: void Plot(int X, int Y, int mode)
{ unsigned char pixel=0x04; if ((X>-1) && (X<128) && (Y>-1) && (Y<64)) { if (mode==0) arrayLCD[(X>>3)+(Y<<7)] = arrayLCD[(X>>3)+(Y<<7)] & (255-(1<<(7-(X&7)))); if (mode==1) arrayLCD[(X>>3)+(Y<<7)] = arrayLCD[(X>>3)+(Y<<7)] | 1<<(7-(X&7)); if (mode==2) arrayLCD[(X>>3)+(Y<<7)] = arrayLCD[(X>>3)+(Y<<7)] ^ 1<<(7-(X&7)); SetColumn(X); SetStartLine(Y); SendLCDData(arrayLCD[(X>>3+(Y<<7)]); } } |
Author: | Kneego [ Tue Aug 23, 2005 10:51 ] |
Post subject: | |
It works better now but a little bug, I take a look. But I understand now the idea with your code. Thank you 4 your help and patience. There's some bug with SetStartLine-function. The Plot function works fine if u write one single time, the second time u use it, the pixels will have some offsets. I take a harder look, THX 4 the help Kneego |
Author: | Kneego [ Tue Aug 23, 2005 11:37 ] |
Post subject: | SetPage |
Can any1 plz explain how the SetPage (X-address) works? And why can it only have values 0~7 ? then X on display is maximum 128/2... |
Author: | Michael [ Tue Aug 23, 2005 11:48 ] |
Post subject: | |
Have a look at this thread: http://forum.lcdinfo.com/viewtopic.php?t=1237 I can email you the source if you like, which includes a stand alone ks0108 driver. It might be helpful to you as I use bitmap fonts and not hardcoded arrays. Michael |
Author: | Michael [ Tue Aug 23, 2005 11:51 ] |
Post subject: | |
Zee wrote: Without knowing how the KS controller works I'm only guessing here...
a cut+paste the KS0108 controller contains 512bytes of ram. ram is organised in vertical blocks (pages). 1 page spans 64 bytes or columns, each byte addresses 8 pixels ie, one byte per 8 vertical pixels. this means a minimum of 8 pixels must be addressed at any instant. to address a pixel set the page (8 pages in a 128x'64' display), page = y%8, or page=y&7 then set the start address within this page, column = x (0-63) put the byte on to the address register. enable the chip select (CS1 or CS2) and lcd enable (E) as the internal address counter is incremented by one, writing another byte will address the next group of 8 pixels, and so on. |
Author: | Zee [ Tue Aug 23, 2005 12:03 ] |
Post subject: | |
Ok, seems to be something freakish like the PCD8544. |
Page 1 of 3 | All times are UTC + 2 hours |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |