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.

LCD 4-bit initializations

Status
Not open for further replies.

Djsarkar

Member level 3
Member level 3
Joined
Jul 27, 2020
Messages
55
Helped
0
Reputation
0
Reaction score
1
Trophy points
8
Activity points
301
Hi,

I am looking help to understand datasheet https://www.sparkfun.com/datasheets/LCD/HD44780.pdf

Let's consider for following connection

PORT D7 - LCD Data pin 7
PORT D6 - LCD Data pin 6
PORT D5 - LCD Data pin 5
PORT D4 - LCD Data pin 4

PORT RC6 - EN
PORT RC5 - RW
PORT RC4 - RS

page 45, figure 24

Power ON
Wait 40ms
PORTD = 0b0011

Should I send only 4 bit data at time ? or should I send in upper and lower nibble ?
 
Last edited by a moderator:

Hi,
Should I send only 4 bit data at time ? or should I send in upper and lower nibble ?
What´s the difference? Your headline says "4 bit initialisation"
I assume I don´t understand what the question/problem is. Please explain.

btw: There are probably millions of informations (documents, code, schematics, videos...) in the internet how to set up a display for/in 4 bit mode..

Klaus
 

Hi,

What´s the difference? Your headline says "4 bit initialisation"
I assume I don´t understand what the question/problem is. Please explain.

btw: There are probably millions of informations (documents, code, schematics, videos...) in the internet how to set up a display for/in 4 bit mode..

Klaus

I want to use 4 bit interface. I am trying to understand diagram given in page 46 figure 24

Power ON
RS = 0; RW = 0;
Wait 40ms

PORTD =

What would be the sequence to send below 4 bit data ?



4 bit LCD.jpg
 

Hi,

from your post:
PORT D7 - LCD Data pin 7
PORT D6 - LCD Data pin 6
PORT D5 - LCD Data pin 5
PORT D4 - LCD Data pin 4
generally: PortD = PD7 | PD6 | PD5 | PD4 | PD3 | PD2 | PD1 | PD0
from the display´s view: DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0

you used D4...D7 thus just the blue marked ones

so if you want DB7...DB4 to be "0011" then
from the display´s view: 0 | 0 | 1 | 1 | x | x | x | x
PortD = 0 | 0 | 1 | 1 | PD3 | PD2 | PD1 | PD0
where "x" means "don´t care". (For details read the datasheet.)
nobody knows what you did connect to PD0 ... PD3 (as always: a schematic usually is essential for such questions), thus neither one of us, nor the display datasheet can tell what should be the values for it.

--> thus lets use "u" for unchanged". RMW: Read state, Modfiy the (used) bits as you like, Write PortD
PortD = 0 | 0 | 1 | 1 | u | u | u | u

Klaus
--- Updated ---

Added:
Power ON
RS = 0; RW = 0;
Wait 40ms

PORTD =
is not according the datasheet.
do this:
* Power ON
* Wait 40ms
* RS = 0; RW = 0; PORTD =0b0011uuuu
* ...

Klaus
 
The 4-bit initialisation scheme expects that D0-D3 are unconnected, respectively have undefined logic level.

One line in the diagram means exactly one write access. If the command involves two nibbles, two lines are shown (farther low in the diagram).
--- Updated ---

I have noticed that at starting there is one instruction in one box and after some sequence there is two instruction in one box

I don't know what that indicates ?
What I said before, these instructions are sent as two nibbles. That's the normal operation in 4-bit mode. Once the interface has been conclusively set to 4-bit mode, you are starting to send regular commands, which consist always of two nibbles.
 
Last edited:

    Djsarkar

    Points: 2
    Helpful Answer Positive Rating
What I said before, these instructions are sent as two nibbles. That's the normal operation in 4-bit mode. Once the interface has been conclusively set to 4-bit mode, you are starting to send regular commands, which consist always of two nibbles.

How to send two nibble data in LCD_WriteCmd(unsigned char comman) function ?

C:
#define _XTAL_FREQ 8000000
#include <xc.h>
// PIC18F45K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF       // Extended Instruction Set (Enabled)
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS  // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 06000-07FFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)

