This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

P89V664 Serial Graphical LCD Problem

Hello

I have confused in the coding of the Serial Graphical LCD on NXP P89V664.

Can any one help ????

the code is

#include<reg52.H>
#include<stdio.h>
#include<intrins.h>

// #define unsigned char unsigned char // 0~255
// #define unsigned int unsigned int   // 0~65535

sbit _CS = P2^3;
sbit _RST = P2^2;
sbit A0 = P2^1;
sbit SCK = P4^0;
sbit DIN = P4^2;

unsigned char ContrastLevel;     // for contrast setting level

//-----------------------------------
// dispaly data (128x64)
//-----------------------------------

unsigned char code Logo[]={

....0x15,0x06,0x00,0x00,0x10,0x1F,0x10,0x00,0x00,0x12,0x15,0x15,0x15,0x88,0xC0
};

//-----------------------------------
// Delay Routine
//-----------------------------------

void delayms(unsigned int m)        // 12MHz Xtal, close to ms value
{
    unsigned int j;
    unsigned int i;

    for(i=0; i<m; i++)
        for(j=0; j<109; j++)
            _nop_();
}

//-----------------------------------
// IO Routine
//-----------------------------------

void lcd_cmd(unsigned char Command)       //send command
{
    SCK = 1;
    A0  = 0;
    _CS = 0;
    DIN = Command & 0x80; SCK= 0; SCK= 1;
    DIN = Command & 0x40; SCK= 0; SCK= 1;
    DIN = Command & 0x20; SCK= 0; SCK= 1;
    DIN = Command & 0x10; SCK= 0; SCK= 1;
    DIN = Command & 0x08; SCK= 0; SCK= 1;
    DIN = Command & 0x04; SCK= 0; SCK= 1;
    DIN = Command & 0x02; SCK= 0; SCK= 1;
    DIN = Command & 0x01; SCK= 0; SCK= 1;
    _CS = 1;
}

void lcd_data(unsigned char DData)        //send data
{
    SCK= 1;
    A0  = 1;
    _CS = 0;
    DIN = DData & 0x80; SCK= 0; SCK= 1;
    DIN = DData & 0x40; SCK= 0; SCK= 1;
    DIN = DData & 0x20; SCK= 0; SCK= 1;
    DIN = DData & 0x10; SCK= 0; SCK= 1;
    DIN = DData & 0x08; SCK= 0; SCK= 1;
    DIN = DData & 0x04; SCK= 0; SCK= 1;
    DIN = DData & 0x02; SCK= 0; SCK= 1;
    DIN = DData & 0x01; SCK= 0; SCK= 1;
    _CS = 1;
}

//-----------------------------------
// Write a Screen
//-----------------------------------
void WriteScreen(unsigned char *DisplayData)    // DisplayData should be 164x64/8 = 1312byte
{
    unsigned char TempData;
    unsigned char i, j;
    for(i=0;i<8;i++)
        {
        lcd_cmd(0xb0 | i);    // select page 0~7
        lcd_cmd(0x10);        // start form column 4
        lcd_cmd(0x00);        // (2byte command)
        for(j=0;j<128;j++)
                {
            TempData=(*(DisplayData+(i*128)+j));
            lcd_data(TempData);
            }
        }
}

//-----------------------------------
// Contrast control
//-----------------------------------
void LCD_Darker(void)
{
    if (ContrastLevel<0x3F)
        {
        ContrastLevel++;
        }
    lcd_cmd(0x81);            // E-Vol setting
    lcd_cmd(ContrastLevel);   // (2byte command)
}



void LCD_Lighter(void)
{
    if (ContrastLevel>0x00)
        {
         ContrastLevel--;
        }
    lcd_cmd(0x81);            // E-Vol setting
    lcd_cmd(ContrastLevel);   // (2byte command)
}


//-----------------------------------
// Init LCD module
//-----------------------------------
void initLCDM(void)
{
    _RST=1;                 // hardware reset LCD module
    _RST=0;
    delayms(1);
    _RST=1;
    delayms(800);

    ContrastLevel=0x17;     // default Contrast Level  1a
    lcd_cmd(0xab);                      //new
    lcd_cmd(0xaf);            // display on
    lcd_cmd(0x40);            // display start line=0
    lcd_cmd(0xc8);            // Common output mode select= reverse
    lcd_cmd(0xa6);            // normal display
    lcd_cmd(0xa4);            // Duisplay all point = off
    lcd_cmd(0xa3);            // LCD bias = 1/9   a2
    lcd_cmd(0x2f);            // Power control = all on
    lcd_cmd(0x25);            // Rab Ratio     26
    lcd_cmd(0x81);            // E-Vol setting
    lcd_cmd(ContrastLevel);   // (2byte command)
}

