1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Problem interfaceing PIC18F2550 and KS0108 LCD

Discussion in 'Microcontrollers' started by hkBattousai, Nov 6, 2009.

  1. Tymoty

    Tymoty New Member

    Joined:
    Nov 10, 2009
    Messages:
    11
    Likes:
    0
    ok. my lcd is atm12864D - datasheet is on the web, but there are mystakes-informations in the table and in description are different. For data I use portB, for others portD (CS1-RD3; CS2-RD2; D/I-RD7; RW-RD6; E-RD5; RESET-RD4) - I use PIC18F4525. I connected leds like you (by the way good work ;) ) and the program doesn't get trouhg init part. I write code for led to init part and it fall down in ClearScreen.

    void ClearScreen(void){
    unsigned char m,n;
    b_GLCD_GCS1=1;Delay();
    b_GLCD_GCS2=1;Delay();
    Delay10KTCYx(0);
    Delay10KTCYx(0);
    blinkLed(3);
    Delay10KTCYx(0);
    Delay10KTCYx(0);
    for(m=0;m<8;m++){
    GLCD_Write_Cmd(0x40);Delay(); //y=0
    GLCD_Write_Cmd(0xb8+m);Delay(); //x=0
    for(n=0;n<0x40;n++){
    GLCD_Write_Data(0x00);Delay();
    }
    }
    it works to for cycle and than it doesn't work. if I measure it, data=0; RS=0;RW=1;CS1=1;CS2=0 - this I don't understand, before blinkled CS1=CS2=1.
     
  2. hkBattousai

    hkBattousai Member

    Joined:
    Oct 30, 2009
    Messages:
    196
    Likes:
    0
    I couldn't understand your problem. But check this out, I rewrote the entire library, renamed the function names, etc, and added a configuration file to it! Download the file in my attachment (Rename the "zip" file extension to "rar", I don't believe that they don't support "rar" extension...).


    Configuration file (glcd_config.h):
    Code (text):
    // EN: Enable
    // DI: Data/Instruction
    // CS: Chip Select
    // RS: Reset
    // RW: Read/Write


    #ifndef _GLCD_CONFIG_H_
    #define _GLCD_CONFIG_H_


    // EN bit is complemented on the LCD side
    //#define GLCD_CFG_EN_COMPLEMENTED

    // DI bit is complemented on the LCD side
    // By default, D is active high and I is active low
    // Uncomment this line if your LCD has different pinout configuration
    //#define GLCD_CFG_DI_COMPLEMENTED

    // CSx bits are complemented on the LCD side
    //#define GLCD_CFG_CS_COMPLEMENTED

    // RS bit is complemented on the LCD side
    #define GLCD_CFG_RS_COMPLEMENTED

    // RW bit is complemented on the LCD side
    // By default, R is active high and W is active low
    // Uncomment this line if your LCD has different pinout configuration
    //#define GLCD_CFG_RW_COMPLEMENTED


    // EN bit
    #ifdef  GLCD_CFG_EN_COMPLEMENTED
    #define GLCD_EN_HIGH 0
    #define GLCD_EN_LOW  1
    #else
    #define GLCD_EN_HIGH 1
    #define GLCD_EN_LOW  0
    #endif

    // DI bit
    #ifdef  GLCD_CFG_DI_COMPLEMENTED
    #define GLCD_DI_HIGH 0
    #define GLCD_DI_LOW  1
    #else
    #define GLCD_DI_HIGH 1
    #define GLCD_DI_LOW  0
    #endif

    // CSx bits
    #ifdef  GLCD_CFG_CS_COMPLEMENTED
    #define GLCD_CS_HIGH 0
    #define GLCD_CS_LOW  1
    #else
    #define GLCD_CS_HIGH 1
    #define GLCD_CS_LOW  0
    #endif

    // RS bit
    #ifdef  GLCD_CFG_RS_COMPLEMENTED
    #define GLCD_RS_HIGH 0
    #define GLCD_RS_LOW  1
    #else
    #define GLCD_RS_HIGH 1
    #define GLCD_RS_LOW  0
    #endif

    // RW bit
    #ifdef  GLCD_CFG_RW_COMPLEMENTED
    #define GLCD_RW_HIGH 0
    #define GLCD_RW_LOW  1
    #else
    #define GLCD_RW_HIGH 1
    #define GLCD_RW_LOW  0
    #endif


    #endif  // #ifndef _GLCD_CONFIG_H_
    DI is the RS in the old library, not to confuse with Reset.

    Just uncomment the GLCD_CFG_xx_COMPLEMENTED constant if your LCD has that pin complemented. For example in my LCD only the Reset pin is complemented, so I only activated GLCD_CFG_RS_COMPLEMENTED constant. Using this configuration file, this library can be used to drive any 128x64 pixel LCD!! Now this library is device-independent!
     

    Attached Files:

  3. Tymoty

    Tymoty New Member

    Joined:
    Nov 10, 2009
    Messages:
    11
    Likes:
    0
    My problem is that my program does't get trought init routine. It fall down at part clearscreen when it do this: GLCD_Write_Cmd(0x40) it go to wait_not_busy and there is fall down. i measured lcd and the values I write before. I don't know how to repair it.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. hkBattousai

    hkBattousai Member

    Joined:
    Oct 30, 2009
    Messages:
    196
    Likes:
    0

    What do you mean by "to fall down"?
    Does your code enter an infinite loop inside ClearScreen() function, or your LCD stop responding after ClearScreen?
     
  6. Tymoty

    Tymoty New Member

    Joined:
    Nov 10, 2009
    Messages:
    11
    Likes:
    0
    I connect leds to parts of init (in wait_not_busy; write_cmd and clearscreen)
    and when program do clearscreen, part :GLCD_Write_Cmd(0x40) it go to wait_not_busy and there the program stop and I don't know why. maybe it do infity loop in
    if (b_GLCD_GCS1==1 && b_GLCD_GCS2==1){
    b_GLCD_GCS1=0;
    while (GLCD_Read()&0x80);
    b_GLCD_GCS1=1;
    b_GLCD_GCS2=0;
    while (GLCD_Read()&0x80);
    b_GLCD_GCS2=1;
    }
    else{
    while (GLCD_Read()&0x80);
    }
     
  7. Tymoty

    Tymoty New Member

    Joined:
    Nov 10, 2009
    Messages:
    11
    Likes:
    0
    I try something and I found part where is the problem. This is it:

    unsigned char GLCD_Read(void){
    b_GLCD_E=1;Delay();
    Delay();
    Wa=GLCD_Data;Delay();
    blinkLed(3);
    b_GLCD_E=0;Delay();
    return Wa;
    }

    two times it go trought right but when it go third it ends in blinkLed(3); and led blink and blink and blink. Any ideas?
     
  8. hkBattousai

    hkBattousai Member

    Joined:
    Oct 30, 2009
    Messages:
    196
    Likes:
    0
    Obviously, it gets stuck at "while (GLCD_Read()&0x80);" line. GLCD_Read() never returns something maskable with 0x80 value.

    1) Check all your wiring. Use a multimeter and test if you have any disconnection in your circuit wires.
    2) Make sure that your display is compatible with this library. Some bits in the LCD may be complemented, while they are not in the library. If that's the case, use the modified library I attached above to configure those pins.
    3) Place some blinkLed() functions inside GLCD_Read() function to find out the exact line where it reads the wrong value. Though this step would not make any contribution to solve your problem, it may help you learn the mechanism of the LCD controller.

    EDIT: And wrap your code between "code" "/code" tags.
     
    Last edited: Nov 15, 2009
  9. Tymoty

    Tymoty New Member

    Joined:
    Nov 10, 2009
    Messages:
    11
    Likes:
    0
    Still nothing. I built it again, measure it but everything is ok.
    program do still the same. it do display on and when it do set adres z (start line) it do again GLCD_Read. i havent any ideas.

     
  10. hkBattousai

    hkBattousai Member

    Joined:
    Oct 30, 2009
    Messages:
    196
    Likes:
    0
    I've just written two new functions using my basic analytical geometry knowledge:

    Code (text):
    void glcd_DrawLine(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2)
    {
        // y = ((y2 - y1) / (x2 - x1)) * (x - x1) + y1
        float m = (float) (y2 - y1) / (float) (x2 - x1);
        for(glcdI=x1; glcdI<=x2; glcdI++) glcd_Plot(glcdI, (unsigned char) (m * (glcdI - x1) + y1));   
    }

    void glcd_DrawCircle(unsigned char x, unsigned char y, unsigned char r)
    {
        // y = y0 - sqrt(r^2 - (x0 - x)^2)
        // y = y0 + sqrt(r^2 - (x0 - x)^2)
        unsigned char rt;   // The root term
        signed char i, j;
        for (i=x-r; i<=x+r; i++)
        {
            rt = (signed char) sqrt((float) r*r - (float) (x-i)*(x-i));
            if ((i < 0) || (i > 127)) continue;
            j = y - rt;
            if (!((j > 63) || (j < 0))) glcd_Plot((unsigned char) i, (unsigned char) j);
            j = y + rt;
            if (!((j > 63) || (j < 0))) glcd_Plot((unsigned char) i, (unsigned char) j);
        }
    }
    glcd_DrawLine() is working good, but glcd_DrawCircle doesn't display anything. Do you guys have any idea why?
     
  11. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,016
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    There is a nice algorithm to draw a circle. I implemented it in VB and it should be simple to convert to C.
    Code (text):

    Sub DrawCircle(CX, CY, R)
        x = 0
        y = R
        p = -R / 2
        Plot8 CX, CY, x, y
        Do While x < y
            x = x + 1
            If p < 0 Then
                p = p + 2 * x + 1
            Else
                y = y - 1
                p = p + 2 * (x - y) + 1
            End If
            Plot8 CX, CY, x, y
        Loop
    End Sub

    Sub Plot8(x, y, dx, dy)
            PlotPixel x + dx, y + dy, vbRed
            PlotPixel x + dx, y - dy, vbRed
            PlotPixel x - dx, y + dy, vbRed
            PlotPixel x - dx, y - dy, vbRed
            PlotPixel x + dy, y + dx, vbRed
            PlotPixel x + dy, y - dx, vbRed
            PlotPixel x - dy, y + dx, vbRed
            PlotPixel x - dy, y - dx, vbRed
    End Sub
    The algorithm generates 1/8th of a circle and the polt8 routine mirrors it about the center.

    The above will be much quicker than using floats and squareroots.

    Mike.
     
  12. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,016
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    I thought I'd dig out my old board and try the circle algorithm and one thing I found is that if your supply isn't good enough you don't see anything. so check your supply is up to the job.

    Anyway, here is the circle code in C18,
    Code (text):

    void Plot8(unsigned char x,unsigned char y,unsigned char dx,unsigned char dy){
        plot(x + dx, y + dy);
        plot(x + dx, y - dy);
        plot(x - dx, y + dy);
        plot(x - dx, y - dy);
        plot(x + dy, y + dx);
        plot(x + dy, y - dx);
        plot(x - dy, y + dx);
        plot(x - dy, y - dx);
    }

    void PutCircle(unsigned char CX,unsigned char CY,unsigned char R){
    unsigned char y,x;
    signed char p;
        x=0;
        y=R;
        p= -(R/2);
        Plot8(CX,CY,x,y);
        while(x<y){
            x++;
            if(p<0)
                p=p+2*x+1;
            else{
                y--;
                p=p+2*(x-y)+1;
            }
            Plot8(CX, CY, x, y);
        }
    }
     
    I like the above as it doesn't use any complex maths routines.

    Mike.
     
  13. Tymoty

    Tymoty New Member

    Joined:
    Nov 10, 2009
    Messages:
    11
    Likes:
    0
    It running!!!
    I am donkey :eek: I forget rewrite header. I have three versions, I use third but header a had write first.
     
  14. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,016
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    I added the code to the plot routine to exclude off screen pixels and you can now plot on the edge of the screen. This is what PutCircle(50,50,20); does. I think it looks pretty good for an integer maths circle.

    Mike.
     

    Attached Files:

    • GLCD.jpg
      GLCD.jpg
      File size:
      54.8 KB
      Views:
      411
  15. hkBattousai

    hkBattousai Member

    Joined:
    Oct 30, 2009
    Messages:
    196
    Likes:
    0
    Is there any algorithm like this for drawing lines?
     
  16. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,016
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    There is an algorithm like this for doing lines at any angle but I haven't implemented it in C. If you google Bresenham you should find it.

    Mike.
     
  17. Oznog

    Oznog Active Member

    Joined:
    Apr 21, 2004
    Messages:
    2,879
    Likes:
    11
    Location:
    Austin, Tx
    Code (text):
    void PutMessage(static char rom *Message){
    This can cause you grief. PIC uses a Harvard architecture, which means that accessing ROM is completely different than accessing RAM. You will probably need to print out a variable which means building a string in RAM and passing that, but that task isn't set up to read RAM strings and passing a RAM pointer will probably bomb badly (actually, depends on compiler somewhat). It SHOULD be set up to accept a RAM pointer, because it's reusable- your main code will create a string buffer at least as big as the char width of the display +1 char for the NULL string terminator, and you sprintf into that buffer, even when printing out fixed ROM messages. Then the task will handle the RAM buffer the same way for fixed or variable messages.
     
  18. ChipBurner

    ChipBurner New Member

    Joined:
    Jul 1, 2010
    Messages:
    5
    Likes:
    1
    Hi people! I'm using the Mplab c18 c compiler, a PIC18F452 and a GLCD Displaytech 64128c series with ks0108/7 controllers.
    I just copy the initial file and tried compile but give me the error D:\PIC_PROGRAMS\lcd_c2\glcd.c:5:Error [1109] type mismatch in redeclaration of 'W'
    any one have a idea of what means? W is a char variable declared only in this file...
    my chages in the code files are:

    #include <p18f452.h> // (in all files)
    #include "glcd.h"
    #pragma config WDT = OFF
    #pragma config BOR = OFF
    #pragma config STVR = ON
    #pragma config DEBUG = ON
    #pragma config LVP = OFF
    #pragma config OSC = RC
    #pragma config OSCS = OFF
     
    Last edited: Jul 1, 2010
  19. hkBattousai

    hkBattousai Member

    Joined:
    Oct 30, 2009
    Messages:
    196
    Likes:
    0
    ^ Can you write here the line where "W" is declared? I is probably in the file "p18f452.h".
     
  20. ChipBurner

    ChipBurner New Member

    Joined:
    Jul 1, 2010
    Messages:
    5
    Likes:
    1
    Hi hkBattousai, Thanks by the answer!
    Is in the 'glcd.c' and starts like:

    #include <p18f452.h>
    #include "glcd.h"

    const rom unsigned char Font[96][7];
    unsigned char i,XPos,YPos,W;

    void plot(unsigned char x,unsigned char y){
    unsigned char d;
    if(x>63){......

    I tried not declare the 'w' and give me the error
    Error - could not find file 'c018i.o'.

    I start thinking that my compiler is not working well... can any one tell me any c compiler to start working? My version is the student version of microchip and I installl it on :\microchip\MCC18\ directory with all features. I maked the test with the buildit.bat file like they say and it generate the file that they say...
     
    Last edited: Jul 2, 2010
  21. 3v0

    3v0 Coop Build Coordinator Forum Supporter

    Joined:
    Jul 14, 2006
    Messages:
    9,404
    Likes:
    227
    Location:
    OKLAHOMA USA
    There is a bug in MPLAB. The only sure way I know of fixing the C018i error is to specify the lib path from the PROJECT>BUILD_OPTIONS_PROJECT
    Select the DIRECTORIES tab and followed by "LIBRARY SEARCH PATH" from the drop down box "show directories for". Add the path C:\MCC18\lib
     

Share This Page