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.

Simple 16X2 LCD not working - Help!

Status
Not open for further replies.

fouadalnoor

Member
Hello guys,

I am currently trying to connect and talk to a simple 16x2 LCD screen using an Atmel SAm4LXplanined development board. I used to be able to output data to both the first and second lines of the screen, however now I am only able to output to the first line! I am really confused as to why this is happening. I bought another LCD screen just in case and it has the same problem, so the fault is probably in my code. The weird thing is that my code (below) seems to be fine, and I can't see anything wrong with the wires.

Currently, I am able to send data from my terminal, via UART to the first line. When it gets to the 16th character, I can get the cursor to reset and overwrite what I have written. When I try to set the cursor to the second line (40H) it doesn't show up at all and nothing that I write shows up. When I read the Display Data Register (DDR) I see that the cursor is indeed set correctly to 40H. So I am a bit lost now as to what is going on.

I am also able to change the cursor settings from blinking/non blinking etc from in the initialization steps so they seem to work fine as well...

Hope you guys can help!

PS: I have added the LCD screen and development board data sheet that I am using.

My code is as follows:

Code:
#include <asf.h>
#include <string.h>
#include <stdio.h>


void initIO(void); //Initialize Input/Output of Board
void EightbitInit (void); //Initialize LCD screen
void outputMessage(int binaryMessage[8]); //Output one character at a time to the screen.
void FirstNewLine(void); //Set cursor to 00H (start of first line in LCD).
void SecondNewLine(void); //Set cursor to 40H (start of second line in LCD).
void ReadDDR(void);
void ResetIO(void);

volatile int DDRValue[8];

int main (void)
{
    board_init();
    sysclk_init();

    initIO(); //Setting all the directions of all the pins as outputs.
    EightbitInit(); //Initialize the screen.

 
 
    ////////////Setting up UART////////
    uint8_t received_byte = NULL; //store the received byte from Bluetooth
    volatile int binaryMessage[8]; // Store the binary version of "received_byte"
    const char data[] = "Hello World!\r\n";
    volatile size_t length = strlen("Hello World!\r\n");
    volatile int NumberOfChar = 0;
 
    static usart_serial_options_t usart_options = {
        .baudrate = CONF_UART_BAUDRATE, //115200 bit/sec
        .charlength = CONF_UART_CHAR_LENGTH, //8bit
        .paritytype = CONF_UART_PARITY, //NO PARITY
        .stopbits = CONF_UART_STOP_BITS //1 STOP BIT
    };

    usart_serial_init(CONF_UART, &usart_options); //Initialize the UART.
    usart_serial_write_packet(CONF_UART, data, length); //Write "Hello World! for verification of communication (Know that TDX works).
 
    while(1)
    {
        //Not sure why it only transmits Bluetooth data but only receives 0? (Seems to work with Wire though...)
        usart_serial_putchar(CONF_UART, received_byte);  //Send received character back to verify the communication.
        usart_serial_getchar(CONF_UART, &received_byte);//Wait until it receives one character ( stored as an ASCII number).

        if(received_byte!=NULL) //Output each letter received to the screen.
        {
         
            volatile int  n;

            for (n = 0; n < 8; n++) //Change received character from decimal to binary representation.
            {
                if (received_byte & (1 << n))
                {
                    binaryMessage[n] = 1;
                }
                else
                {
                    binaryMessage[n] = 0;
                }
            }
         
            n = 0; //reset n.
         
            //delay_ms(1); //It may be too quick..may need to add appropriate delay
            outputMessage(binaryMessage); //outputs one letter at a time
            NumberOfChar++;
            if (NumberOfChar==16)
            {
                NumberOfChar = 0;
                SecondNewLine();
                ReadDDR(); //Almost working, not sure why DB6 is always found to be = 1 (even when explicitly set to 0 with SecondLine!)
                //SecondNewLine(); //Does not work..:( might need new screen..
                //ReadDDR(); //Almost working, not sure why DB6 is always found to be = 1 (even when explicitly set to 0 with SecondLine!)
                //FirstNewLine();
             
                //ResetIO();    //not working..
             
             
            }
        }
     
     
    }
}


