Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] PIC24 with 20x4 Winstar LCD display problem

Status
Not open for further replies.

bicibici1

Newbie level 4
Joined
Nov 6, 2009
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
United Kingdom
Activity points
1,335
Hi everyone, I have a problem regarding my design. I have recently designed a development board (similar to Explorer 16) using the bits and pieces of Explorer 16 schematic. As I couldn't find the LCD used on the Explorer 16 kit or the Microchip suggested LCDs I went for the 20x4 Winstar 2004a Alphanumeric LCD display. After a long debugging process I have tried to get something on the LCD. I have used the schematic from Explorer 16 user guide which is below. On the LCD datasheet I see that this is correct. So it looks like I have no problem with the hardware.

View attachment LCD module.bmp

I have than added a variable resistor to the pin 3 o adjust the contrast which is fine. When I power up the PCB I see black rectangles on 1st and 3rd line which is I believe how it is supposed to be. I have been trying the code below. I tried the same code on an actual Explorer 16 board and it works but when I try it on my board, the rectangles disappear and nothing comes up on the display. I tried debuggng it using Mplab and looks like it initialises it and completes the code but than I still cant see anything on the display. I have no idea what the problem is. I know the addresses on 2 line LCD and 4line LCD are different but there should still be things visible somewhere on the display right? Any suggestions would be amazing. Here is the code I am using and again this works on 16x2 LCD on Explorer 16 board.

Code:
#include <p24Fxxxx.h>

#if defined( __PIC24FJ256GB110__ ) || defined( __PIC24FJ256GB106__ )
#define PLL_96MHZ_ON    0xF7FF
_CONFIG1(ICS_PGx2 & JTAGEN_OFF & FWDTEN_OFF)        // JTAG off, watchdog timer off
_CONFIG2( FNOSC_PRIPLL & PLL_96MHZ_ON & PLLDIV_DIV2 & OSCIOFNC_OFF & FCKSM_CSDCMD & POSCMOD_XT)
#else                   // PIC24FJ128GA010 and PIC24FJ256GA110
_CONFIG1( ICS_PGx2 & JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF) 
_CONFIG2( FNOSC_PRIPLL & OSCIOFNC_OFF & FCKSM_CSDCMD & POSCMOD_HS)
#endif

#define LCDDATA 1
#define LCDCMD  0
#define PMDATA  PMDIN1

void initLCD( void)
{
    // PMP initialization 
    PMCON = 0x83BF;             // Enable the PMP, long waits
    PMMODE = 0x3FF;             // Master Mode 1
	PMAEN = 0x0001;             // PMA0 enabled


    
    // init TMR1
    T1CON = 0x8030;             // Fosc/2, prescaled 1:256, 16us/tick

    // wait for >30ms
    TMR1 = 0; while( TMR1<2000);// 2000 x 16us = 32ms   
    
    //initiate the HD44780 display 8-bit init sequence
    PMADDR = LCDCMD;            // command register
    PMDATA = 0b00111000;        // 8-bit interface, 2 lines, 5x7
    TMR1 = 0; while( TMR1<3);   // 3 x 16us = 48us   
    
    PMDATA = 0b00001100;        // display ON, cursor off, blink off
    TMR1 = 0; while( TMR1<3);   // 3 x 16us = 48us   
    
    PMDATA = 0b00000001;        // clear display
    TMR1 = 0; while( TMR1<100); // 100 x 16us = 1.6ms   
    
    PMDATA = 0b00000110;        // increment cursor, no shift
    TMR1 = 0; while( TMR1<100); // 100 x 16us = 1.6ms   
} // initLCD


char readLCD( int addr)
{
    int dummy;
    while( PMMODEbits.BUSY);    // wait for PMP to be available
    PMADDR = addr;              // select the command address
    dummy = PMDATA;            // initiate a read cycle, dummy read
    while( PMMODEbits.BUSY);    // wait for PMP to be available
    return( PMDATA);            // read the status register
    
} // readLCD

#define busyLCD() readLCD( LCDCMD) & 0x80
#define addrLCD() readLCD( LCDCMD) & 0x7F
#define getLCD()  readLCD( LCDDATA)


