Multisim and Ultiboard

cancel
Showing results for 
Search instead for 
Did you mean: 

Using LCD module in Multisim 10

Guys, I'm having trouble using the 20x2 LCD module. I interfaced it with an 8051 MCU module. And, I use the standard busy flag check(RS = 0, R/W = 1, d7 -> busy flag), but there are two problems:

 

1)  If the LCD is set to trigger on falling edge, the busy check routine goes on an infinite loop,I placed an oscilloscope at d7 and En. Each time there is a falling edge at En, the busy flag (d7) goes to zero(not busy) and immediately comes back to one (busy). This is the case always.

     Is this because there is some other setting to be changed or is the busy fuction not implemented?

 

2)  If the LCD is set to trigger on high state, when one character is sent the entire display gets filled by it and besides, the busy check doesn't iterate even once(Is the simulated LCD so fast that it can process faster than the CPU? wierd)

 

     I tried the same program in UMPS and it works fine. What can I do to make the LCD module work properly?

0 Kudos
Message 1 of 6
(10,898 Views)

I am not going to be able to really answer this question as I have not fooled around with the MCU Module that much. One thing is that you need to post your MS10 File for people to review if that is a possiblitly. Without that it is hard to diagnose any problems.

 

One other thing..There is a sample circuit that uses the 20x4 LCD that you might take a peek at. This uses the PIC as the controller, but you may be able to glean something from that to help you out.

 

That's about all I have, Sorry

Kittmaster's Component Database
http://ni.kittmaster.com

Have a Nice Day
0 Kudos
Message 2 of 6
(10,881 Views)
 I have found a way around the problem, setting the LCD module to trigger on negative edge displays the characters properly ableit the busy check routine can't be used. This I think is a software bug in the LCD module since any LCD device would take a finite time to process data and will indicate 'busy' while at it. All LCD programs that we use with the 8051 uses either a delay or tests for busy condition. The simulated LCD is too fast and the busy flag is not implemented properly i guess. Once the LCD(the real one) is done processing, the busy flag goes low and stays low. Thanks anyways. 🙂
0 Kudos
Message 3 of 6
(10,847 Views)

Hello PCA,

I've been strugling with LCD for some times now. I will be very glad if you could show me what you did with the code, and connectiion.

I'm going to paste the code in C, and the schematic of the circuit. Please tell me what is wrong with what im doind.

The LCD is always blank!

 

Here is my code:



#include <htc.h>
#include <stdio.h>

#define LCD_data P2
#define LCD_D7   P27
#define LCD_rs   P10
#define LCD_rw   P11
#define LCD_en   P12

/*static volatile unsigned char LCD_data @ 0xA0;
static volatile bit LCD_D7   @ 0xA7;
static volatile bit LCD_rs   @ 0x90;
static volatile bit LCD_rw   @ 0x91;
static volatile bit LCD_en   @ 0x92;*/

void LCD_init();
void LCD_busy();
void LCD_command(unsigned char );
void LCD_senddata(unsigned char );
void LCD_sendstring(unsigned char *);


void main()
{
    unsigned char msg[] = "HELLO WORLD";
     LCD_init();
     LCD_command(0x80);
     LCD_sendstring(msg);

    while(1); 
    
}


void LCD_init()
{
     LCD_data = 0x38;     //Function set: 2 Line, 8-bit, 5x7 dots
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command


     LCD_data = 0x0D;     //Display on, Curson blinking command
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command


     LCD_data = 0x01;     //Clear LCD
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command

     LCD_data = 0x06;     //Entry mode, auto increment with no shift
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_busy();

}

void LCD_busy()
{
     LCD_D7   = 1;           //Make D7th bit of LCD as i/p
     LCD_en   = 1;           //Make port pin as o/p
     LCD_rs   = 0;           //Selected command register
     LCD_rw   = 1;           //We are reading
     while(LCD_D7)
    {          //read busy flag again and again till it becomes 0
           LCD_en   = 0;     //Enable H->L
           LCD_en   = 1;
     }

/*unsigned char i,j;

3+69
         for(i=0;i<50;i++)        //A simple for loop for delay
            for(j=0;j<255;j++);*/
}

void LCD_command(unsigned char var)
{
     LCD_data = var;      //Function set: 2 Line, 8-bit, 5x7 dots
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in instruction register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command
}
/* Using the above function is really simple
 var will carry the command for LCD
 e.g.
 LCD_command(0x01);*/


void LCD_senddata(unsigned char var)
{
     LCD_data = var;      //Function set: 2 Line, 8-bit, 5x7 dots
     LCD_rs   = 1;        //Selected data register
     LCD_rw   = 0;        //We are writing
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command
}
/* Using the above function is really simple
 we will pass the character to display as argument to function
 e.g.

 LCD_senddata('A');*/


void LCD_sendstring(unsigned char *var)
{
     while(*var)              //till string ends
       LCD_senddata(*var++);  //send characters one by one
}
/* Using the above function is really simple
// we will pass the string directly to the function
// e.g.
//
// LCD_sendstring("LCD Tutorial");*/

 

 

 

 

0 Kudos
Message 4 of 6
(10,645 Views)

itLike i've said before, the simulation has a bug. In the real thing once the LCD controller has doneits job it sets the busy flag low. But in the sim, it's low only when the en is high regardless of the module being in edge trigger mode. All you have to do to get the LCD working in the sim is to make a small modification in the busy flag check function. Just change the while(busy_flag) to while(1) temporarily. Once you are done with the simulation, before you download it change it back.:-)

 

I haven't seen the circuit. It should be proper. The code WILL run fine on hardware.

Message Edited by PCA on 12-27-2008 07:33 AM
0 Kudos
Message 5 of 6
(10,586 Views)

just delete code to check bit D7(lcd_busy).

 

0 Kudos
Message 6 of 6
(6,988 Views)