Continue to Site

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.

  • 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.

HD44780 and 18f4550 problems

Status
Not open for further replies.
Connected to ground, I can now see black contrast squares.
I still cant get this ******* to work though.
Now im trying to make a crude USB daq to see whats going wrong.
 
HerbertMunch said:
Connected to ground, I can now see black contrast squares.
I still cant get this ******* to work though.
Now im trying to make a crude USB daq to see whats going wrong.

If you can't get an LCD to work, I don't hold out much hope for USB :p

On a scale of 1 to 10, a text LCD is probably 3 or 4?, USB is probably 15 to 20!!!.

Like I've said previously, WIRE A CONTRAST CONTROL UP, get rid of one variable - remove the PIC, adjust the contrast until you get the black squares, then back it off until the black squares are only just visible. At this point you are guaranteed to see something if the display is being fed correctly.

When you refit the PIC and power it up, the faint squares should disappear IF it's been initialised correctly - if they don't, then it's not getting initialised.

How are you building this?, it's not on a breadboard is it?.
 
I purchased a little Microelectronica 4-bit mode LCD adapter board recently ($8 USD) that includes the contrast pot'. I wonder if something like this adapter might help you reduce the number of variables you're trying to work through?


**broken link removed**
 
Nigel, ive got contrast squares; it’s not a breadboard (I posted the board layout above).
I can't add a pot as there’s not enough space on my board, however maximum contrast is being applied as it is tied to ground.

I’ve almost completely ruled out a contrast problem. It’s an init problem. When I turn it on, I can see a row of black squares on the top row. As my init code is working, another row of black squares appears, and then disappears again.
There is something wrong with the init code, as the busy flag never clears.

As for the USB:
I’ve had infinitely more success and have already got the USB speaking to the computer! This is more than I can say about my stupid LCD.
Using the framework, USB seems to be fairly straight forward, apart from many things I don’t quite yet understand, such as interface/endpoint descriptors, etc.

The problem with my LCD is that I can’t see what’s going wrong, and if I could at least rule out another variable (i.e. are pins being set correctly? Not just what ICD2 says about pin states either, but actually physically testing pins) i might be able to crack it.

I understand what your saying about USB being harder to implement, but at least im not still banging my head against a wall, trying in vain to sort out LCD dilemma.

The problem with LCD, is that if it doesnt work, its very difficult to see why its not working. Im not even sure if my LCD is in correct working order.
When i finally get the LCD working, Im going to make a small board and firmware that i can use to test if a LCD works, hence reducing a varaible.

Thanks.
 
Mike said:
I purchased a little Microelectronica 4-bit mode LCD adapter board recently ($8 USD) that includes the contrast pot'. I wonder if something like this adapter might help you reduce the number of variables you're trying to work through?

Sounds good, maybe ill give it a try if i fail to get it working in the next day or so.

Thanks.
 
HerbertMunch said:
The problem with LCD, is that if it doesnt work, its very difficult to see why its not working. Im not even sure if my LCD is in correct working order.
When i finally get the LCD working, Im going to make a small board and firmware that i can use to test if a LCD works, hence reducing a varaible.

Like many such problems, it's difficult to know if it's a hardware problem or a software one - it took me a LONG time to ever get an LCD working, and I wasn't able to find any code that 'just worked'. In the end I wrote my own, based on bits of all sorts of other code - initially 8 bit, when that was fully working I moved to 4 bit, then after that I added reading the busy pin.

So I did it in three separate sections, that way you know what part is duff if it doesn't work after a change - but it's that first 'leap in the dark' that takes some getting.

It's also more difficult because you're using C, so you're not even sure exactly what code you're creating - you might find it helpful to examine the assembler it produces?.
 
Nigel Goodwin said:
Like many such problems, it's difficult to know if it's a hardware problem or a software one - it took me a LONG time to ever get an LCD working, and I wasn't able to find any code that 'just worked'. In the end I wrote my own, based on bits of all sorts of other code - initially 8 bit, when that was fully working I moved to 4 bit, then after that I added reading the busy pin.

So I did it in three separate sections, that way you know what part is duff if it doesn't work after a change - but it's that first 'leap in the dark' that takes some getting.