void writeLCD( int addr, char c)    
{
    while( busyLCD());
    while( PMMODEbits.BUSY);    // wait for PMP to be available
    PMADDR = addr;
    PMDATA = c;
} // writeLCD
    

#define putLCD( d)  writeLCD( LCDDATA, (d))
#define cmdLCD( c)  writeLCD( LCDCMD, (c))

#define homeLCD()   writeLCD( LCDCMD, 2)    
#define clrLCD()    writeLCD( LCDCMD, 1)
#define setLCDG( a) writeLCD( LCDCMD, (a & 0x3F) | 0x40)
#define setLCDC( a) writeLCD( LCDCMD, (a & 0x7F) | 0x80)

void putsLCD( char *s)
{
    while( *s) putLCD( *s++);
} //putsLCD



main( void)
{
    int i;
        
    // initializations
    initLCD();


    putsLCD( "Why is\n");
    putsLCD( "my LCD\n");
    putsLCD( "not working???\n");



} // main
 

Most 4 lines alphanumeric displays are using the same controllers and work in the same mode as a 2-lines display. Typically the third line directly continues the first line. So seeing first and third line activated refers to uninitialized single line controller mode.

You should of course consult the datasheet of your display for details, but most likely there aren't much differences to the standard Explorer16 display, except for having two lines of virtually 40 characters.
 

I tried consulting the datasheet but it is no help. It only bits and pieces copied and pasted from HD44780 datasheet. So you think there is a problm with the LCD itself? I mean do you think its burnt or something? How can I make sure the LCD as a hardware is performing as it should? I have read somewhere that if, after initialization, those black rectangles disappear, it means that it has initialized correctly. is that correct?

Thanks for your help and feedback

---------- Post added at 18:34 ---------- Previous post was at 18:14 ----------

i would just like to add that the Explorer 16 datasheet mentions that the PIC24 is only compatiable with HD44780 controllers but my LCD has a ks0066 controller. I have read in many forums that these two are identical. do you think that as a role in malfunctioning of the LCD?

Thanks
 

As far as I know, all LCD character displays on the market are compatible with HD44780.

I would expect a wiring problem of your design. It would be good to verify the correct operation of each processor IO line connected to the display before starting to guess about damaged display.
 

I have checked the connectivity of the wires on the PCB. They are nicely seperated so no short circuit and they are all connected to the ports. I can see that it is receiving a command but thats about it. After
Code:
PMDATA = 0b00111000;        // 8-bit interface, 2 lines, 5x7
is being sent the rectangles disappear and seems to be initialising. If the connectivity was bad the command wouldnt also be received right? However, when the command is being sent to the port, what should the voltage reading be at the pins? is it 3.3V(PIC) or 5V(LCD input voltage) or something lower?
 

The I/O lines will show 3.3 V logic level, when driven by the PIC. When reading data from the display (at least the busy bit), the level should rise to display VCC.
 

Ok, it turns out the problem was something very idiotic. Between the track and the pins 98-99-100 of the PIC24 there was a microscopic gap. i just gave some heat to it and its working perfectly now. Ive spend over 1 week to find this stupid problem. If anyone else is also having problems with LCDs with KS0066 controller, I can confirm that they are fully compatible with Explorer16, PIC...etc. KS0066 and HD44780 turns out to be exactly the same apart from a couple of extra steps in the initialization stage. Code is below if anyone is interested. This is a code for Winstar WH2004a 20x4 LCD interface and application for PIC24FJ128GA010 Developent board.

Heres the configurations bits setup in MPLab, if you prefer coding, u can uncomment the relevant config1 and config 2 lines in the code (uncomment the ones after "else" for PIC24FJ128GA010).

config bits.jpg

Heres the code in C

Code:
/*
**
** Bugra Ergin
*/

#include <p24Fxxxx.h>