#define RS            LATCbits.LATC4
#define RW            LATCbits.LATC5
#define EN            LATCbits.LATC6

#define LCD_Port      LATD

void Port_Initialized (void)
{
    LATA = LATB = LATC = LATD = LATE =  0;
    TRISA = 0b0000000;// all are output, Unused
    TRISB = 0b0000000;// all are output, Unused
    TRISC = 0b0000000;// RS RW EN
    TRISD = 0b0000000;//  LCD
    TRISE = 0b0000000;// All are output, Unused

    ANCON0 = 0; // digital port
    ANCON1 = 0; // digital port
    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
}

void LCD_E_Pulse(void)
{
    EN = 1;
    __delay_us(4);
    EN = 0;
    __delay_us(4);
}

void LCD_WriteCmd(unsigned char command)
{
    RS = 0; RW = 0;
    LCD_Port = data & 0xF0 ;  // send upper nibble
    LCD_E_Pulse();
    
}

void LCD_WriteData(unsigned char data)
{
    

}


void LCD_Init(void)
{
    __delay_ms(40);
    LCD_WriteCmd(0x30); //Function set
    __delay_ms(5);
    LCD_WriteCmd(0x30);  //Function set
    __delay_us(100);
    LCD_WriteCmd(0x30);  ////Function set
    
    LCD_WriteCmd(0x20);  // 4 bit long 
   
}

void main ()
{
    Port_Initialized();
    
     while (1)
     {

    
     }
}
 

Hi,

doesn´t look bad ... although I didn´t check thoroughly.

so now you need to follow datasheet sections
* Interfacing to the MPU
* Interfacing to a 4-bit MPU

read through the documents that already exist in the internet. Watch videos.

Then show us your idea, so we can discuss about it.

Klaus
 
Hi,

doesn´t look bad ... although I didn´t check thoroughly.

so now you need to follow datasheet sections
* Interfacing to the MPU
* Interfacing to a 4-bit MPU

read through the documents that already exist in the internet. Watch videos.

Then show us your idea, so we can discuss about it.

Klaus
I am struggling with two function in my code

Code:
void LCD_WriteCmd(unsigned char command)
{
    RS = 0; RW = 0;
    LCD_Port = data & 0xF0 ;  // send upper nibble
    LCD_E_Pulse();
    
}

void LCD_Init(void)
{
    __delay_ms(40);
    LCD_WriteCmd(0x30); //Function set
    __delay_ms(5);
    LCD_WriteCmd(0x30);  //Function set
    __delay_us(100);
    LCD_WriteCmd(0x30);  ////Function set
    
    LCD_WriteCmd(0x20);  // 4 bit long
  
}

LCD_Port = data & 0xF0 ; // send upper nibble
LCD_Port = (data << 4 ) & 0xF0 ; // send lower nibble

4 bit LCD.jpg


I am trying to fix below two functions to initialize LCD in 4 bit mode
 

Hi,
LCD_Port = data & 0xF0 ; // send upper nibble
so far so good. you mask your data with 0xF= and ouput it as HIGH nibble.

Code:
data:  D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0
mask:   1 |  1 |  1 |  1 |  0 |  0 |  0 |  0 
makes: D7 | D6 | D5 | D4 |  0 |  0 |  0 |  0 = higher nibble

then: LCD_Port = (data << 4 ) & 0xF0 ; // send lower nibble

Code:
data:  D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0
shifted four bits left. (zeros in)
data:  D3 | D2 | D1 | D0 |  0 |  0 |  0 |  0 = lower nibble
You see: no need to mask with "0xF0". you may omit it.

Klaus
 

Hi,

so far so good. you mask your data with 0xF= and ouput it as HIGH nibble.

You see: no need to mask with "0xF0". you may omit it.

Klaus
Here is my complete code. LCD is not showing data as expected . What's wrong with program?

C:
#define _XTAL_FREQ 8000000
#include <xc.h>
// PIC18F45K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF       // Extended Instruction Set (Enabled)
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS  // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 06000-07FFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)

#define RS            LATCbits.LATC4
#define RW            LATCbits.LATC5
#define EN            LATCbits.LATC6

