GLCD with a PIC16F877

(instructions, reset, WDT, specifications...) PIC12F6xx, PIC16Fxxx, PIC16F6x, PIC16F7x

GLCD with a PIC16F877

Postby GettinBetter » Wed Jan 13, 2021 11:46 pm

H/W: EasyPIC V7 Dev Board, ICD3, PIC16F877, Winstar WDG0151-TMI GLCD module.
S/W: MPLABX, XC8
4MHz Xtal


Untill my newer PIC16F18877's turn up, I'm using this chip. But with the help of some tweaked example code I'm trying to find my way around a GLCD.
Example code from https://www.exploreembedded.com/wiki/Interfacing_GLCD(128x64)_with_PIC16F877A
Here's the code I'm using..

Code: Select all
/*
 * File:   main.c
 * Author: Example Code from exploreembedded.com
 * Created on 09 January 2021, 23:37
 */


// CONFIG
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config CP = OFF         // FLASH Program Memory Code Protection bits (Code protection off)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low Voltage In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection (Code Protection off)
#pragma config WRT = ON         // FLASH Program Memory Write Enable (Unprotected program memory may be written to by EECON control)


#include <xc.h>
#include <pic.h>
#include <pic16f877.h>
#include <htc.h>
#include <stdio.h>



/*
 * Project name: Testing GLCD with PIC16F887
*/

#define  FOSC = 4000000L   


/**
 *  Control bus PB0:PB4
 *  Data bus PD0:PD7
 */


#define GlcdDataBus      PORTD
#define GlcdControlBus   PORTB

#define GlcdDataBusDirnReg   TRISD
#define GlcdCtrlBusDirnReg   TRISB

#define CS1     0x00       // Select segments 1-64
#define CS2     0x01       // Select segments 65-128
#define RS      0x02       // H: Data - L: Instruction
#define RW      0x03       // H: Read Data - L: Write Data
#define EN      0x04       // Enable

/* 5x7 Font including 1 space to display HELLO WORLD */
char H[]={0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00};
char E[]={0x7F, 0x49, 0x49, 0x49, 0x41, 0x00};
char L[]={0x7F, 0x40, 0x40, 0x40, 0x40, 0x00};
char O[]={0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00};

char W[]={0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00};
char R[]={0x7F, 0x09, 0x19, 0x29, 0x46, 0x00};
char D[]={0x7F, 0x41, 0x41, 0x22, 0x1C, 0x00};


/* local function to generate delay */
void delay(int cnt)
{
   int i;
    for(i=0;i<cnt;i++);
}


void Glcd_SelectPage0() // CS1=1, CS2=0
{
    GlcdControlBus |= (1<<CS1);
    GlcdControlBus &= ~(1<<CS2);
}

void Glcd_SelectPage1() // CS1=0, CS1=1
{
    GlcdControlBus &= ~(1<<CS1);
    GlcdControlBus |= (1<<CS2);
}

/* Function to send the command to LCD */
void Glcd_CmdWrite(char cmd)
{
    GlcdDataBus = cmd;           //Send the Command nibble
    GlcdControlBus &= ~(1<<RS);  // Send LOW pulse on RS pin for selecting Command register
    GlcdControlBus &= ~(1<<RW);  // Send LOW pulse on RW pin for Write operation
    GlcdControlBus |= (1<<EN);   // Generate a High-to-low pulse on EN pin
    delay(100);
    GlcdControlBus &= ~(1<<EN);

    delay(1000);
}

/* Function to send the Data to LCD */
void Glcd_DataWrite(char dat)
{
    GlcdDataBus = dat;           //Send the data on DataBus nibble
    GlcdControlBus |= (1<<RS);   // Send HIGH pulse on RS pin for selecting data register
    GlcdControlBus &= ~(1<<RW);  // Send LOW pulse on RW pin for Write operation
    GlcdControlBus |= (1<<EN);   // Generate a High-to-low pulse on EN pin
    delay(100);
    GlcdControlBus &= ~(1<<EN);

    delay(1000);
}

void Glcd_DisplayChar(char *ptr_array)
{
    int i;
    for(i=0;i<6;i++) // 5x7 font, 5 chars + 1 blank space
        Glcd_DataWrite(ptr_array[i]);
}
                                                                   