#if defined( __PIC24FJ256GB110__ ) || defined( __PIC24FJ256GB106__ )
#define PLL_96MHZ_ON    0xF7FF
//_CONFIG1(ICS_PGx2 & JTAGEN_OFF & FWDTEN_OFF)        // JTAG off, watchdog timer off
//_CONFIG2( FNOSC_PRIPLL & PLL_96MHZ_ON & PLLDIV_DIV2 & OSCIOFNC_OFF & FCKSM_CSDCMD & POSCMOD_XT)
#else                   // PIC24FJ128GA010 and PIC24FJ256GA110
//_CONFIG1( ICS_PGx2 & JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF) 
//_CONFIG2( FNOSC_PRIPLL & OSCIOFNC_OFF & FCKSM_CSDCMD & POSCMOD_HS)
#endif

#define LCDDATA 1
#define LCDCMD  0
#define PMDATA  PMDIN1

void initLCD( void)
{
    // PMP initialization 
    PMCON = 0x83BF;             // Enable the PMP, long waits
    PMMODE = 0x3FF;             // Master Mode 1
             
    PMAEN = 0x0001;           // PMA0 enabled
    
    // init TMR1
    T1CON = 0x8030;             // Fosc/2, prescaled 1:256, 16us/tick

    // wait for >30ms
    TMR1 = 0; while( TMR1<2700);// 2700 x 16us = ~42ms   
    
    //initiate the KS0066 display 8-bit init sequence
    PMADDR = LCDCMD;            // command register
    PMDATA = 0b00111100;        // 8-bit interface, 4 lines, 5x8
    TMR1 = 0; while( TMR1<3);   // 3 x 16us = 48us   
    
    PMDATA = 0b00111100;        // 8-bit interface, 8 lines, 5x8  - again
    TMR1 = 0; while( TMR1<3);   // 3 x 16us = 48us 
    
    
    PMDATA = 0b00001100;        // display ON, cursor off, blink off
    TMR1 = 0; while( TMR1<3);   // 3 x 16us = 48us   
    
    PMDATA = 0b00000001;        // clear display
    TMR1 = 0; while( TMR1<100); // 100 x 16us = 1.6ms   
    
    PMDATA = 0b00000110;        // increment cursor, no shift
    TMR1 = 0; while( TMR1<100); // 100 x 16us = 1.6ms   
} // initLCD

char readLCD( int addr)
{
    int dummy;
    while( PMMODEbits.BUSY);    // wait for PMP to be available
    PMADDR = addr;              // select the command address
    dummy = PMDATA;            // initiate a read cycle, dummy read
    while( PMMODEbits.BUSY);    // wait for PMP to be available
    return( PMDATA);            // read the status register
    
} // readLCD

#define busyLCD() readLCD( LCDCMD) & 0x80
#define addrLCD() readLCD( LCDCMD) & 0x7F
#define getLCD()  readLCD( LCDDATA)


void writeLCD( int addr, char c)    
{
    while( busyLCD());
    while( PMMODEbits.BUSY);    // wait for PMP to be available
    PMADDR = addr;
    PMDATA = c;
} // writeLCD
    
#define putLCD( d)  writeLCD( LCDDATA, (d))
#define cmdLCD( c)  writeLCD( LCDCMD, (c))

#define homeLCD()   writeLCD( LCDCMD, 2)    
#define clrLCD()    writeLCD( LCDCMD, 1)
#define setLCDG( a) writeLCD( LCDCMD, (a & 0x3F) | 0x40)
#define setLCDC( a) writeLCD( LCDCMD, (a & 0x7F) | 0x80)


void putsLCD( char *s)
{
    while( *s) putLCD( *s++);
} //putsLCD

main( void)
{

    // initializations
    initLCD();
    
    // put a title on the first line 
     
    putsLCD( "First line");
    setLCDC(0x40);
    putsLCD( "Second line");
    setLCDC(0x14);
    putsLCD( "third line");
    setLCDC(0x54);
    putsLCD( "fourth line");

} // main
 

Between the track and the pins 98-99-100 of the PIC24 there was a microscopic gap.
But the problem shows in complete I/O-test, isn't it? Anyway, good to have it solved.
 

well i was sending a couple of test commands and testing the first couple of pins and asuming its fine. i than tracked the lines for connectivity it was fine, the problem was at the very legs of the micro - so note to myself, make sure verything is connected before going crazy.. thanks for your suggestions anyway :)
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top