#define LCD_Port      LATD

void Port_Initialized (void)
{
    LATA = LATB = LATC = LATD = LATE =  0;
    TRISA = 0b0000000;// all are output, Unused
    TRISB = 0b0000000;// all are output, Unused
    TRISC = 0b0000000;// RS RW EN
    TRISD = 0b0000000;//  LCD
    TRISE = 0b0000000;// All are output, Unused

    ANCON0 = 0; // digital port
    ANCON1 = 0; // digital port
    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
}

void LCD_E_Pulse(void)
{
    EN = 1;
    __delay_us(4);
    EN = 0;
    __delay_us(4);
}

void LCD_WriteCmd(unsigned char data)
{

    RS = 0; RW = 0;
    LCD_Port = data & 0xF0 ;  // send upper nibble
    LCD_E_Pulse();
    LCD_Port = (data << 4 );
    LCD_E_Pulse();
 
}


void LCD_Init(void)
{
    __delay_ms(40);
    LCD_WriteCmd(0x30); //Function set 00110000
    __delay_ms(5);
    LCD_WriteCmd(0x30);  //Function set 00110000
    __delay_us(100);
    LCD_WriteCmd(0x30);  ////Function set 00110000
 
    LCD_WriteCmd(0x20);  // 4 bit  00100000
    LCD_WriteCmd(0x0C);  // Display ON

    LCD_WriteCmd(0x2C);  // 4 bit, 1-line display  5 × 8 dot character font 00101100
    LCD_WriteCmd(0x08);  //  clear display 00001000
 
}

void LCD_WriteData(unsigned char data)
{
 
   RS = 1;  // select Data register
   RW = 0 ;  // write mode

    LCD_Port = data & 0xF0 ;  // send upper nibble
    LCD_E_Pulse();
    LCD_Port = (data << 4 );  // send lower nibble
    LCD_E_Pulse();
}

void buffer( unsigned char *p)
{

    while (*p != '\0')
    {
      LCD_WriteData(*p);

        p++;
    }
}
void main ()
{
    unsigned int i = 0;
    unsigned char Data1 []={"EDA Board"};
    Port_Initialized();
    LCD_Init();
    buffer(Data1);

    while (1)
    {


     }
}



IMG_20201010_021433.jpg
 
Last edited:

Almost there....

Your problem is you do not have a delay between each character being written to the LCD. Understand that inside the LCD module there is another MCU and it runs at quite low speed. Your MCU runs MUCH faster so you have to be careful not to 'overfeed it'. There are two ways to do that, the fastest is to read the status bit back from the LCD (RW = 1 then read the data lines) or you can use the easier but possibly slower way of just adding a short delay after sending each character.

Brian.
 
Hi,

And as FvM already pointed out there are 4-bit commands for the initialisation and there are 8 bit commands --> "two lines".

Klaus
 

Almost there....

Your problem is you do not have a delay between each character being written to the LCD. Understand that inside the LCD module there is another MCU and it runs at quite low speed. Your MCU runs MUCH faster so you have to be careful not to 'overfeed it'. There are two ways to do that, the fastest is to read the status bit back from the LCD (RW = 1 then read the data lines) or you can use the easier but possibly slower way of just adding a short delay after sending each character.

Brian.
Hi Brian I have added delay in function but still I am not getting data as expected

Code:
void LCD_WriteCmd(unsigned char data)
{

    RS = 0; RW = 0;
    LCD_Port = data & 0xF0 ;  // send upper nibble
    LCD_E_Pulse();
     __delay_ms(40);
    LCD_Port = (data << 4 );  // send lower nibble
    LCD_E_Pulse();
 
}
 

hello,

it could work ,if you add Positionning and additional Delay
i tested it ,but with my LCD wired on RB0..RB3
so modified a litle bit the function to be compliant with this.
my LCD is a 2x16 chars on a Microchip Irda Board demo
18F47K42 MCU at 64MHz
MikroC 7.60 (not MPLABX!)


Code:
sbit LCD_D7 at LATB3_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D4 at LATB0_bit


void LCD_E_Pulse(void)
{
    EN = 1;
    Delay_us(5);
    EN = 0;
    Delay_us(5);
}