//-----------------------------------
// Main Program
//-----------------------------------
void main()
{
    SP=0x60;
    EA = 0;         // disable interrupts

    _CS    =1;
    _RST   =1;
    A0     =1;
    SCK   =1;
    DIN    =1;

    initLCDM();
    WriteScreen(Logo);
    while(1)
    {
    }
}
//end of program


The error it shoes that P4 is an undefined identifier. error C202

Parents
  • You may try this as it is formed using code from original post with added macros.
    [Compiled with uVision3 v3.72] [C51 v8.17] [Code Optimization Level 8]
    There might be a timing issue with the sequence SCK_clear; SCK_set; and one or more _nop(); must be added.
    Hints:
    The delayms function is based on software loops. This is not a good solution for accurate timing. At some optimization level this will be eliminated. A timer must be used for delay purposes at millisecond level, or a well written ASM module for accurate timing.
    The lcd_cmd and lcd_data is better to be rewritten using loops.

    #include <Philips\P89V66x.h>
    //#include <reg52.H>
    #include <stdio.h>
    #include <intrins.h>
    
    #define SCK_bit 0
    #define DIN_bit 2
    #define SCK_set   P4 |= (1<<SCK_bit)
    #define DIN_set   P4 |= (1<<DIN_bit)
    #define SCK_clear P4 &= ~(1<<SCK_bit)
    #define DIN_clear P4 &= ~(1<<DIN_bit)
    
    sbit _CS = P2^3;
    sbit _RST = P2^2;
    sbit A0 = P2^1;
    
    /* These are not working because P4 is located at 0xA1, not bit addressable with sbit extension
     * sbit SCK = P4^0;
     * sbit DIN = P4^2;
     */
    unsigned char ContrastLevel;     // for contrast setting level
    
    //-----------------------------------
    // display data (128x64)
    //-----------------------------------
    
    unsigned char code Logo[]={
        // DisplayData should be 164x64/8 = 1312byte
        //....
        0x15,0x06,0x00,0x00,0x10,0x1F,0x10,0x00,0x00,0x12,0x15,0x15,0x15,0x88,0xC0
    };
    
    //-----------------------------------
    // Delay Routine
    //-----------------------------------
    
    void delayms(unsigned int m)                                    // 12MHz Xtal, close to ms value
    {
        unsigned int j;
        unsigned int i;
    
        for(i=0; i<m; i++)
            for(j=0; j<109; j++)
                _nop_();
    }
    
    //-----------------------------------
    // IO Routine
    //-----------------------------------
    
    void lcd_cmd(unsigned char Command)                             // Send command
    {
        SCK_set;
        A0 = 0;
        _CS = 0;
            if (Command & 0x80) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x40) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x20) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x10) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x08) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x04) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x02) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x01) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        _CS = 1;
    }
    
    void lcd_data(unsigned char DData)                              // Send data
    {
        SCK_set;
        A0 = 1;
        _CS = 0;
        if (DData & 0x80) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x40) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x20) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x10) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x08) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x04) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x02) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x01) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        _CS = 1;
    }
    
    //-----------------------------------
    // Write a Screen
    //-----------------------------------
    void WriteScreen(unsigned char *DisplayData)                    // DisplayData should be 164x64/8 = 1312byte
    {
        unsigned char TempData;
        unsigned char i, j;
        for(i = 0; i < 8; i++) {
            lcd_cmd(0xb0 | i);    // select page 0~7
            lcd_cmd(0x10);        // start form column 4
            lcd_cmd(0x00);        // (2byte command)
            for(j=0;j<128;j++) {
                TempData=(*(DisplayData+(i*128)+j));
                lcd_data(TempData);
            }
        }
    }
    
    //-----------------------------------
    // Contrast control
    //-----------------------------------
    
    void LCD_Darker(void)
    {
        if (ContrastLevel < 0x3F) {
            ContrastLevel++;
        }
        lcd_cmd(0x81);            // E-Vol setting
        lcd_cmd(ContrastLevel);   // (2byte command)
    }
    
    void LCD_Lighter(void)
    {
        if (ContrastLevel>0x00) {
            ContrastLevel--;
        }
        lcd_cmd(0x81);            // E-Vol setting
        lcd_cmd(ContrastLevel);   // (2byte command)
    }
    
    
    //-----------------------------------
    // Init LCD module
    //-----------------------------------
    void initLCDM(void)
    {
        _RST = 1;                   // hardware reset LCD module
        _RST = 0;
        delayms(1);
        _RST = 1;
        delayms(800);
    
        ContrastLevel = 0x17;       // default Contrast Level  1a
        lcd_cmd(0xab);              // new
        lcd_cmd(0xaf);              // display on
        lcd_cmd(0x40);              // display start line=0
        lcd_cmd(0xc8);              // Common output mode select= reverse
        lcd_cmd(0xa6);              // normal display
        lcd_cmd(0xa4);              // Duisplay all point = off
        lcd_cmd(0xa3);              // LCD bias = 1/9   a2
        lcd_cmd(0x2f);              // Power control = all on
        lcd_cmd(0x25);              // Rab Ratio     26
        lcd_cmd(0x81);              // E-Vol setting
        lcd_cmd(ContrastLevel);     // (2byte command)
    }
    
    //-----------------------------------
    // Main Program
    //-----------------------------------
    void main()
    {
        /* In C never try to manipulate Stack Pointer, it is too dangerous !!!
         * SP = 0x60;
         */
    
         EA = 0;         // disable interrupts
        _CS = 1;
        _RST = 1;
        A0 = 1;
        SCK_set;
        DIN_set;
    
        initLCDM();
            LCD_Darker();
            LCD_Lighter();
        WriteScreen(Logo);
        while(1)
            ;
    }
    //end of program
    

