Need help in solving issue with LCD Nokia5110 (PCD8544)

Discussion in 'Embedded Systems and Microcontrollers' started by phetal, Jun 19, 2017.

  1. phetal

    Thread Starter New Member

    Jun 18, 2017
    5
    0
    I have been scratching my head since couple of days to solve a lcd display issue.

    Problem-1: As I read from the datasheet of PCD8544, I can set x, y position to (0, 0) by writing command 0x80 and 0x40. However upon restart when I write these commands and then display any pattern, it seem to be displaying at different location (almost at x=73, y = 0) when I keep on writing then after it continue to write till last pixel (bottom right corner) and then rolls back to top left. If i write exactly 504 data, it covers whole LCD but the start position is not as expected (0,0). Any clue or pointer what could be going wrong? PS: If I don't write (0,0) upon restart and directly start writing data, it starts writing from the first pixel of the lcd as expected :(

    pls see the Scenario1 image

    Problem-2: If I want to write some data i.e. write data to first byte of first row, second byte of second row, third byte of third row and so on....
    If I dont set the x,y position at start up (first set_xy_pos(0,0)) and only set the Y position within while loop.

    I see that it starts to display from first pixel but does not display all the rows.
    It just displays 1st, 2nd and 4th rows only rest remains blank

    Pls see Scenario2 image


    Any clue why it does not display any data on 3rd, 5th and 6th row when I explicitly set the y position?

    Problem-3: upon restart if I write data 0x01, it makes two pixel ON. MSB and LSB as if I have written 0x81, any clue?
    Pls see Scenario3 image
     
  2. GopherT

    AAC Fanatic!

    Nov 23, 2012
    8,025
    6,784
    I don't open zip files. Post your code as text inside tags as follows (replace quote marks with square brackets)
    "code"
    (Place program code here)
    "/code"
     
  3. phetal

    Thread Starter New Member

    Jun 18, 2017
    5
    0
    Here is the code....

    ======= main.c ============
    "code"
    #include <pic18f45k40.h>
    #include "config.h"
    //#include "switch_matrix.h"
    //#include "queue.h"
    #include "lcd.h"

    #define LED1_LATBIT LATAbits.LATA1
    #define LED1_PORTBIT PORTAbits.RA1

    #define LED2_LATBIT LATAbits.LATA2
    #define LED2_PORTBIT PORTAbits.RA2

    void main(void) {

    OSCFRQbits.HFFRQ = 0b0011; //8MHZ clock

    LATDbits.LATD2 = 1; //LCD_POWER_ON_OFF

    // INTCONbits.PEIE = 1; //peripheral interrupt enable
    // INTCONbits.GIE = 1;

    init_lcd_if();
    unsigned char y_pos = 0;
    unsigned char x_pos = 0;

    __delay_ms(100);
    set_xy_pos(0, 0);

    while (1)
    {
    //buf full, read and flush
    proc_lcd_data();
    __delay_ms(100);

    x_pos++;

    if(x_pos > 83) {
    x_pos = 0;
    y_pos++;

    if(y_pos > 5) {
    y_pos = 0;
    }
    }
    set_xy_pos(x_pos, y_pos);
    }
    return;
    }
    "/code"

    =========== lcd.c ====================
    "code"


    #include <pic18f45k40.h>
    #include "config.h"
    #include "lcd.h"
    //#include "queue.h"

    #define LCD_COMMAND LATDbits.LATD1 = 0;
    #define LCD_DATA LATDbits.LATD1 = 1;
    #define LCD_CS(level) LATAbits.LA5 = level;

    #define HIGH 1
    #define LOW 0

    static void send_lcd_cmd(unsigned char cmd);
    void SPI_Write(unsigned char x);

    void init_lcd_if(void)
    {
    ANSELDbits.ANSELD1 = 0; //MODE Select, 0:Cmd, 1:Data
    TRISDbits.TRISD1 = 0;

    ANSELDbits.ANSELD2 = 0; //LCD_ON_OFF
    TRISDbits.TRISD2 = 0;

    ANSELDbits.ANSELD3 = 0; //RESET, Active low
    TRISDbits.TRISD3 = 0;
    // LATDbits.LATD3 = 1;

    ANSELCbits.ANSELC3 = 0; //CLK
    TRISCbits.TRISC3 = 0;

    ANSELCbits.ANSELC5 = 0; //MOSI
    TRISCbits.TRISC5 = 0;

    ANSELAbits.ANSELA5 = 0; //CS, Active low
    TRISAbits.TRISA5 = 0;

    //MOSI
    RC5PPS = 0b10000;
    //CLK
    RC3PPS = 0b01111;

    //config SPI registers

    SSP1STATbits.SMP = 1;
    SSP1CON1bits.WCOL = 0; //no collision
    SSP1CON1bits.SSPOV = 0; //no overflow

    SSP1CON1bits.CKP = 0; //idle state for the clock is a low level
    // SSP1CON1bits.SSPM = 0b0010; //clock = FOSC/64
    SSP1CON1bits.SSPM = 0b0001; //clock = FOSC/16
    // SSP1CON1bits.SSPM = 0b0000; //clock = FOSC/4

    SSP1CON3bits.PCIE = 1;


    SSP1CON1bits.SSPEN = 1;

    // PIE3bits.SSP1IE = 1; //SPI int enabled
    SSP1BUF = 0x00;
    // SPI_Write(0x00);
    //SS bit always on, SP_DEBUG
    LCD_CS(HIGH);
    __delay_ms(10);
    LCD_CS(LOW); //Keep the CS enabled always

    LATDbits.LATD3 = 0; //LCD_RESET
    __delay_ms(100);
    LATDbits.LATD3 = 1; //LCD_RESET

    PIR3bits.SSP1IF=0;

    SPI_Write(0x00);

    LCD_COMMAND;

    send_lcd_cmd(0x21);
    send_lcd_cmd(0x13);
    send_lcd_cmd(0x07);
    send_lcd_cmd(0x80);
    send_lcd_cmd(0x20);
    send_lcd_cmd(0x0C); //Normal mode

    clear_lcd_disp();
    }

    static void send_lcd_cmd(unsigned char cmd)
    {
    LCD_CS(LOW);
    LCD_COMMAND;
    SPI_Write(cmd);
    LCD_CS(HIGH);
    }

    void send_lcd_data(unsigned char data)
    {
    LCD_CS(LOW);
    LCD_DATA;
    SPI_Write(data);
    LCD_CS(HIGH);
    }

    void set_display_off()
    {
    send_lcd_cmd(0x08); //Normal mode
    }

    void set_display_on()
    {
    send_lcd_cmd(0x0C); //Normal mode
    }
    void clear_lcd_disp(void)
    {
    LCD_DATA;
    LCD_CS(LOW);
    for(int i = 0; i < 504; i++) {
    SPI_Write(0x00);
    }
    LCD_CS(HIGH);
    }

    void proc_lcd_data(void)
    {
    LCD_CS(LOW);
    LCD_DATA;
    SPI_Write(0xFC);
    LCD_CS(HIGH);
    }

    void set_xy_pos(unsigned char x, unsigned char y)
    {
    // send_lcd_cmd(0x40 | y);
    // send_lcd_cmd(0x80 | x);
    }

    void SPI_Write(unsigned char x)
    {
    unsigned char data_flush;
    SSP1BUF=x; /* Copy data in SSBUF to transmit */
    while(!PIR3bits.SSP1IF); /* Wait for complete 1 byte transmission */
    PIR3bits.SSP1IF=0; /* Clear SSPIF flag */
    data_flush=SSP1BUF; /* Flush the data */
    }
    "/code"

    =============== lcd.h =====================
    "code"

    #ifndef LCD_H
    #define LCD_H

    #ifdef __cplusplus
    extern "C" {
    #endif

    typedef enum LCD_STATE
    {
    LCD_INIT = 0,
    LCD_IDLE,
    LCD_DATA_WRITE,
    LCD_CMD_WRITE,
    };


    void init_lcd_if(void);
    void clear_lcd_disp(void);
    void write_lcd_cmd(void);
    void send_lcd_data(unsigned char data);
    void set_display_off();
    void set_display_on();
    void set_xy_pos(unsigned char x, unsigned char y);

    void proc_lcd_data(void);



    #ifdef __cplusplus
    }
    #endif

    #endif /* LCD_H */

    "/code"
     
  4. GopherT

    AAC Fanatic!

    Nov 23, 2012
    8,025
    6,784
    Unreadable without formatting.

    Inset your code by clicking as follows and selecting "code" when you make a new post.
    image.jpeg
     
  5. phetal

    Thread Starter New Member

    Jun 18, 2017
    5
    0
    ======= main.c =================

    Code (Text):
    1. #include <pic18f45k40.h>
    2. #include "config.h"
    3. //#include "switch_matrix.h"
    4. //#include "queue.h"
    5. #include "lcd.h"
    6.  
    7. #define LED1_LATBIT LATAbits.LATA1
    8. #define LED1_PORTBIT PORTAbits.RA1
    9.  
    10. #define LED2_LATBIT LATAbits.LATA2
    11. #define LED2_PORTBIT PORTAbits.RA2
    12.  
    13. void main(void) {
    14.  
    15.    OSCFRQbits.HFFRQ = 0b0011;   //8MHZ clock
    16.  
    17.     LATDbits.LATD2 = 1;     //LCD_POWER_ON_OFF
    18.    
    19. //    INTCONbits.PEIE = 1;    //peripheral interrupt enable
    20. //    INTCONbits.GIE = 1;
    21.    
    22.     init_lcd_if();
    23.  
    24.     unsigned char y_pos = 0;
    25.     unsigned char x_pos = 0;
    26.    
    27.     __delay_ms(100);
    28.     set_xy_pos(0, 0);
    29.  
    30.     while (1)
    31.     {
    32.         //buf full, read and flush
    33.         proc_lcd_data();
    34.         __delay_ms(100);
    35.  
    36.         x_pos++;
    37.  
    38.         if(x_pos > 83) {
    39.             x_pos = 0;
    40.             y_pos++;
    41.  
    42.             if(y_pos > 5) {
    43.                 y_pos = 0;
    44.             }
    45.         }
    46.         set_xy_pos(x_pos, y_pos);
    47.     }
    48.     return;
    49. }
    ===================== lcd.c ===================

    Code (Text):
    1.  
    2. #include <pic18f45k40.h>
    3. #include "config.h"
    4. #include "lcd.h"
    5. //#include "queue.h"
    6.  
    7. #define LCD_COMMAND LATDbits.LATD1 = 0;
    8. #define LCD_DATA LATDbits.LATD1 = 1;
    9. #define LCD_CS(level) LATAbits.LA5 = level;
    10.  
    11. #define HIGH 1
    12. #define LOW  0
    13.  
    14. static void send_lcd_cmd(unsigned char cmd);
    15. void SPI_Write(unsigned char x);
    16.  
    17. void init_lcd_if(void)
    18. {
    19.     ANSELDbits.ANSELD1 = 0;     //MODE Select, 0:Cmd, 1:Data
    20.     TRISDbits.TRISD1 = 0;
    21.    
    22.     ANSELDbits.ANSELD2 = 0;     //LCD_ON_OFF
    23.     TRISDbits.TRISD2 = 0;
    24.    
    25.     ANSELDbits.ANSELD3 = 0;     //RESET, Active low
    26.     TRISDbits.TRISD3 = 0;
    27. //   LATDbits.LATD3 = 1;
    28.  
    29.     ANSELCbits.ANSELC3 = 0;     //CLK
    30.     TRISCbits.TRISC3 = 0;
    31.    
    32.     ANSELCbits.ANSELC5 = 0;     //MOSI
    33.     TRISCbits.TRISC5 = 0;
    34.    
    35.     ANSELAbits.ANSELA5 = 0;     //CS, Active low
    36.     TRISAbits.TRISA5 = 0;
    37.    
    38.     //MOSI
    39.     RC5PPS = 0b10000;
    40.     //CLK
    41.     RC3PPS = 0b01111;
    42.    
    43.     //config SPI registers
    44.    
    45.     SSP1STATbits.SMP = 1;
    46.     SSP1CON1bits.WCOL = 0;  //no collision
    47.     SSP1CON1bits.SSPOV = 0; //no overflow
    48.    
    49.     SSP1CON1bits.CKP = 0;   //idle state for the clock is a low level
    50. //    SSP1CON1bits.SSPM = 0b0010;  //clock = FOSC/64
    51.     SSP1CON1bits.SSPM = 0b0001;  //clock = FOSC/16
    52. //    SSP1CON1bits.SSPM = 0b0000;  //clock = FOSC/4
    53.    
    54.     SSP1CON3bits.PCIE = 1;
    55.  
    56.  
    57.     SSP1CON1bits.SSPEN = 1;
    58.    
    59. //    PIE3bits.SSP1IE = 1;       //SPI int enabled
    60.     SSP1BUF = 0x00;
    61. //    SPI_Write(0x00);
    62.     //SS bit always on, SP_DEBUG
    63.     LCD_CS(HIGH);
    64.     __delay_ms(10);
    65.     LCD_CS(LOW);        //Keep the CS enabled always
    66.    
    67.     LATDbits.LATD3 = 0;     //LCD_RESET
    68.     __delay_ms(100);
    69.     LATDbits.LATD3 = 1;     //LCD_RESET
    70.    
    71.     PIR3bits.SSP1IF=0;
    72.  
    73.     SPI_Write(0x00);
    74.    
    75.     LCD_COMMAND;
    76.  
    77.     send_lcd_cmd(0x21);
    78.     send_lcd_cmd(0x13);
    79.     send_lcd_cmd(0x07);
    80.     send_lcd_cmd(0x80);
    81.     send_lcd_cmd(0x20);
    82.     send_lcd_cmd(0x0C);     //Normal mode
    83.    
    84.     clear_lcd_disp();
    85. }
    86.  
    87. static void send_lcd_cmd(unsigned char cmd)
    88. {
    89.     LCD_CS(LOW);
    90.     LCD_COMMAND;
    91.     SPI_Write(cmd);
    92.     LCD_CS(HIGH);  
    93. }
    94.  
    95. void send_lcd_data(unsigned char data)
    96. {
    97.     LCD_CS(LOW);
    98.     LCD_DATA;
    99.     SPI_Write(data);
    100.     LCD_CS(HIGH);
    101. }
    102.  
    103. void set_display_off()
    104. {
    105.     send_lcd_cmd(0x08);     //Normal mode
    106. }
    107.  
    108. void set_display_on()
    109. {
    110.     send_lcd_cmd(0x0C);     //Normal mode
    111. }
    112. void clear_lcd_disp(void)
    113. {
    114.     LCD_DATA;
    115.     LCD_CS(LOW);
    116.     for(int i = 0; i < 504; i++) {
    117.         SPI_Write(0x00);
    118.     }
    119.     LCD_CS(HIGH);
    120. }
    121.  
    122. void proc_lcd_data(void)
    123. {
    124.     LCD_CS(LOW);
    125.     LCD_DATA;
    126.     SPI_Write(0xFC);
    127.     LCD_CS(HIGH);
    128. }
    129.  
    130. void set_xy_pos(unsigned char x, unsigned char y)
    131. {
    132. //    send_lcd_cmd(0x40 | y);
    133. //    send_lcd_cmd(0x80 | x);
    134. }
    135.  
    136. void SPI_Write(unsigned char x)
    137. {
    138.     unsigned char data_flush;
    139.     SSP1BUF=x;                /* Copy data in SSBUF to transmit */
    140.     while(!PIR3bits.SSP1IF);    /* Wait for complete 1 byte transmission */
    141.     PIR3bits.SSP1IF=0;        /* Clear SSPIF flag */
    142.     data_flush=SSP1BUF;        /* Flush the data */
    143. }
    =========== lcd.h =============================
    Code (Text):
    1.  
    2. #ifndef LCD_H
    3. #define    LCD_H
    4.  
    5. #ifdef    __cplusplus
    6. extern "C" {
    7. #endif
    8.  
    9.     typedef enum LCD_STATE
    10.     {
    11.         LCD_INIT = 0,
    12.         LCD_IDLE,
    13.         LCD_DATA_WRITE,
    14.         LCD_CMD_WRITE,
    15.     };
    16.  
    17.    
    18.     void init_lcd_if(void);
    19.     void clear_lcd_disp(void);
    20.     void write_lcd_cmd(void);
    21.     void send_lcd_data(unsigned char data);
    22.     void set_display_off();
    23.     void set_display_on();
    24.     void set_xy_pos(unsigned char x, unsigned char y);
    25.    
    26.     void proc_lcd_data(void);
    27.  
    28.  
    29.  
    30. #ifdef    __cplusplus
    31. }
    32. #endif
    33.  
    34. #endif    /* LCD_H */
    35.  
    36.  
     
  6. GopherT

    AAC Fanatic!

    Nov 23, 2012
    8,025
    6,784
    Read the data sheet for the LCD driver chip, there is something about automatically increment into the current register to the next pixel after a write event.
     
  7. phetal

    Thread Starter New Member

    Jun 18, 2017
    5
    0
    Yes, it says it will automatically increment based on the selection (V=0 or V=1). In my case I have it V=0 and also I am facing problem when I explicitly set the x n y position to 0 at start up.
    So, I wonder could there be any other issue?
     
  8. jjw

    Member

    Dec 24, 2013
    236
    34
    In the set_xy_pos ( ) you have commented out the commands:
    send _lcd_cmd ( 0x80|x) ...
     
    Last edited: Jun 23, 2017
  9. phetal

    Thread Starter New Member

    Jun 18, 2017
    5
    0
    As I have mentioned three problems, I face the problem when I do not comment this line (basically setting x,y position to '0' at startup). However it was comment to test other problem scenarios
     
Loading...