LCDInfo.com

http://www.lcdinfo.com
It is currently Thu Mar 28, 2024 11:59

All times are UTC + 2 hours




Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: Sat Aug 16, 2008 18:25 
Offline

Joined: Sat Aug 16, 2008 8:50
Posts: 6
Hey everybody,

New to this forum. I've encountered a very strange problem while trying to interface to a Nokia 3310 LCD using my parallel port. Everything seems to be working, except instead of 6 rows of 8 pixels high, I'm getting 5 rows of 8 pixels high and two messed-up rows of 5 pixels and 3 pixels high at the top and bottom of the display.

Image

I have done the following checks:
- I'm running the LCD with 3.3V
- I've studied all the signals using a logic analyzer and confirmed that they are according to the specs on the datasheet
- I've tried two additional display units with identical results

I really appreciate any help I can get.

Zinahe A


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 18, 2008 11:18 
Offline

Joined: Mon Jun 20, 2005 23:03
Posts: 161
Location: Hong Kong
What are you using to drive the display? Given that you're experiencing similar symptoms on other displays I'd say this is software related.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 18, 2008 11:47 
Offline

Joined: Sat Aug 16, 2008 8:50
Posts: 6
Michael:

I wrote my own program in C# to drive the circuit; which I am very much willing to share it with you all guys.

The program allows easy configuration of the parallel port pins to any of the inputs on the LCD display.

I really appreciate if there is anyone willing to test my code on their hardware.

Zinahe A.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 18, 2008 13:17 
Offline

Joined: Mon Jun 20, 2005 23:03
Posts: 161
Location: Hong Kong
Zinahe wrote:
Michael:

I wrote my own program in C# to drive the circuit; which I am very much willing to share it with you all guys.

The program allows easy configuration of the parallel port pins to any of the inputs on the LCD display.

I really appreciate if there is anyone willing to test my code on their hardware.

Zinahe A.


I'm sure it will do no harm posting what you've got but it may be easier for you to first try LCDInfo.


Top
 Profile  
 
 Post subject: C# code to drive the LCD
PostPosted: Mon Aug 18, 2008 19:06 
Offline

Joined: Sat Aug 16, 2008 8:50
Posts: 6
As promised, here is the c# code that I'm using to drive the LCD *** here ***. Unfortunately the LCDInfo Forum doesn't allow uploading of attachments; so I had to find other means.

Lines 42-47 are used to map the parallel port data register bits to the LCD input terminals. So for those of you who would like to try this code, kindly make sure to map it to your configuration.

Code:
    // Mapping of parallel port data register bits to LCD inputs
    private static Pin sclk  = new Pin(0x01);      // sclk => 00000001
    private static Pin sdin  = new Pin(0x02);      // sdin => 00000010
    private static Pin dc    = new Pin(0x04);      // d/c  => 00000100
    private static Pin power = new Pin(0x08);      // vdd  => 00001000
    private static Pin reset = new Pin(0x10);      // res  => 00010000


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 19, 2008 13:00 
Offline

Joined: Mon Jun 20, 2005 23:03
Posts: 161
Location: Hong Kong
That forum requires registration before attachments can be viewed.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 21, 2008 9:54 
Offline

