0

I want to learn about microchip programming and have downloaded PicsimLab.I am trying to program a PIC18F452 to display the character '0' in the output of a LCD.Here is the picture with the binary functions of my LCD:

I connected the pins like this to the PIC18F452:

Here is my code:

void main() {
TRISD = 0x00;
TRISE = 0x00;
PORTE = 0x00;
PORTD = 0x0E;

delay_ms(500);

while(1)
{
PORTE = 0x05;
PORTD = 0x30;   
delay_ms(500);
PORTE = 0x00;  
delay_ms(500);  
} 

}

I am sending in port E 0x00 and in port B 0x05 to turn on the LCD. Then I send in port E 0x05 to write data to the LCD and in port D my data(the hex value of 0 is 0x30).Then after a delay I send 0x00 in port E to display 0 on my screen but it doesnt. Where am I wrong?

  • 1
    I don't see your code doing the items what you say it does. The only thing it might do is to send a data byte of 0x30, but even that is sent incorrectly. You need to first be able to correct command and data writes on the bus, and then send correct commands to initialize the display to be on, and then finally send the ASCII character 0x30. – Justme Mar 14 '23 at 15:11
  • Maybe you could point to my errors in your answer? – appliedSciences Mar 14 '23 at 15:21
  • 2
    The code does not just have errors, it does not do anything you say it does so it is difficult to point errors in code that does not exist, there are no lines in the code that would do the things you describe. Maybe if you would describe in detail why you think the code does what you say it does, by going through each line of code. It just repeatedly sends a data byte of 0x30 and even that is sent incorrectly by violating the address hold time. – Justme Mar 14 '23 at 15:28
  • You should be able to find various tutorials about using these LCD display modules. Here are a few: https://www.intechopen.com/chapters/80636 | https://stackoverflow.com/questions/20735498/how-to-initialize-4-bit-operation-of-an-lcd | https://electronics.stackexchange.com/questions/5413/power-up-initialization-of-hd44780-lcd-module | https://www.edaboard.com/threads/lcd-interfacing-with-pic18f452.274877/ | https://forum.microchip.com/s/topic/a5C3l000000M8oGEAS/t263924?comment=P-2038936 – PStechPaul Mar 14 '23 at 21:44
  • @appliedSciences - Hi, Please can you add the [required reference link](/help/referencing) (or if you are using a local copy, then give the full title, version etc.) for the datasheet whose extract you've included? Thanks. – SamGibson Mar 15 '23 at 00:01

1 Answers1

2

You appear to be using a 1602 LCD which is sold under many different names. You are not following the timing diagram. The timing diagram shows 5 distinct times where the signals change, I have labeled them A-E.

For some controllers, tAS can be zero, and A and B can be simultaneous. You need to look at the timing diagram for your exact controller. (If you want people to help, you should post this type of information)

E would be the earliest that the next cycle could start. If you are not starting another cycle, you still may want to set all signals to an inactive state. but this is optional.

For D, you must only change the Enable bit, or you will violate the hold on RS and/or RW.

enter image description here

enter image description here

https://focuslcds.com/content/ST7066Uv25.pdf

Above is the datasheet for my controller, it has been cloned by many others (actually this may be a clone), others may be slightly different.

Use good programming practices so people can follow what you did. Define your bits.

My setup has an I2C interface using 4-bit mode on the LCD, so, I am unable to test this. There may be errors, but the general flow should be correct.

// HW Port Bits
#define LCD_EN   0b00000100    // Enable bit
#define LCD_RW   0b00000010    // Read/Write bit
#define LCD_RS   0b00000001    // Register select bit, 0 = Instr, 1 = Data    

// Instruction control bits
#define LCD_INSTR_CLEAR_DISP       0x01
#define LCD_INSTR_RETURN_HOME      0x02
#define LCD_INSTR_ENTRY_MODE_SET   0x04
#define LCD_INSTR_DISP_ON_OFF      0x08
#define LCD_INSTR_CURS_DISP_SHIFT  0x10
#define LCD_INSTR_SET_FUNCT        0x20
#define LCD_INSTR_SET_CGRAPH_ADDR  0x40
#define LCD_INSTR_SET_DATA_ADDR    0x80

// Bit definitions for Display on/off
#define LCD_DISPLAY_ON             0x04
#define LCD_DISPLAY_CURS           0x02
#define LCD_DISPLAY_BLINK          0x01

// Bit definitions for Cursor shift
#define LCD_CURS_SHIFT_RIGHT       0x04

// Bit definitions for Set Function
#define LCD_FUNCTION_8BIT          0x10
#define LCD_FUNCTION_2LINE         0x08
#define LCD_FUNCTION_5x11          0x04

main()
{
   // Setup ports
   TBD

   // Clear display
   WriteLcdInstr( LCD_INSTR_CLEAR_DISP );

   // Display ON
   WriteLcdInstr( LCD_INSTR_DISP_ON_OFF | LCD_DISPLAY_ON );    

   // Write some text
   WriteLcdData( 'H' );
   WriteLcdData( 'e' );
   WriteLcdData( 'l' );
   WriteLcdData( 'l' );
   WriteLcdData( 'o' );
}

WriteLCDInstr( uint8_t u8Instr )
{
    PORTE = LCD_RS;             // A in timing diagram
    delay_us( 1 );
    PORTE = LCD_RS | LCD_EN;    // B in timing diagram
    delay_us( 1 );
    PORTD = u8Instr ;           // C in timing diagram
    delay_us( 1 );
    PORTE = LCD_RS;             // D in timing diagram
    delay_us( 1 );
    PORTE = 0;                  // E in timing diagram
    
    // Longer delay required for some instructions
    if ( u8Instr <= LCD_INSTR_RETURN_HOME )
        delay_us( 1520 ); 
} 

WriteLCDData( uint8_t u8Data )
{
    PORTE = 0;                  // A in timing diagram
    delay_us( 1 );
    PORTE = LCD_EN;             // B in timing diagram
    delay_us( 1 );
    PORTD = u8Data;             // C in timing diagram
    delay_us( 1 );
    PORTE = 0;                  // D in timing diagram
    delay_us( 1 );
                                // E (no change)
} 
Mattman944
  • 13,638
  • 1
  • 19
  • 43
  • Where is it said that Tas can be 0? There is no info which LCD the OP uses. And typically, Tas has been non-zero for most display controllers. I'd be interested to know which display you have with zero Tas? – Justme Mar 14 '23 at 17:50
  • @Justme - I recognize the instruction table, it is from a 1602 LCD. Mine is a Sunfounder brand with a Shenzhen Eone controller. It is sold under many, many different names. With and without an I2C add-on. I have both, but I have never powered up the non-I2C modules. The OP should verify that theirs is the same. I will add the timing table to my answer. – Mattman944 Mar 14 '23 at 19:13
  • I recognize that too - standard HD44780 interface, cloned by dozens of manufacturers with more or less compatible timings. The Shenzen Eone says it uses the ST7066U controller, a Sitronix clone of HD44780. The U model does have zero address setup time. The non-U model doesn't. So it should not be assumed that all displays have zero address setup time, as many displays with a different controller would fail to work. – Justme Mar 14 '23 at 19:24
  • @Justme - Good point on tAS, I updated the answer. The OP could have made this easier by posting the timing diagram and tables, or a link. – Mattman944 Mar 14 '23 at 19:33
  • Also E is not a point for idle. Both points A and E are starts of a cycle. It's just that there must be long enough time between D and E, and between two cycles, A and E. Or rather, points B and F, but E to F would be same as A to B. – Justme Mar 14 '23 at 20:31