void LCD_WriteCmd(unsigned char dat2)
{

    RS = 0;
    Delay_us(5);
    RW = 0;
    Delay_us(5);
  //  LCD_Port = data & 0xF0 ;  // send upper nibble
    LCD_Port = dat2 >> 4 ;
    LCD_E_Pulse();
//   LCD_Port = (data << 4 );
    LCD_Port = dat2 & 0x0F ;
    LCD_E_Pulse();

}

void LCD_WriteData(unsigned char dat)
{

   RS = 1;  // select Data register
   Delay_us(10);
   RW = 0 ;  // write mode

    LCD_Port = dat >> 4;  // send upper nibble
    LCD_E_Pulse();
    LCD_Port = (dat & 0x0F );  // send lower nibble
    LCD_E_Pulse();

  //LCD_Port = dat & 0xF0 ;  // send upper nibble
  //LCD_E_Pulse();
  //LCD_Port = (dat << 4 );  // send lower nibble
  //LCD_E_Pulse();
}

void bufferx( unsigned char *px)
{

    while (*(px)>0)
    {
      LCD_WriteData(*(px));
        px++;
        Delay_ms(1);
    }
}
void LCD_Init2(void)
{
    Delay_ms(40);
    LCD_WriteCmd(0x30); //Function set 00110000
    Delay_ms(25);
    LCD_WriteCmd(0x30);  //Function set 00110000
     Delay_ms(25);
    LCD_WriteCmd(0x30);  ////Function set 00110000
     Delay_ms(25);
    LCD_WriteCmd(0x20);  // 4 bit  00100000
    LCD_WriteCmd(0x28);  // 4 bit, 2-line display  5 × 8 dot character font 00101100

    LCD_WriteCmd(0x0C);  // Display ON
    LCD_WriteCmd(0x08);  //  clear display 00001000
    LCD_WriteCmd(0x0F);  //   <--- added  after completly removing  mikroE LCD library


}