////////END OF USART SETUP/////////////

//Now I need to take in the value from 'message' and output it onto the display. I may need an ASCII to binary converter.


void initIO(void)
{
    //Setting the pins for: RS, R/W and E as outputs.
    ioport_set_pin_dir(EXT3_PIN_15, IOPORT_DIR_OUTPUT); //RS
    ioport_set_pin_dir(EXT4_PIN_5, IOPORT_DIR_OUTPUT); //R/W
    ioport_set_pin_dir(EXT4_PIN_6, IOPORT_DIR_OUTPUT); //E
 
    //Setting the pins for: Data DB0-DB7
    ioport_set_pin_dir(EXT1_PIN_5, IOPORT_DIR_OUTPUT); //DB0
    ioport_set_pin_dir(EXT1_PIN_6, IOPORT_DIR_OUTPUT); //DB1
    ioport_set_pin_dir(EXT2_PIN_5, IOPORT_DIR_OUTPUT); //DB2
    ioport_set_pin_dir(EXT2_PIN_6, IOPORT_DIR_OUTPUT); //DB3
    ioport_set_pin_dir(EXT2_PIN_10, IOPORT_DIR_OUTPUT); //DB4
    ioport_set_pin_dir(EXT3_PIN_5, IOPORT_DIR_OUTPUT); //DB5
    ioport_set_pin_dir(EXT3_PIN_6, IOPORT_DIR_OUTPUT); //DB6
    ioport_set_pin_dir(EXT3_PIN_10, IOPORT_DIR_OUTPUT); //DB7 <- Will need to change this to input later on (to check for busy signal).
 
}

