LCDInfo.com

http://www.lcdinfo.com
It is currently Fri Mar 29, 2024 11:12

All times are UTC + 2 hours




Post new topic Reply to topic  [ 35 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: C programmin 4 fun
PostPosted: Mon Aug 22, 2005 15:52 
Offline

Joined: Mon Aug 22, 2005 15:09
Posts: 15
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 :wink:

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");
}


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2005 18:32 
Offline

Joined: Wed Aug 03, 2005 20:27
Posts: 130
Location: .fi
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.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2005 18:59 
Offline

Joined: Mon Aug 22, 2005 15:09
Posts: 15
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


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2005 19:33 
Offline

Joined: Wed Aug 03, 2005 20:27
Posts: 130
Location: .fi
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.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2005 20:20 
Offline

Joined: Mon Aug 22, 2005 15:09
Posts: 15
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 :wink:


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2005 20:25 
Offline

Joined: Mon Aug 22, 2005 15:09
Posts: 15
The outputed position on my LCD is x=0 y=1 where origo is the upper-left-corner
(0,1) is exactlly 0x04 :wink:
Kneego


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2005 21:26 
Offline

Joined: Wed Aug 03, 2005 20:27
Posts: 130
Location: .fi
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.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 22, 2005 21:49 
Offline

Joined: Mon Jun 20, 2005 23:03
Posts: 161
Location: Hong Kong
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


Last edited by Michael on Thu Aug 25, 2005 6:16, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2005 10:24 
Offline

Joined: Mon Aug 22, 2005 15:09
Posts: 15
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 :wink:
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 :)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2005 10:32 
Offline

Joined: Wed Aug 03, 2005 20:27
Posts: 130
Location: .fi
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)]);
   }
}


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2005 10:51 
Offline

Joined: Mon Aug 22, 2005 15:09
Posts: 15
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


Top
 Profile  
 
 Post subject: SetPage
PostPosted: Tue Aug 23, 2005 11:37 
Offline

Joined: Mon Aug 22, 2005 15:09
Posts: 15
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...
:?:


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2005 11:48 
Offline

Joined: Mon Jun 20, 2005 23:03
Posts: 161
Location: Hong Kong
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


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2005 11:51 
Offline

Joined: Mon Jun 20, 2005 23:03
Posts: 161
Location: Hong Kong
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.


Last edited by Michael on Tue Aug 23, 2005 12:15, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 23, 2005 12:03 
Offline

Joined: Wed Aug 03, 2005 20:27
Posts: 130
Location: .fi
Ok, seems to be something freakish like the PCD8544.


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

All times are UTC + 2 hours


Who is online

Users browsing this forum: No registered users and 26 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:  
cron
Powered by phpBB® Forum Software © phpBB Group