int main()
{
    GlcdDataBusDirnReg = 0x00;  // Configure all the LCD pins as output
    GlcdCtrlBusDirnReg = 0x00;  // Configure the Ctrl pins as output

    /* Select the Page0/Page1 and Turn on the GLCD */
    Glcd_SelectPage0();     //
    Glcd_CmdWrite(0x3F);    //
    Glcd_SelectPage1();     //
    Glcd_CmdWrite(0x3F);    //
    delay(100);

    /* Select the Page0/Page1 and Enable the GLCD */
    Glcd_SelectPage0();     //
    Glcd_CmdWrite(0xC0);    //
    Glcd_SelectPage1();     //
    Glcd_CmdWrite(0xC0);    //
    delay(100);

    Glcd_SelectPage0();     // Display HELLO on Page0, Line1
    Glcd_CmdWrite(0xB8);    // 0xB8 = line 0 (the top line)
    Glcd_DisplayChar(H);
    Glcd_DisplayChar(E);
    Glcd_DisplayChar(L);
    Glcd_DisplayChar(L);
    Glcd_DisplayChar(O);

    Glcd_SelectPage1();     // Display WORLD on Page1, Last line
    Glcd_CmdWrite(0xBF);    // 0xB8 = line 7 (the bottom line)
    Glcd_DisplayChar(W);
    Glcd_DisplayChar(O);
    Glcd_DisplayChar(R);
    Glcd_DisplayChar(L);
    Glcd_DisplayChar(D);

    while(1);
}


... and here's the output on the analyser.

GLCD_nalyser-01.png
GLCD analyser output
GLCD_nalyser-01.png (112.07 KiB) Viewed 4623 times


Problem is that there is no output on the screen, pixels are illuminated and contrast is adjustable.

Any suggestions would be appreciated

Regards
GB
History teaches us that history doesn't teach us.
User avatar
GettinBetter
 
Posts: 43
Joined: Wed Jun 06, 2018 8:48 pm

Re: GLCD with a PIC16F877

Postby AussieSusan » Thu Jan 14, 2021 3:07 am

No idea of your problem but the #include lines after the "xc.h" one (including the stdio.h one) can and should be removed.
The 'delay' function you have written may well not be working - the compiler would have every right to replace the whole thing with a NOP (or not even that) - and it almost certainly will if there is any level of optimisation applied. Use the builtin delay functions is you need to.
Looking at the trace, the 'EN' signal seems to be triggering too often for the changes in the data lines.
With an old chip that does not have LAT registers I would certainly NOT be writing to the same register with 1 bit changes the way you are. Read the register if you need to into a shadow variable, set/clear the bits you need to i that shadow, and then write the shadow out to the port register.
Susan
AussieSusan
Verified identity
 
Posts: 173
Joined: Mon Jun 16, 2014 4:45 am
PIC experience: Experienced Hobbyist

Re: GLCD with a PIC16F877

Postby GettinBetter » Thu Jan 14, 2021 11:04 pm

AussieSusan wrote:No idea of your problem but the #include lines after the "xc.h" one (including the stdio.h one) can and should be removed.

Ok, commented out and it was fine, so removed.

AussieSusan wrote:The 'delay' function you have written may well not be working - the compiler would have every right to replace the whole thing with a NOP (or not even that) - and it almost certainly will if there is any level of optimisation applied. Use the builtin delay functions is you need to.

Yep, you were right. FOSC definition syntax was incorrect, hence that was why I couldn't get the iternal delays working at my first attempt, the loop was supposed to be a temp fix.

AussieSusan wrote:Looking at the trace, the 'EN' signal seems to be triggering too often for the changes in the data lines.

Yes, that's my first thought, I'll be exploring the command order and timings as my next task.

AussieSusan wrote:With an old chip that does not have LAT registers...

Oh, I didn't realise that.

AussieSusan wrote: ...I would certainly NOT be writing to the same register with 1 bit changes the way you are.

Ah well, in my defence its an example that I'm using to get something working and to get to understand how the nitty gritty functions.

AussieSusan wrote: ...Read the register if you need to into a shadow variable, set/clear the bits you need to i that shadow, and then write the shadow out to the port register.
Susan

Ok, I'll look at that when I've worked out what you've said.

Many thanks for your input.

Regards
GB
History teaches us that history doesn't teach us.
User avatar
GettinBetter
 
Posts: 43
Joined: Wed Jun 06, 2018 8:48 pm


Return to 14-Bit Core

Who is online

Users browsing this forum: No registered users and 0 guests

cron