It's also more difficult because you're using C, so you're not even sure exactly what code you're creating - you might find it helpful to examine the assembler it produces?.

Well at least its not just me then! I personally find getting this sodding lcd working to be the most frustrating thing that Ive done, in my short electronics 'career':D .

Ive done LCD twice now, once in c, once in asm. Both times must have reduced my life considerably! :mad:

I'll have a look at the asm its producing as you suggest, to try and get to the bottom of the problem.

Thanks Nigel.
 
Pommie said:
Regarding 4/8 bit, it makes no difference, the display hasn't been informed if the interface is 4 or 8 bit and therefore it ignores the bottom 4 bits.
Wrong again :)
After power up the controller is set up for 8 bit mode and 1 line display.
The 4 bottom bits aren't ignored that way!
That's why you don't need the 3 times 0x30 when you intend to use the display in 8 bit mode.
You can start directly with the "Function set" byte to set the number of lines and font (DB4 = 1 of course).

@Mike, K8LH
The 4 unused bits, are they tied to ground on the board?
I once read that this isn't good practice since those pins can be shortened under certain circumstances. Better was to use a 10k pull down resistor. I will try to find it back and post it here...
 
HerbertMunch said:
Well at least its not just me then! I personally find getting this sodding lcd working to be the most frustrating thing that Ive done, in my short electronics 'career':D .

Ive done LCD twice now, once in c, once in asm. Both times must have reduced my life considerably!
LCDs can be tricky. They're simple, but the tiniest thing wrong and nothing happens. You can be "right there", but with that one little thing that's off it won't work. Then what happens is you start chasing what you think is the problem instead of what the actual problem was.

Really go through that init sequence over and over. Getting that right is critical. I can send you some working 4550 (at 20MHz) asm code for both 4-bit and 8-bit if it'll help.
 
Last edited:
Your write LCD is oring the bits in and so the previous nibble is still present. Also, you don't always clear RW.

Try
Code:
void SendLCD(byte message)
{
	//Send high nibble first
	LCD_RW=0;
	LCDPORT = (LCDPORT & 0x0f) | (message & 0xF0);
	PulseE();
	LCDPORT = (LCDPORT & 0x0f) | (message<<4) & 0xf0;
	PulseE();
}

I notice also that you write to the port rather than the latch. Try changing
#define LCD_RS PORTDbits.RD0
to
#define LCD_RS LATDbits.LATD0
etc.
You should leave LCD_BUSY pointing to the PORT.

Added, Your LCD busy isn't setting enable. Try,
Code:
int LCDBusy(void)
{
	int result=0;
	LCD_TRIS_BUSY = 1; //set pin to input
	LCD_RS = 0;
	LCD_RW = 1;
	LCD_E=1;
	result = (LCDPORT & 0x80) ? 1: 0;
	LCD_E=0;
	LCD_TRIS_BUSY = 0; //Set pin to output
	return result;
}

Mike.
 
Last edited:
Herbert,
I took the liberty of hacking your code so that it will work on a Unicorn board. If you change the port assignments then it should work on your circuit.

Mike.
edit, tidied the code format and fixed a typo (bug).
Code:
#pragma config WDT = OFF, LVP = OFF, FOSC = HS

#define byte unsigned char

#define LCDPORT LATD
#define LCDTRIS TRISD
#define LCD_RS LATEbits.LATE0
#define LCD_TRIS_RS TRISEbits.TRISE0
#define LCD_RW LATEbits.LATE1
#define LCD_TRIS_RW TRISEbits.TRISE1
#define LCD_E LATEbits.LATE2
#define LCD_TRIS_E TRISEbits.TRISE2
#define LCD_BUSY PORTDbits.RD7
#define LCD_TRIS_BUSY TRISDbits.TRISD7


void Delay(int);
void PulseE(void);
void SendCommand(byte);
void SendCharacter(char);
void SendCmdNibble(byte);
void WaitLCDBusy(void);
void SendLCD(byte);
void OpenLCD(void);

void main(void){
int i;
    OpenLCD();
    SendCharacter('H');
    SendCharacter('e');
    SendCharacter('l');
    SendCharacter('l');
    SendCharacter('o');
    SendCharacter(' ');
    SendCharacter('W');
    SendCharacter('o');
    SendCharacter('r');
    SendCharacter('l');
    SendCharacter('d');
    SendCharacter('!');
    while(1);
}