void EightbitInit(void)
{
    delay_ms(50); //wait more than 30ms.
 
    //8-bit interface mode.
    ioport_set_pin_level(EXT4_PIN_6,1); //Enable = 1;
 
    //Function Set
    ioport_set_pin_level(EXT3_PIN_15, 0); //RS = 0
    ioport_set_pin_level(EXT4_PIN_5, 0); //R/W = 0
 
    ioport_set_pin_level(EXT3_PIN_10,0); //DB7 = 0
    ioport_set_pin_level(EXT3_PIN_6,0); //DB6 = 0
    ioport_set_pin_level(EXT3_PIN_5,1); //DB5 = 1 //DL = 1 for 8 bit mode.
    ioport_set_pin_level(EXT2_PIN_10,1); //DB4 = 1
    ioport_set_pin_level(EXT2_PIN_6,1); //DB3 = N =  1,  N = Numbers of display line (N:2-line/1-line) //<--Not working?! may need new Screen..
    ioport_set_pin_level(EXT2_PIN_5,1); //DB2 = F =  1, F = Display font type (F:5*10 dots/5*7 dots)
 
    ioport_set_pin_level(EXT1_PIN_6,0); //DB1 = 0 (don't care)
    ioport_set_pin_level(EXT1_PIN_5,0); //DB0 = 0 (don't care)

    ioport_set_pin_level(EXT4_PIN_6,0); //Enable = 0;
 
    delay_us(50); //wait more than 39us
 
    ioport_set_pin_level(EXT4_PIN_6,1); //Enable = 1;
 
    //Display ON/OFF Control
    ioport_set_pin_level(EXT3_PIN_15,0); //RS = 0
    ioport_set_pin_level(EXT4_PIN_5,0); //R/W = 0
 
    ioport_set_pin_level(EXT3_PIN_10,0); //DB7 = 0
    ioport_set_pin_level(EXT3_PIN_6,0); //DB6 = 0
    ioport_set_pin_level(EXT3_PIN_5,0); //DB5 = 0
    ioport_set_pin_level(EXT2_PIN_10,0); //DB4 = 0
    ioport_set_pin_level(EXT2_PIN_6,1); //DB3 = 1
    ioport_set_pin_level(EXT2_PIN_5,1); //DB2 = D = 1, D = Set Display (ON)
 
    ioport_set_pin_level(EXT1_PIN_6,1); //DB1 = C = 1, C =  cursor on
    ioport_set_pin_level(EXT1_PIN_5,0); //DB0 = B = 1, Blinking  cursor (ON/OFF)
 
    ioport_set_pin_level(EXT4_PIN_6,0); //Enable = 0;
 
    delay_us(50); //wait more than 39us

    ioport_set_pin_level(EXT4_PIN_6,1); //Enable = 1;
    //Display clear
 
    ioport_set_pin_level(EXT3_PIN_15,0); //RS = 0
    ioport_set_pin_level(EXT4_PIN_5,0); //R/W = 0
 
    ioport_set_pin_level(EXT3_PIN_10,0); //DB7 = 0
    ioport_set_pin_level(EXT3_PIN_6,0); //DB6 = 0
    ioport_set_pin_level(EXT3_PIN_5,0); //DB5 = 0
    ioport_set_pin_level(EXT2_PIN_10,0); //DB4 = 0
    ioport_set_pin_level(EXT2_PIN_6,0); //DB3 = 0
    ioport_set_pin_level(EXT2_PIN_5,0); //DB2 = 0
 
    ioport_set_pin_level(EXT1_PIN_6,0); //DB1 = 0
    ioport_set_pin_level(EXT1_PIN_5,1); //DB0 = 1
 
    ioport_set_pin_level(EXT4_PIN_6,0); //Enable = 0;
    delay_ms(2);
 
    //Entry mode set (increment)
 
    ioport_set_pin_level(EXT4_PIN_6,1); //Enable = 1;
 
    ioport_set_pin_level(EXT3_PIN_15,0); //RS = 0
    ioport_set_pin_level(EXT4_PIN_5,0); //R/W = 0
 
    ioport_set_pin_level(EXT3_PIN_10,0); //DB7 = 0
    ioport_set_pin_level(EXT3_PIN_6,0); //DB6 = 0
    ioport_set_pin_level(EXT3_PIN_5,0); //DB5 = 0
    ioport_set_pin_level(EXT2_PIN_10,0); //DB4 = 0
    ioport_set_pin_level(EXT2_PIN_6,0); //DB3 = 0
    ioport_set_pin_level(EXT2_PIN_5,1); //DB2 = 1
    ioport_set_pin_level(EXT1_PIN_6,1); //DB1 = I/D = 1 (increment/decrement)
    ioport_set_pin_level(EXT1_PIN_5,0); //DB0 = S = 0, Enable the shift of entire display (entire shift off/entire shift on).
 
    ioport_set_pin_level(EXT4_PIN_6,0); //Enable = 0;
 
    delay_us(50);
 
 
    //initialization end.
 
}

void outputMessage(int message[])
{
 
    //'H'
    ioport_set_pin_level(EXT4_PIN_6,1); //Enable = 1;
 
    ioport_set_pin_level(EXT3_PIN_15,1); //RS = 1 //Set the RS bit for writing into the data register.
    ioport_set_pin_level(EXT4_PIN_5,0); //R/W = 0
 
    ioport_set_pin_level(EXT3_PIN_10,0); //DB7 =0 //Always 0 since ASCII is only 7 bits.
    ioport_set_pin_level(EXT3_PIN_6,message[6]); //DB6 = 1
    ioport_set_pin_level(EXT3_PIN_5,message[5]); //DB5 = 0
    ioport_set_pin_level(EXT2_PIN_10,message[4]);//DB4 = 0
    ioport_set_pin_level(EXT2_PIN_6,message[3]); //DB3 = 1
    ioport_set_pin_level(EXT2_PIN_5,message[2]); //DB2 = 0
    ioport_set_pin_level(EXT1_PIN_6,message[1]); //DB1 = 0
    ioport_set_pin_level(EXT1_PIN_5,message[0]); //DB0 = 0
 
    ioport_set_pin_level(EXT4_PIN_6,0); //Enable = 0;
 
    delay_us(1);
}