Reply
  • You may try this as it is formed using code from original post with added macros.
    [Compiled with uVision3 v3.72] [C51 v8.17] [Code Optimization Level 8]
    There might be a timing issue with the sequence SCK_clear; SCK_set; and one or more _nop(); must be added.
    Hints:
    The delayms function is based on software loops. This is not a good solution for accurate timing. At some optimization level this will be eliminated. A timer must be used for delay purposes at millisecond level, or a well written ASM module for accurate timing.
    The lcd_cmd and lcd_data is better to be rewritten using loops.

    #include <Philips\P89V66x.h>
    //#include <reg52.H>
    #include <stdio.h>
    #include <intrins.h>
    
    #define SCK_bit 0
    #define DIN_bit 2
    #define SCK_set   P4 |= (1<<SCK_bit)
    #define DIN_set   P4 |= (1<<DIN_bit)
    #define SCK_clear P4 &= ~(1<<SCK_bit)
    #define DIN_clear P4 &= ~(1<<DIN_bit)
    
    sbit _CS = P2^3;
    sbit _RST = P2^2;
    sbit A0 = P2^1;
    
    /* These are not working because P4 is located at 0xA1, not bit addressable with sbit extension
     * sbit SCK = P4^0;
     * sbit DIN = P4^2;
     */
    unsigned char ContrastLevel;     // for contrast setting level
    
    //-----------------------------------
    // display data (128x64)
    //-----------------------------------
    
    unsigned char code Logo[]={
        // DisplayData should be 164x64/8 = 1312byte
        //....
        0x15,0x06,0x00,0x00,0x10,0x1F,0x10,0x00,0x00,0x12,0x15,0x15,0x15,0x88,0xC0
    };
    
    //-----------------------------------
    // Delay Routine
    //-----------------------------------
    
    void delayms(unsigned int m)                                    // 12MHz Xtal, close to ms value
    {
        unsigned int j;
        unsigned int i;
    
        for(i=0; i<m; i++)
            for(j=0; j<109; j++)
                _nop_();
    }
    
    //-----------------------------------
    // IO Routine
    //-----------------------------------
    
    void lcd_cmd(unsigned char Command)                             // Send command
    {
        SCK_set;
        A0 = 0;
        _CS = 0;
            if (Command & 0x80) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x40) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x20) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x10) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x08) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x04) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x02) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x01) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        _CS = 1;
    }
    
    void lcd_data(unsigned char DData)                              // Send data
    {
        SCK_set;
        A0 = 1;
        _CS = 0;
        if (DData & 0x80) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x40) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x20) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x10) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x08) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x04) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x02) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        if (DData & 0x01) DIN_set; else DIN_clear; SCK_clear; SCK_set;
        _CS = 1;
    }
    
    //-----------------------------------
    // Write a Screen
    //-----------------------------------
    void WriteScreen(unsigned char *DisplayData)                    // DisplayData should be 164x64/8 = 1312byte
    {
        unsigned char TempData;
        unsigned char i, j;
        for(i = 0; i < 8; i++) {
            lcd_cmd(0xb0 | i);    // select page 0~7
            lcd_cmd(0x10);        // start form column 4
            lcd_cmd(0x00);        // (2byte command)
            for(j=0;j<128;j++) {
                TempData=(*(DisplayData+(i*128)+j));
                lcd_data(TempData);
            }
        }
    }
    
    //-----------------------------------
    // Contrast control
    //-----------------------------------
    
    void LCD_Darker(void)
    {
        if (ContrastLevel < 0x3F) {
            ContrastLevel++;
        }
        lcd_cmd(0x81);            // E-Vol setting
        lcd_cmd(ContrastLevel);   // (2byte command)
    }
    
    void LCD_Lighter(void)
    {
        if (ContrastLevel>0x00) {
            ContrastLevel--;
        }
        lcd_cmd(0x81);            // E-Vol setting
        lcd_cmd(ContrastLevel);   // (2byte command)
    }
    
    
    //-----------------------------------
    // Init LCD module
    //-----------------------------------
    void initLCDM(void)
    {
        _RST = 1;                   // hardware reset LCD module
        _RST = 0;
        delayms(1);
        _RST = 1;
        delayms(800);
    
        ContrastLevel = 0x17;       // default Contrast Level  1a
        lcd_cmd(0xab);              // new
        lcd_cmd(0xaf);              // display on
        lcd_cmd(0x40);              // display start line=0
        lcd_cmd(0xc8);              // Common output mode select= reverse
        lcd_cmd(0xa6);              // normal display
        lcd_cmd(0xa4);              // Duisplay all point = off
        lcd_cmd(0xa3);              // LCD bias = 1/9   a2
        lcd_cmd(0x2f);              // Power control = all on
        lcd_cmd(0x25);              // Rab Ratio     26
        lcd_cmd(0x81);              // E-Vol setting
        lcd_cmd(ContrastLevel);     // (2byte command)
    }
    
    //-----------------------------------
    // Main Program
    //-----------------------------------
    void main()
    {
        /* In C never try to manipulate Stack Pointer, it is too dangerous !!!
         * SP = 0x60;
         */
    
         EA = 0;         // disable interrupts
        _CS = 1;
        _RST = 1;
        A0 = 1;
        SCK_set;
        DIN_set;
    
        initLCDM();
            LCD_Darker();
            LCD_Lighter();
        WriteScreen(Logo);
        while(1)
            ;
    }
    //end of program
    

