'init codes not working on sitronix' st7920 LCD12864B
while learning how to control a LCD 12864B from a PIC16F84A, I found an unexpected behaviour in init codes. I better explain the problem on a comment in the submitted code. I hope someone can give a clarifying reply. Here it is my LCD.c file:
`#include "Includes.h"`
void ToggleEpinOfLCD(void)
{
LCD_E = 1; // Give a pulse on E pin
__delay_us(E_Delay); // so that LCD can latch the
LCD_E = 0; // data from data bus
__delay_us(E_Delay);
}
void WriteCommandToLCD(unsigned char Command)
{
LCD_RS = 0; // It is a command
PORTB &= 0xF0; // Make Data pins zero
PORTB |= ((Command>>4)&0x0F); // Write Upper nibble of data
ToggleEpinOfLCD(); // Give pulse on E pin
PORTB &= 0xF0; // Make Data pins zero
PORTB |= (Command&0x0F); // Write Lower nibble of data
ToggleEpinOfLCD(); // Give pulse on E pin
}
void WriteDataToLCD(char LCDChar)
{
LCD_RS = 1; // It is data
PORTB &= 0xF0; // Make Data pins zero
PORTB |= ((LCDChar>>4)&0x0F); // Write Upper nibble of data
ToggleEpinOfLCD(); // Give pulse on E pin
PORTB &= 0xF0; // Make Data pins zero
PORTB |= (LCDChar&0x0F); // Write Lower nibble of data
ToggleEpinOfLCD(); // Give pulse on E pin
}
void InitLCD(void)
{
// Firstly make all pins output
LCD_E = 0; // E = 0
LCD_RS = 0; // RS = 0
LCD_Data_Bus_D0 = 0; // Data bus = 0
LCD_Data_Bus_D1 = 0; // Data bus = 0
LCD_Data_Bus_D2 = 0; // Data bus = 0
LCD_Data_Bus_D3 = 0; // Data bus = 0
LCD_E_Dir = 0; // Make Output
LCD_RS_Dir = 0; // Make Output
LCD_Data_Bus_Dir_D0 = 0; // Make Output
LCD_Data_Bus_Dir_D1 = 0; // Make Output
LCD_Data_Bus_Dir_D2 = 0; // Make Output
LCD_Data_Bus_Dir_D3 = 0; // Make Output
///////////////// Reset process //////////////
// On page 29 of the Sitronix' ST7920 datasheet, the display init procedure for 4 bits communication is the following:
// Wait 40 ms after power on
// labels here RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 HEX
// function set 0 0 0 0 1 0 X X X X 20
// Wait > 100 us
// function set 0 0 0 0 1 0 X X X X 20
// 0 0 X 0 X X X X X X 00
// this to me sounds correct, as 20h it's the code that sets the display on 4-bit mode
// but this doesn't work... WHY??
// Other people at this point suggest to send a 0x03 twice and then a 0x02, separated by a 500 us delay
// but I found it suffices to send a single 0x02 as below.
// Can someone please explain this, mainly as the official sitronix codes are involved?
__delay_ms(40);
WriteCommandToLCD(0x02); //select DDRAM, cursor move to dx address counter +1
/////////////////// Reset process end //////////
WriteCommandToLCD(0x20); //function set 4 bits mode
WriteCommandToLCD(0x0c); //display on,cursor off,blink off
WriteCommandToLCD(0x01); //clear display
__delay_ms(2); //
WriteCommandToLCD(0x06); //entry mode, set increment
}
void ClearLCDScreen(void) // Clear the Screen and return cursor to zero position
{
WriteCommandToLCD(0x01); // Clear the screen
__delay_ms(2); // Delay for cursor to return at zero position
}
For sake of completeness, I add the schematic image. Be well!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|