void FirstNewLine(void)
{
    //Set DDR to 00H
    delay_us(50);
    ioport_set_pin_level(EXT4_PIN_6,1); //Enable = 1;
 
    ioport_set_pin_level(EXT3_PIN_15,0); //RS = 0 //Set the RS bit for instruction code (Display shift)
    ioport_set_pin_level(EXT4_PIN_5,0); //R/W = 0 //Write
 
    ioport_set_pin_level(EXT3_PIN_10,1); //DB7 =1
 
    ioport_set_pin_level(EXT3_PIN_6,0); //DB6 = 1 //From here its DDR (Display Data Ram).  (note that MSB does not count!)
    ioport_set_pin_level(EXT3_PIN_5,0); //DB5 = 0
    ioport_set_pin_level(EXT2_PIN_10,0);//DB4 = 0
    ioport_set_pin_level(EXT2_PIN_6,0); //DB3 = 0
    ioport_set_pin_level(EXT2_PIN_5,0); //DB2 = 0
    ioport_set_pin_level(EXT1_PIN_6,0); //DB1 = 0
    ioport_set_pin_level(EXT1_PIN_5,0); //DB0 = 0
 
    ioport_set_pin_level(EXT4_PIN_6,0); //Enable = 0;
 
    delay_us(50);
}

void SecondNewLine(void)
{
    //Set DDR to 40H
    delay_us(50);
    ioport_set_pin_level(EXT4_PIN_6,1); //Enable = 1;
 
    ioport_set_pin_level(EXT3_PIN_15,0); //RS = 0 //Set the RS bit for instruction code (Display shift)
    ioport_set_pin_level(EXT4_PIN_5,0); //R/W = 0 //Write
 
    ioport_set_pin_level(EXT3_PIN_10,1); //DB7 =1
 
    ioport_set_pin_level(EXT3_PIN_6,1); //DB6 = 1 //From here its DDR (Display Data Ram).  (note that MSB - DB7 does not count!)
    ioport_set_pin_level(EXT3_PIN_5,0); //DB5 = 0
    ioport_set_pin_level(EXT2_PIN_10,0);//DB4 = 0
    ioport_set_pin_level(EXT2_PIN_6,0); //DB3 = 0
    ioport_set_pin_level(EXT2_PIN_5,0); //DB2 = 0
    ioport_set_pin_level(EXT1_PIN_6,0); //DB1 = 0
    ioport_set_pin_level(EXT1_PIN_5,0); //DB0 = 0
 
    ioport_set_pin_level(EXT4_PIN_6,0); //Enable = 0;
 
    delay_us(50);
 
 
}

void ReadDDR(void)
{
    //Setting pin Direction:
 
    //Setting the pins for: Data DB0-DB7
    ioport_set_pin_dir(EXT1_PIN_5, IOPORT_DIR_INPUT); //DB0
    ioport_set_pin_dir(EXT1_PIN_6, IOPORT_DIR_INPUT); //DB1
    ioport_set_pin_dir(EXT2_PIN_5, IOPORT_DIR_INPUT); //DB2
    ioport_set_pin_dir(EXT2_PIN_6, IOPORT_DIR_INPUT); //DB3
    ioport_set_pin_dir(EXT2_PIN_10, IOPORT_DIR_INPUT); //DB4
    ioport_set_pin_dir(EXT3_PIN_5, IOPORT_DIR_INPUT); //DB5
    ioport_set_pin_dir(EXT3_PIN_6, IOPORT_DIR_INPUT); //DB6
    ioport_set_pin_dir(EXT3_PIN_10, IOPORT_DIR_INPUT); //DB7 <- Will need to change this to input later on (to check for busy signal).
 
 
    //Read Address of cursor (DDR address).
    delay_us(50);
    ioport_set_pin_level(EXT4_PIN_6,1); //Enable = 1;
    ioport_set_pin_level(EXT3_PIN_15,0); //RS = 0 //Set the RS bit for instruction code
    ioport_set_pin_level(EXT4_PIN_5,1); //R/W = 1 //Read (R/W =1)

    DDRValue[7]= ioport_get_pin_level(EXT3_PIN_6); //DB6 //The first bit that get read will always = 1!? (Discard this bit...)
    DDRValue[6]= ioport_get_pin_level(EXT3_PIN_6); //DB6
    DDRValue[5]= ioport_get_pin_level(EXT3_PIN_5); //DB5
    DDRValue[4]= ioport_get_pin_level(EXT2_PIN_10);//DB4
    DDRValue[3]= ioport_get_pin_level(EXT2_PIN_6); //DB3
    DDRValue[2]= ioport_get_pin_level(EXT2_PIN_5); //DB2
    DDRValue[1]= ioport_get_pin_level(EXT1_PIN_6); //DB1
    DDRValue[0]= ioport_get_pin_level(EXT1_PIN_5); //DB0
 

    ioport_set_pin_level(EXT4_PIN_6,0); //Enable = 0;

    delay_us(50);

    initIO();

    /*
    while(1) //DB7 Read the busy Flag (BF)
    {
    if(ioport_get_pin_level(EXT3_PIN_10)==0)
    {
    DDRValue[6]= ioport_get_pin_level(EXT3_PIN_6); //DB6
    DDRValue[5]= ioport_get_pin_level(EXT3_PIN_5); //DB5
    DDRValue[4]= ioport_get_pin_level(EXT2_PIN_10);//DB4
    DDRValue[3]= ioport_get_pin_level(EXT2_PIN_6); //DB3
    DDRValue[2]= ioport_get_pin_level(EXT2_PIN_5); //DB2
    DDRValue[1]= ioport_get_pin_level(EXT1_PIN_6); //DB1
    DDRValue[0]= ioport_get_pin_level(EXT1_PIN_5); //DB0
    break;
    }
 
    }
 
 
    ioport_set_pin_level(EXT4_PIN_6,0); //Enable = 0;

    delay_us(50);
    */
}