Children
  •         if (Command & 0x80) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x40) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x20) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x10) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x08) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x04) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x02) DIN_set; else DIN_clear; SCK_clear; SCK_set;
            if (Command & 0x01) DIN_set; else DIN_clear; SCK_clear; SCK_set;
    


    comes out as

            if (Command & 0x80) DIN_set;
            else DIN_clear;
            SCK_clear;
            SCK_set;
            if (Command & 0x40) DIN_set;
            else DIN_clear;
            SCK_clear;
            SCK_set;
            if (Command & 0x20) DIN_set;
            else DIN_clear;
            SCK_clear;
            SCK_set;
    ..............
    


    which will clock a lot of time
    evidently the "zeusti" language does not have the 'C' construct of "else if"

    Erik

  • it's done, thanks for the help

    and one more thing for additional help from you,

    If i want to write a string in 4 lines then what change i have to do

    Please guide for further.....

    waiting for the reply.....

  • I don't see anything wrong with the code, with the exception of handling of setup and hold times.

    The if statement just decides if the next bit emitted should be zero or one. Then there is an obligatory clock pulse, before the next if statement decides if next bit his high or low.

    So the code is really expected to clock out 8 bits, from most significant to least significant.

    Baiscally:

    for (i = 0; i < 8; i++) {
        data_pin = (data & 0x80) ? 1 : 0;
        pulse_clock();
        data <<= 1;
    }
    

  • beware of forgeries.

    only genuine Zeusti posts have the Zeusti seal of approval

    Always yo're freind.

    Zeusti.

  • the first place you go blind is on the eyes.

  • In this particular program, If i have to display the individual strings on the graphical display on four lines of the lcd,

    what the modification i have to do for the same, Waiting for the reply....

    Please guide for further....

  • In this particular program, If i have to display the individual strings on the graphical display on four lines of the lcd,

    what the modification i have to do for the same, Waiting for the reply....

    Please guide for further....

  • But haven't we already solved your problem, i.e. how to address the processor pins?

    Or do you now want someone to rewrite your program according to a specific - not posted - requirements specification?

    If you have solved how to communicate with the module, then it's back to reading the datasheet for how to send commands to the display. Then combine commands + data output until the display shows the intended information.

  • Yes the problem is solved for only displaying the graphics on the lcd.

    I am still not able to write commands using the modules, it doesn't shows anything and one more thing is that the module has the highest darkness in it so i am not able to see anything on the lcd placing front of me, i have to place lcd in an angle which it shows the graphics

    void main()
    {
        /* In C never try to manipulate Stack Pointer, it is too dangerous !!!
         * SP = 0x60;
         */
    
         EA = 0;         // disable interrupts
        _CS = 1;
        _RST = 1;
        A0 = 1;
        SCK_set;
        DIN_set;
    
        initLCDM();
            lcd_data('S');    <------- data is not showing on the lcd, it shows raster image
            lcd_data(0x41);
        WriteScreen(Logo);
        while(1);
    }
    
    

    waiting for the reply...

  • It seems that this method to send commands and data to GLCD is for bitmap graphics.
    Is there other type of commands to send text and this rendered by the device ?
    The type/model/manufacturer of the GLCD never mentioned.
    A link to GLCD datasheet is never posted.
    A similar (successfull) case which is presented at http://www.8052.com user pages is this:
    www.8052.com/.../GraphLCD.phtml
    There is described fonts, glyphs, ASCII, rendering etc. BUT this is not a copy paste case.

  • This seems to be a combined effort.
    I think Original Poster must be very fortunate since valuable members are trying to help.

  • Yes, I am actually very lucky that all the members are helping me to clear this problem, I am a still a learner and i want to learn as much as possible.

    So my Senior members who are excellent in this field are helping me which is very helpful to me in learning.

    Please guides me as you are guiding me like always

  • This is the code for the serial graphical LCD I am using for sending the serial data to the lcd on four lines but it does not give any result at the end.

    It shows the raster image on the graphical lcd so please help for further for sending the lcd data on four lines

    #include <stdio.h>
    #include <config.h>
    #include <lcd128x64.h>                                    // definitions for the LCD controller
    #include <fonts.h>                                                // definitions for the fonts
    
    //-----------------------------------------------------------------------------
    // MAIN Routine
    //-----------------------------------------------------------------------------
    
    sbit SWT = P2^4;                                        /* eval board switch */
    
    void main (void)
    {
            config();                                                               // setup all the SFR initialization
            lcd_init();                                                             // initialize LCD display
            lcd_erase();                                                    // erase the display
    
            while(1)
            {
                    lcd_clear_area(SCRN_LEFT,SCRN_TOP,SCRN_RIGHT,SCRN_BOTTOM);
                    lcd_box(SCRN_LEFT,SCRN_TOP,SCRN_RIGHT,SCRN_BOTTOM);
                    lcd_box(SCRN_LEFT+2,SCRN_TOP+2,SCRN_RIGHT-2,SCRN_BOTTOM-2);
                    lcd_text(4,4,FONT_NINE_DOT," Priyank Rathod");
                    lcd_text(6,29,FONT_NINE_DOT,"128x64");
                    lcd_text(60,32,FONT_SEVEN_DOT," Toggling");
                    lcd_text(17,52,FONT_SIX_DOT,"">http://www.google.com");
                    lcd_update(SCRN_TOP,SCRN_BOTTOM);
    
                    while(SWT == 1);
                    while(SWT == 0);
    
                    lcd_invert_area(SCRN_LEFT+3,SCRN_TOP+3,SCRN_RIGHT-3,SCRN_BOTTOM-3);
                    lcd_update(SCRN_TOP,SCRN_BOTTOM);
    
                    while(SWT == 1);
                    while(SWT == 0);
    
            }
    }