//Initialises the display
void OpenLCD(void){
    //Make port outputs
    LCDTRIS = 0x0F;
    LCD_E=0;
    LCD_TRIS_E=0;
    LCD_TRIS_RS=0;
    LCD_TRIS_RW=0;
    //Wait for display
    Delay(30);
    //Send 0x30
    SendCmdNibble(0x30);
    Delay(5);
    SendCmdNibble(0x30);
    Delay(1);
    SendCommand(0x20);
    SendCommand(0x2c);
    SendCommand(0x08);
    SendCommand(0x01);    
    SendCommand(0x06);
    SendCommand(0x0C);
}

void SendCmdNibble(byte command){
    LCD_RS = 0;
    LCD_RW=0;
    LCDPORT &= 0x0f;
    LCDPORT |= (command & 0xf0);
    PulseE();
}

void WaitLCDBusy(void){
    LCD_TRIS_BUSY = 1; //set pin to input
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_E=1;
    while(LCD_BUSY);
    LCD_E=0;
    LCD_TRIS_BUSY = 0; //Set pin to output
}

void SendCommand(byte command){
    //setup to send command
    WaitLCDBusy();
    LCD_RS = 0;
    SendLCD(command);
}

//Sends a character to the LCD
void SendCharacter(char chr){
    WaitLCDBusy();
    LCD_RS = 1;//Setup to send character
    SendLCD((byte) chr );
}

//Sends message/command to lcd. Requires the RS line to be set appropriately
void SendLCD(byte message){
    //Send high nibble first
    LCD_RW=0;
    LCDPORT = (LCDPORT & 0x0f) | (message & 0xF0);
    PulseE();
    LCDPORT = (LCDPORT & 0x0f) | (message<<4 & 0xf0);
    PulseE();
}

void PulseE(void){
    LCD_E = 1;
    LCD_E = 0;
}

void Delay(int Time){
// delay mS at 20MHz
int i,j;
    for(j=0;j<Time;j++){
        for(i=0;i<275;i++);
    }
}
 
Last edited:
Thanks everyone for the help, I really appreciate it.

I’m not in any state to be fiddling with LCD at the moment, but ill give the code a go tommorow (today) after I wake up.

Cheers,
chris.
 
Pommie said:
Code:
void Delay(int Time){
// delay mS at 20MHz
int i,j;
    for(j=0;j<Time;j++){
        for(i=0;i<275;i++);
    }
}
My delay code was a crude behemoth:eek: !

With the frustration of the LCD, nice code goes out the window, and in comes the messy stuff. Its this mess that i create, that hinders me further.

Cheers
 
Last edited:
Pommie your a wonderful man, not to mention a genius!
It works! HURRAH!

You have saved me from making myself bald at 22!

Id give your post reputation, but it wont let me until I have 'Spread some reputation around' apparently!
Anyway thanks again,
chris.
 
Good to hear it's finally working. Now you can do the nice easy bit of getting it to work with USB.:eek: :eek:

Mike.
 
Unfortunately, I’m still not finished with the dreaded LCD. I’m not going to able to move onto something else until I have coded working lcd routines from the ground up. Now i have some working code though, the job should be trivial.

After the hardware variable is ruled out, its much easier to see where you're going wrong.

Thanks
 
Last edited:
Do you mind sending me your working code, I have pic18f4550 prototype board & some 20pin LCD (tempone@kingstardia.com) best regards.
 
hi, the code is allready included in this post! Pommie was kind enough to provide me with his code.

All you need to do it set it up to use the ports you have connected (or intend to connect)
 
Lcd

Yes, I have tried this code on my prototype of pic18f4550 but could not get it to work, my lcd is 20pin (DV-20208 kind it does not have pin for BUSY), I used port D (D6,D7,D8 pn pic) for control (RS, RW, EN on lcd) and used four pins from Port B (B4,B5,B6,B7) for (D4,D5,D6, D7 of lcd), pin lcd negative 5v and 2 positive, I replaced the Busy line on code with some ms delay and no luck to get anything on th escreen. Do you have any idea please of what could be wrong?
 
Status
Not open for further replies.

Latest threads

Back
Top