void ResetIO()
{
    //Setting the pins for: Data DB0-DB7
    ioport_set_pin_dir(EXT1_PIN_5, IOPORT_DIR_OUTPUT); //DB0
    ioport_set_pin_dir(EXT1_PIN_6, IOPORT_DIR_OUTPUT); //DB1
    ioport_set_pin_dir(EXT2_PIN_5, IOPORT_DIR_OUTPUT); //DB2
    ioport_set_pin_dir(EXT2_PIN_6, IOPORT_DIR_OUTPUT); //DB3
    ioport_set_pin_dir(EXT2_PIN_10, IOPORT_DIR_OUTPUT); //DB4
    ioport_set_pin_dir(EXT3_PIN_5, IOPORT_DIR_OUTPUT); //DB5
    ioport_set_pin_dir(EXT3_PIN_6, IOPORT_DIR_OUTPUT); //DB6
    ioport_set_pin_dir(EXT3_PIN_10, IOPORT_DIR_OUTPUT); //DB7 <- Will need to change this to input later on (to check for busy signal).
}
 

Attachments

  • dem16217syhly.pdf
    261.5 KB · Views: 195
  • Atmel-42074-SAM4L-Xplained-Pro_User-Guide copy.pdf
    1.2 MB · Views: 431
On PDF page 11, this

In 2-line display mode (N=1), DDRAM address in the 1st line is from “00H” to “27H”, and DDRAM address in the 2nd line is from “40H” to “67H”.

Will probably help.
 
Yeah, well 40H is 0100 0000 in binary. That's what I put in my SecondLine function. Note that it always ignores the MSB since its always 0. So it is 100 0000, hence DB6 = 1, DB5 =0 etc. This used to work before..so not sure why its not working now. Also, I have noticed that the screen only displays "black boxes" on the first line only, when I change the potentiometer (to change the contrast). I suspect its an initilization issue. I believe the default setting is a 1-line display..and I can't get it to make it a 2-line display.
 
Do you check the done bit after every function before issuing another command?

I THINK the datasheet had a way of setting the 1 or 2 line mode and also a way to read the mode.
 
Do you check the done bit after every function before issuing another command?

I THINK the datasheet had a way of setting the 1 or 2 line mode and also a way to read the mode.

Fixed! The problem was occurring due to one of my physical data pins being in the wrong spot (basically had to swap data pins DB5 and DB6). It all works as expected now! Goes to show, one must always double check the pins.

Note: No, I don't check the BF (busy flag - DB7 ) bit since I have just added delays which work for now (I ensured that the timing of the delays is a fair bit above the recommended values).
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top