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:
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).
}