void main()
{
     init   Hardware and UART ......etc ......
 
    CPrint1(" test2 with independant LCD software\r\n");
    LCD_Init2();
    Delay_ms(10);
    do
    {
    LCD_WriteCmd(_LCD_CLEAR);// =1
    Delay_ms(10);
    LCD_WriteCmd(128); //_LCD_FIRST_ROW;
    Delay_ms(10);
    strcpy(CRam1,"Test2 New LCD  ");
    bufferx(CRam1);
     Delay_ms(3000);
    LCD_WriteCmd (192); // _LCD_SECOND_ROW);
     Delay_ms(10);
    strcpy(CRam1,"EDA Board 2    ");
    bufferx(CRam1);
    Delay_ms(3000);
    }
    while(1);
 
Last edited:
  • Like
Reactions: Eric_O

    Eric_O

    Points: 2
    Helpful Answer Positive Rating
You put the delay in the wrong place! The timing the 'E' signal was fine but you need a delay between sending one character and the next.
Code:
void buffer( unsigned char *p)
{

    while (*p != '\0')
    {
      LCD_WriteData(*p);
     Delay_ms(1);     // you can probably make this shorter
        p++;
    }
}

Remember each character needs two write operations, you put the delay between writing the first and second half instead of between complete characters.

Brian.
 

LCD_WriteData(*p);
send the 2 half of the character !
and delay 1ms between each char

i added
LCD_WriteCmd(0x0F); //
at the end of LCD_Init2();
to be able to remove all the LCD MikroE library ( LCD not checked)
 
Last edited:

You should have a LCD_Write_CmdNibble() function for the first initialisation steps.

A question not yet addressed, what's connected to the lower 4 bits of Port D (LCD_Port)? People use 4-Bit mode to save GPIO lines for other purposes, if this is the case in your application, the lower bits must be masked out in writes to Port D. Otherwise, if the bits are unused, why don't you use it t odrive the LCD module in 8-bit mode?
 
You should have a LCD_Write_CmdNibble() function for the first initialisation steps.

A question not yet addressed, what's connected to the lower 4 bits of Port D (LCD_Port)? People use 4-Bit mode to save GPIO lines for other purposes, if this is the case in your application, the lower bits must be masked out in writes to Port D. Otherwise, if the bits are unused, why don't you use it t odrive the LCD module in 8-bit mode?

I want to save pins. I want to save GPIO lines for array of switch buttons

PORT D7 - LCD Data pin 7
PORT D6 - LCD Data pin 6
PORT D5 - LCD Data pin 5
PORT D4 - LCD Data pin 4

PORT D3 - Reserve for sw1
PORT D2 - Reserve for sw2
PORT D1 - Reserve for sw3
PORT D0 - Reserve for sw4

PORT RC6 - EN
PORT RC5 - RW
PORT RC4 - RS
--- Updated ---

still I am not getting data as expected

C:
#define _XTAL_FREQ 8000000
#include <xc.h>
// PIC18F45K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF       // Extended Instruction Set (Enabled)
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS  // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 06000-07FFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)

#define RS            LATCbits.LATC4
#define RW            LATCbits.LATC5
#define EN            LATCbits.LATC6

#define LCD_Port      LATD

void Port_Initialized (void)
{
    LATA = LATB = LATC = LATD = LATE =  0;
    TRISA = 0b0000000;// all are output, Unused
    TRISB = 0b0000000;// all are output, Unused
    TRISC = 0b0000000;// RS RW EN
    TRISD = 0b0000000;//  LCD
    TRISE = 0b0000000;// All are output, Unused

    ANCON0 = 0; // digital port
    ANCON1 = 0; // digital port
    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
}

void LCD_E_Pulse(void)
{
    EN = 1;
    __delay_us(4);
    EN = 0;
    __delay_us(4);
}

LCD_Write_CmdNibble(unsigned char data)
{
    RS = 0; RW = 0;
    LCD_Port = data & 0xF0 ;  // send upper nibble
    LCD_E_Pulse();
}
void LCD_WriteCmd(unsigned char data)
{

    RS = 0; RW = 0;
    LCD_Port = data & 0xF0 ;  // send upper nibble
    LCD_E_Pulse();
    __delay_ms(5);
    LCD_Port = (data << 4 );
    LCD_E_Pulse();
 
}


void LCD_Init(void)
{

    __delay_ms(40);
    LCD_Write_CmdNibble(0x30); //Function set 00110000
    __delay_ms(5);
    LCD_Write_CmdNibble(0x30);  //Function set 00110000
    __delay_us(100);
    LCD_Write_CmdNibble(0x30);  ////Function set 00110000
    
    LCD_WriteCmd(0x20);  // 4 bit  00100000
    LCD_WriteCmd(0x0C);  // Display ON
    LCD_WriteCmd(0x2C);  // 4 bit, 1-line display  5 × 8 dot character font 00101100
    LCD_WriteCmd(0x08);  //  clear display 00001000
 
}

void LCD_WriteData(unsigned char data)
{
 
   RS = 1;  // select Data register
   RW = 0 ;  // write mode

    LCD_Port = data & 0xF0 ;  // send upper nibble
    LCD_E_Pulse();
    __delay_ms(5);
    LCD_Port = (data << 4 );  // send lower nibble
    LCD_E_Pulse();
}


void buffer( unsigned char *p)
{

    while (*p != '\0')
    {
      LCD_WriteData(*p);
    __delay_ms(1) ;  // you can probably make this shorter
        p++;
    }
}
void main ()
{
    unsigned int i = 0;
    unsigned char Data1 []={"EDA Board"};
    Port_Initialized();
    LCD_Init();
    buffer(Data1);

    while (1)
    {


     }
}
 
Last edited:

That is actually a smart choice - you can trash D0 to D3 output registers with impunity when writing to LCD, since you will be setting them as inputs.

Must remember and use that trick....
 

Hi,

I see no problem to use
* PORTD(7..0) as output to LCD. PortD configured as output, Display_RW as WRITE.
* and at the same time connect 8 switches to PortD with a 10k series resistor each. PortD temporarily configured as input with pullup.

The resistors just prevent short circuit.

***

for many more switches or inputs one may use three state buffers like 74HC541. Display_E could be combined with HC541_OE

Klaus
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top