Joined: Sun May 05, 2002 22:05
Posts: 2063
Location: Lappeenranta, Finland
Setting the display start address register wrong might cause something like that. (if the PCD8544 had that kind register, don't really remember ;))


Top
 Profile  
 
PostPosted: Thu Aug 21, 2008 13:41 
Offline

Joined: Sat Aug 16, 2008 8:50
Posts: 6
According to the datasheet, the PCD8544 allows column and row based addressing; row addresses range from 0 to 5 corresponding to the 6 byte-sized columns and column addresses range from 0-83 corresponding to the 84 columns.

Here is the full c# code for those of you who couldn't access the attachment on the link. Don't forget to download and put the InpOut32.dll in the same folder with the code.

Code:
using System;
using System.Threading;
using System.Runtime.InteropServices;

enum Mode
{
    Data,
    Command
}

class Pin
{
    private int _mask;
   
    public int Mask
    {
       get { return _mask; }
       set { _mask = value; }
    }
   
    public Pin(int mask)
    {
       _mask = mask;
    }
}

class LCD
{
    [DllImport("inpout32.dll")]
    public static extern void Out32(int address, int data);
   
   
    private static int port_address = 0x378;      
    private static int port_data = 0x00;
    private static int reset_delay = 5;
    private static int data_delay = 0;
    private static int MSB = 0x80;         // Most Significant Bit (left-most bit) mask
    private static bool invert = false;         // Inverts parallel port output (useful) if using an inverter HCMOS logic to
                         // translate TTL (5v output) to 3.3V
   
   
    // Mapping of parallel port data register bits to LCD inputs
    private static Pin sclk  = new Pin(0x01);      // sclk => 00000001
    private static Pin sdin  = new Pin(0x02);      // sdin => 00000010
    private static Pin dc    = new Pin(0x04);      // d/c  => 00000100
    private static Pin power = new Pin(0x08);      // vdd  => 00001000
    private static Pin reset = new Pin(0x10);       // res  => 00010000
   
    // Encapsulate Out32 function to implement port-wide invert
    public static void Out(int data)
    {
       if (invert)
            Out32(port_address, ~data);
       else
          Out32(port_address, data);
    }
   
    public static void Main()
    {
       {
           Power();
                                   
            Thread.Sleep(reset_delay);

            Reset();
                         
           Init();
                     
           Clear();
          
           GoToXY(15, 1);
          
           WriteString("It works !!");
         
           for (int i = 0; i < 6; i++)
           {
              GoToXY(0, i);
      WriteString(i.ToString());
           }
        }
    }
   
       
    public static void Reset()
    {
       port_data &= ~reset.Mask;         // RES = 0
       Out(port_data);
       
       Thread.Sleep(reset_delay);
       
       port_data |= reset.Mask;         // RES = 1
       Out(port_data);
    }

    public static void Power()
    {
      port_data |= reset.Mask;         // RES = 1
       port_data |= power.Mask;         // VDD = 1
       Out(port_data);
    }
   
    public static void Init()
    {
       Write(0x21, Mode.Command);      // Function Set (Extended) : Horizonta Addressing
       //Write(0x23, Mode.Command);      // Function Set (Extended) : Vertical Addressing
       Write(0x13, Mode.Command);      // Bias System   (BS2=0, BS1=1, BS0=1)
       Write(0xD0, Mode.Command);      // Vop (Operating Voltage) = 8.5v
                 
       Write(0x20, Mode.Command);      // Function Set (Basic)
       Write(0x0C, Mode.Command);      // Display Control (Normal)
       //Write(0x0D, Mode.Command);      // Display Control (Inverse)
    }
   
    public static void Write(int data, Mode mode)
    {
   for (int i = 0; i < 8; i++)
   {
       if (mode == Mode.Data)
          port_data |= dc.Mask;         // D/C = 1
       else
          port_data &= ~dc.Mask;         // D/C = 0

       port_data &= (~sdin.Mask & ~sclk.Mask);   // SCLK = 0, SDIN = 0
       port_data |= ((data & MSB) >> 6);      // SDIN = Bit(data, 7-i) : MSB first
      
       Out(port_data);
       Thread.Sleep(data_delay);

       port_data |= sclk.Mask;         // SCLK = 1 (latch data)

       Out(port_data);
       Thread.Sleep(data_delay);

       data = (data << 1);            // shift data right by 1 bit
   }
    }
   
    public static void Clear()
    {
       int buffer = data_delay;
       
       // Clear delay
       data_delay = 0;
       
       for (int y = 0; y < 6; y++)
           for (int x = 0; x < 84; x++)
               Write(0x00, Mode.Data);
       
       // Restore delay
       data_delay = buffer;
    }
   
    public static void GoToXY(int x, int y)
    {
       Write(0x40 | y, Mode.Command);       // Set y
       Write(0x80 | x, Mode.Command);       // Set x
    }
   
    public static void WriteString(string s)
    {
       int index;
       
        foreach (char _ch in s)
        {
            index = (int)_ch;
            for (int i = 0; i < 5; i++)
                Write(charmap[index - 32][i], Mode.Data);
        }
    }
   
    private static int[][] charmap = new int[][]
    {
        new int[] { 0x00, 0x00, 0x00, 0x00, 0x00 },   // sp
        new int[] { 0x00, 0x00, 0x2f, 0x00, 0x00 },   // !
        new int[] { 0x00, 0x07, 0x00, 0x07, 0x00 },   // "
        new int[] { 0x14, 0x7f, 0x14, 0x7f, 0x14 },   // #
        new int[] { 0x24, 0x2a, 0x7f, 0x2a, 0x12 },   // $
        new int[] { 0x32, 0x34, 0x08, 0x16, 0x26 },   // %
        new int[] { 0x36, 0x49, 0x55, 0x22, 0x50 },   // &
        new int[] { 0x00, 0x05, 0x03, 0x00, 0x00 },   // '
        new int[] { 0x00, 0x1c, 0x22, 0x41, 0x00 },   // (
        new int[] { 0x00, 0x41, 0x22, 0x1c, 0x00 },   // )
        new int[] { 0x14, 0x08, 0x3E, 0x08, 0x14 },   // *
        new int[] { 0x08, 0x08, 0x3E, 0x08, 0x08 },   // +
        new int[] { 0x00, 0x00, 0x50, 0x30, 0x00 },   // ,
        new int[] { 0x10, 0x10, 0x10, 0x10, 0x10 },   // -
        new int[] { 0x00, 0x60, 0x60, 0x00, 0x00 },   // .
        new int[] { 0x20, 0x10, 0x08, 0x04, 0x02 },   // /
        new int[] { 0x3E, 0x51, 0x49, 0x45, 0x3E },   // 0
        new int[] { 0x00, 0x42, 0x7F, 0x40, 0x00 },   // 1
        new int[] { 0x42, 0x61, 0x51, 0x49, 0x46 },   // 2
        new int[] { 0x21, 0x41, 0x45, 0x4B, 0x31 },   // 3
        new int[] { 0x18, 0x14, 0x12, 0x7F, 0x10 },   // 4
        new int[] { 0x27, 0x45, 0x45, 0x45, 0x39 },   // 5
        new int[] { 0x3C, 0x4A, 0x49, 0x49, 0x30 },   // 6
        new int[] { 0x01, 0x71, 0x09, 0x05, 0x03 },   // 7
        new int[] { 0x36, 0x49, 0x49, 0x49, 0x36 },   // 8
        new int[] { 0x06, 0x49, 0x49, 0x29, 0x1E },   // 9
        new int[] { 0x00, 0x36, 0x36, 0x00, 0x00 },   // :
        new int[] { 0x00, 0x56, 0x36, 0x00, 0x00 },   // ;
        new int[] { 0x08, 0x14, 0x22, 0x41, 0x00 },   // <
        new int[] { 0x14, 0x14, 0x14, 0x14, 0x14 },   // =
        new int[] { 0x00, 0x41, 0x22, 0x14, 0x08 },   // >
        new int[] { 0x02, 0x01, 0x51, 0x09, 0x06 },   // ?
        new int[] { 0x32, 0x49, 0x59, 0x51, 0x3E },   // @
        new int[] { 0x7E, 0x11, 0x11, 0x11, 0x7E },   // A
        new int[] { 0x7F, 0x49, 0x49, 0x49, 0x36 },   // B
        new int[] { 0x3E, 0x41, 0x41, 0x41, 0x22 },   // C
        new int[] { 0x7F, 0x41, 0x41, 0x22, 0x1C },   // D
        new int[] { 0x7F, 0x49, 0x49, 0x49, 0x41 },   // E
        new int[] { 0x7F, 0x09, 0x09, 0x09, 0x01 },   // F
        new int[] { 0x3E, 0x41, 0x49, 0x49, 0x7A },   // G
        new int[] { 0x7F, 0x08, 0x08, 0x08, 0x7F },   // H
        new int[] { 0x00, 0x41, 0x7F, 0x41, 0x00 },   // I
        new int[] { 0x20, 0x40, 0x41, 0x3F, 0x01 },   // J
        new int[] { 0x7F, 0x08, 0x14, 0x22, 0x41 },   // K
        new int[] { 0x7F, 0x40, 0x40, 0x40, 0x40 },   // L
        new int[] { 0x7F, 0x02, 0x0C, 0x02, 0x7F },   // M
        new int[] { 0x7F, 0x04, 0x08, 0x10, 0x7F },   // N
        new int[] { 0x3E, 0x41, 0x41, 0x41, 0x3E },   // O
        new int[] { 0x7F, 0x09, 0x09, 0x09, 0x06 },   // P
        new int[] { 0x3E, 0x41, 0x51, 0x21, 0x5E },   // Q
        new int[] { 0x7F, 0x09, 0x19, 0x29, 0x46 },   // R
        new int[] { 0x46, 0x49, 0x49, 0x49, 0x31 },   // S
        new int[] { 0x01, 0x01, 0x7F, 0x01, 0x01 },   // T
        new int[] { 0x3F, 0x40, 0x40, 0x40, 0x3F },   // U
        new int[] { 0x1F, 0x20, 0x40, 0x20, 0x1F },   // V
        new int[] { 0x3F, 0x40, 0x38, 0x40, 0x3F },   // W
        new int[] { 0x63, 0x14, 0x08, 0x14, 0x63 },   // X
        new int[] { 0x07, 0x08, 0x70, 0x08, 0x07 },   // Y
        new int[] { 0x61, 0x51, 0x49, 0x45, 0x43 },   // Z
        new int[] { 0x00, 0x7F, 0x41, 0x41, 0x00 },   // [
        new int[] { 0x55, 0x2A, 0x55, 0x2A, 0x55 },   // 55
        new int[] { 0x00, 0x41, 0x41, 0x7F, 0x00 },   // ]
        new int[] { 0x04, 0x02, 0x01, 0x02, 0x04 },   // ^
        new int[] { 0x40, 0x40, 0x40, 0x40, 0x40 },   // _
        new int[] { 0x00, 0x01, 0x02, 0x04, 0x00 },   // '
        new int[] { 0x20, 0x54, 0x54, 0x54, 0x78 },   // a
        new int[] { 0x7F, 0x48, 0x44, 0x44, 0x38 },   // b
        new int[] { 0x38, 0x44, 0x44, 0x44, 0x20 },   // c
        new int[] { 0x38, 0x44, 0x44, 0x48, 0x7F },   // d
        new int[] { 0x38, 0x54, 0x54, 0x54, 0x18 },   // e 
        new int[] { 0x08, 0x7E, 0x09, 0x01, 0x02 },   // f
        new int[] { 0x0C, 0x52, 0x52, 0x52, 0x3E },   // g
        new int[] { 0x7F, 0x08, 0x04, 0x04, 0x78 },   // h
        new int[] { 0x00, 0x44, 0x7D, 0x40, 0x00 },   // i
        new int[] { 0x20, 0x40, 0x44, 0x3D, 0x00 },   // j
        new int[] { 0x7F, 0x10, 0x28, 0x44, 0x00 },   // k
        new int[] { 0x00, 0x41, 0x7F, 0x40, 0x00 },   // l
        new int[] { 0x7C, 0x04, 0x18, 0x04, 0x78 },   // m
        new int[] { 0x7C, 0x08, 0x04, 0x04, 0x78 },   // n
        new int[] { 0x38, 0x44, 0x44, 0x44, 0x38 },   // o
        new int[] { 0x7C, 0x14, 0x14, 0x14, 0x08 },   // p
        new int[] { 0x08, 0x14, 0x14, 0x18, 0x7C },   // q
        new int[] { 0x7C, 0x08, 0x04, 0x04, 0x08 },   // r
        new int[] { 0x48, 0x54, 0x54, 0x54, 0x20 },   // s
        new int[] { 0x04, 0x3F, 0x44, 0x40, 0x20 },   // t
        new int[] { 0x3C, 0x40, 0x40, 0x20, 0x7C },   // u
        new int[] { 0x1C, 0x20, 0x40, 0x20, 0x1C },   // v
        new int[] { 0x3C, 0x40, 0x30, 0x40, 0x3C },   // w
        new int[] { 0x44, 0x28, 0x10, 0x28, 0x44 },   // x
        new int[] { 0x0C, 0x50, 0x50, 0x50, 0x3C },   // y
        new int[] { 0x44, 0x64, 0x54, 0x4C, 0x44 },   // z
        new int[] { 0x00, 0x7F, 0x3E, 0x1C, 0x08 },   // > Filled
        new int[] { 0x08, 0x1C, 0x3E, 0x7F, 0x00 },      // < Filled
        new int[] { 0x08, 0x7C, 0x7E, 0x7C, 0x08 },   // Arrow up
        new int[] { 0x10, 0x3E, 0x7E, 0x3E, 0x10 },   // Arrow down   
        new int[] { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E },   // Stop
        new int[] { 0x00, 0x7F, 0x3E, 0x1C, 0x08 }    // Play
    };

}
[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 21, 2008 13:51 
Offline

Joined: Sun May 05, 2002 22:05
Posts: 2063
Location: Lappeenranta, Finland
Henri wrote:
Setting the display start address register wrong might cause something like that. (if the PCD8544 had that kind register, don't really remember ;))


Ok, I just got the PCD8544 datasheet in front of me and looks like it doesn't have a register like that.

I was thinking about a register that is called "Display start line" in this datasheet for example:
http://pdfdata.datasheetsite.com/pdf1/S ... B0108A.pdf


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 21, 2008 21:35 
Offline

Joined: Sat Aug 16, 2008 8:50
Posts: 6
Has anyone done interfacing of the Nokia 3310 LCD with a parallel port ?? I really appreciate if someone can help me figure out where the problem is. I'm not even sure if it's in the hardware or software.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 22, 2008 9:14 
Offline

Joined: Sun May 05, 2002 22:05
Posts: 2063
Location: Lappeenranta, Finland
I have done that but it was quite a while ago. Maybe you could compare your code to the LCDInfo PCD8544 driver:
http://www.skippari.net/lcd/alpha/sourc ... source.rar


Top
 Profile  
 
 Post subject: Testing with LCDInfo
PostPosted: Fri Aug 22, 2008 21:42 
Offline

Joined: Sat Aug 16, 2008 8:50
Posts: 6
Hey guys,

I've tried the display with LCDInfo and here is the output. Well LCDInfo works ! ! ! But, as you can see from the photo the whole thing is shifted upwards by 3 pixels leaving behind an unusable area at the bottom. I'm using a very simplified connection with the parallel port:

- Driving the display with an external power source.
- SCE pin is permanently tied to ground

Basically I'm doing away with two pins from LCDInfo's side. The only additional component I'm using is a 4.7uF cap at VOUT to ground. And as in the previous cases the result is the same when tested with two additional display units

Image[/b]


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC + 2 hours


Who is online

Users browsing this forum: No registered users and 30 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