How to print message on Graphical LCD

John P

Joined Oct 14, 2008
2,026
What does a line like this mean?

#define RSL P0^0 = 0

If it's "Set bit 0 of Port 0 low" then it's a format that I've never seen.
 

Ian Rogers

Joined Dec 12, 2012
1,136
Like I said, I haven't got a copy of Kiel, I don't want to install it because I don't use it.. I have used several 8051 compilers and Keil is different to all the others.

Quick fix.... every RSL or RSH replace with PORT0^0 You need to get your head around this as C isn't as portable as folk say!

C:
#include <mcs51reg.h>
#define LcdDataBus  P2
#define LcdControlBus P0

#define DefaultDigits  10
#define GlcdFirstLine 0x00u
#define GlcdLastLine 0x07u
#define FirstLineAddress 0xB8
#define LastLineAddress  0xBF
#define BUSY_FLAG  7
void DELAY_us(int x);
void DELAY_ms(int x);
void GLCD_Init(void);
void GLCD_DisplayChar(unsigned char ch);
void GLCD_DisplayString(unsigned char  *);
void GLCD_ScrollMessage(unsigned char  lineNum, char *strptr);
void GLCD_Clear(void);
void GLCD_GoToPage(unsigned char  );
void GLCD_GoToLine(unsigned char  );
void GLCD_GoToNextLine(void);
void GLCD_SetCursor(unsigned char  lineNumber,unsigned char  CursorPosition);
void glcd_SelectPage0();
void glcd_SelectPage1();
void glcd_BusyCheck();
void glcd_CmdWrite( unsigned char  cmd);
void glcd_DataWrite( unsigned char  dat);
int GLCDPageNum;
int  GLCDLineNum;
int  GLCDCursorPos;

#define FONT_SIZE 5
const char GlcdFontTable[]=
{
0x00, 0x00, 0x00, 0x00, 0x00,  // space
0x00, 0x00, 0x2f, 0x00, 0x00,  // !
0x00, 0x07, 0x00, 0x07, 0x00,  // "
0x14, 0x7f, 0x14, 0x7f, 0x14,  // #
0x24, 0x2a, 0x7f, 0x2a, 0x12,  // $
0x23, 0x13, 0x08, 0x64, 0x62,  // %
0x36, 0x49, 0x55, 0x22, 0x50,  // &
0x00, 0x05, 0x03, 0x00, 0x00,  // '
0x00, 0x1c, 0x22, 0x41, 0x00,  // (
0x00, 0x41, 0x22, 0x1c, 0x00,  // )
0x14, 0x08, 0x3E, 0x08, 0x14,  // *
0x08, 0x08, 0x3E, 0x08, 0x08,  // +
0x00, 0x00, 0xA0, 0x60, 0x00,  // ,
0x08, 0x08, 0x08, 0x08, 0x08,  // -
0x00, 0x60, 0x60, 0x00, 0x00,  // .
0x20, 0x10, 0x08, 0x04, 0x02,  // /
0x3E, 0x51, 0x49, 0x45, 0x3E,  // 0
0x00, 0x42, 0x7F, 0x40, 0x00,  // 1
0x42, 0x61, 0x51, 0x49, 0x46,  // 2
0x21, 0x41, 0x45, 0x4B, 0x31,  // 3
0x18, 0x14, 0x12, 0x7F, 0x10,  // 4
0x27, 0x45, 0x45, 0x45, 0x39,  // 5
0x3C, 0x4A, 0x49, 0x49, 0x30,  // 6
0x01, 0x71, 0x09, 0x05, 0x03,  // 7
0x36, 0x49, 0x49, 0x49, 0x36,  // 8
0x06, 0x49, 0x49, 0x29, 0x1E,  // 9
0x00, 0x36, 0x36, 0x00, 0x00,  // :
0x00, 0x56, 0x36, 0x00, 0x00,  // ;
0x08, 0x14, 0x22, 0x41, 0x00,  // <
0x14, 0x14, 0x14, 0x14, 0x14,  // =
0x00, 0x41, 0x22, 0x14, 0x08,  // >
0x02, 0x01, 0x51, 0x09, 0x06,  // ?
0x32, 0x49, 0x59, 0x51, 0x3E,  // @
0x7C, 0x12, 0x11, 0x12, 0x7C,  // A
0x7F, 0x49, 0x49, 0x49, 0x36,  // B
0x3E, 0x41, 0x41, 0x41, 0x22,  // C
0x7F, 0x41, 0x41, 0x22, 0x1C,  // D
0x7F, 0x49, 0x49, 0x49, 0x41,  // E
0x7F, 0x09, 0x09, 0x09, 0x01,  // F
0x3E, 0x41, 0x49, 0x49, 0x7A,  // G
0x7F, 0x08, 0x08, 0x08, 0x7F,  // H
0x00, 0x41, 0x7F, 0x41, 0x00,  // I
0x20, 0x40, 0x41, 0x3F, 0x01,  // J
0x7F, 0x08, 0x14, 0x22, 0x41,  // K
0x7F, 0x40, 0x40, 0x40, 0x40,  // L
0x7F, 0x02, 0x0C, 0x02, 0x7F,  // M
0x7F, 0x04, 0x08, 0x10, 0x7F,  // N
0x3E, 0x41, 0x41, 0x41, 0x3E,  // O
0x7F, 0x09, 0x09, 0x09, 0x06,  // P
0x3E, 0x41, 0x51, 0x21, 0x5E,  // Q
0x7F, 0x09, 0x19, 0x29, 0x46,  // R
0x46, 0x49, 0x49, 0x49, 0x31,  // S
0x01, 0x01, 0x7F, 0x01, 0x01,  // T
0x3F, 0x40, 0x40, 0x40, 0x3F,  // U
0x1F, 0x20, 0x40, 0x20, 0x1F,  // V
0x3F, 0x40, 0x38, 0x40, 0x3F,  // W
0x63, 0x14, 0x08, 0x14, 0x63,  // X
0x07, 0x08, 0x70, 0x08, 0x07,  // Y
0x61, 0x51, 0x49, 0x45, 0x43,  // Z
0x00, 0x7F, 0x41, 0x41, 0x00,  // [
0x55, 0xAA, 0x55, 0xAA, 0x55,  // Backslash (Checker pattern)
0x00, 0x41, 0x41, 0x7F, 0x00,  // ]
0x04, 0x02, 0x01, 0x02, 0x04,  // ^
0x40, 0x40, 0x40, 0x40, 0x40,  // _
0x00, 0x03, 0x05, 0x00, 0x00,  // `
0x20, 0x54, 0x54, 0x54, 0x78,  // a
0x7F, 0x48, 0x44, 0x44, 0x38,  // b
0x38, 0x44, 0x44, 0x44, 0x20,  // c
0x38, 0x44, 0x44, 0x48, 0x7F,  // d
0x38, 0x54, 0x54, 0x54, 0x18,  // e
0x08, 0x7E, 0x09, 0x01, 0x02,  // f
0x18, 0xA4, 0xA4, 0xA4, 0x7C,  // g
0x7F, 0x08, 0x04, 0x04, 0x78,  // h
0x00, 0x44, 0x7D, 0x40, 0x00,  // i
0x40, 0x80, 0x84, 0x7D, 0x00,  // j
0x7F, 0x10, 0x28, 0x44, 0x00,  // k
0x00, 0x41, 0x7F, 0x40, 0x00,  // l
0x7C, 0x04, 0x18, 0x04, 0x78,  // m
0x7C, 0x08, 0x04, 0x04, 0x78,  // n
0x38, 0x44, 0x44, 0x44, 0x38,  // o
0xFC, 0x24, 0x24, 0x24, 0x18,  // p
0x18, 0x24, 0x24, 0x18, 0xFC,  // q
0x7C, 0x08, 0x04, 0x04, 0x08,  // r
0x48, 0x54, 0x54, 0x54, 0x20,  // s
0x04, 0x3F, 0x44, 0x40, 0x20,  // t
0x3C, 0x40, 0x40, 0x20, 0x7C,  // u
0x1C, 0x20, 0x40, 0x20, 0x1C,  // v
0x3C, 0x40, 0x30, 0x40, 0x3C,  // w
0x44, 0x28, 0x10, 0x28, 0x44,  // x
0x1C, 0xA0, 0xA0, 0xA0, 0x7C,  // y
0x44, 0x64, 0x54, 0x4C, 0x44,  // z
0x00, 0x10, 0x7C, 0x82, 0x00,  // {
0x00, 0x00, 0xFF, 0x00, 0x00,  // |
0x00, 0x82, 0x7C, 0x10, 0x00,  // }
0x00, 0x06, 0x09, 0x09, 0x06  // ~ (Degrees)
};
void DELAY_us(int x)
 {
 x>>=3;
 while(x--);
 }
void DELAY_ms(int x)
 {
 while(x--)
 DELAY_us(1000);
 }
void GLCD_Init()
{
 /* Select the Page0/Page1 and Enable the GLCD */
 glcd_SelectPage0();
 glcd_CmdWrite(0x3f);
 glcd_SelectPage1();
 glcd_CmdWrite(0x3f);
 DELAY_ms(10);
 /* Select the Page0/Page1 and Enable the GLCD */
 glcd_SelectPage0();
 glcd_CmdWrite(0xc0);
 glcd_SelectPage1();
 glcd_CmdWrite(0xc0);
 GLCD_GoToPage(0);
 /* Clear the complete LCD during init */
 GLCD_Clear();
 /* Set the cursor to beginning of page0 */
 GLCDPageNum=0;
 GLCDLineNum=0xB8;
 GLCDCursorPos=0x40;
 GLCD_GoToPage(0);
}
void GLCD_DisplayChar(unsigned char ch)
{
 unsigned char  dat,i=0;
 int addr = 0;
 if(((GLCDPageNum == 0x01) && ((GLCDCursorPos+FONT_SIZE)>=128)) || (ch=='\n'))
 {
 /* If the cursor has reached to end of line on page1
 OR NewLine command is issued Then Move the cursor to next line */
 GLCD_GoToNextLine();
 }
 if(ch!='\n') /* TODO */
 {
 ch -= 0x20; // As the lookup table starts from Space(0x20)
 addr = ch * 5;
 while(1)
 {
 if((GLCDPageNum == 0x00) && (GLCDCursorPos==0x80))
 {
 /* If the cursor has reached to end of line on page0
  Then Move the cursor to Page1 */
 GLCD_GoToPage(1);
 }
 dat= GlcdFontTable[addr+i]; /* Get the data to be displayed for LookUptable*/
 i++;
 glcd_DataWrite(dat); /* Display the data and keep track of cursor */
 GLCDCursorPos++;

 if(i==FONT_SIZE) /* Exit the loop if End of char is encountered */
 {
 glcd_DataWrite(0x00); /* Display the data and keep track of cursor */
 GLCDCursorPos++;
 break;
 }
 }
 }
}
void GLCD_DisplayString(unsigned char  *ptr)
{
 while(*ptr)
 GLCD_DisplayChar(*ptr++);
}
void GLCD_ScrollMessage(unsigned char  lineNum, char *strptr)
{
 unsigned char i,j,k,l,cursor,ch;
 if(lineNum > 7)
 lineNum = 0; // Select first line if the var_lineNumber_u8 is out of range
 for(i=0;strptr[i];i++)
 {
 /* Loop to display the complete string,  each time 16 chars are displayed and
  pointer is incremented to point to next char */
 for(k=0;k<6;k++)
 {
 GLCD_SetCursor(lineNum,6-k);  //Move the Cursor to first line
 cursor = 6-k;
 
 for(j=0;strptr[i+j] && (cursor<128);j++)
 {
 ch = strptr[i+j]-0x20;
 for(l=0;(l<5) && (cursor<128);l++)//Display first 16 Chars or till Null char is reached
 {
  glcd_DataWrite(GlcdFontTable[ch+l]);
 cursor++;
    if(cursor==64)  /* Has the cursor reached end of page0 */
  {
    glcd_SelectPage1(); /*  then set it to beginning of page1 */
 glcd_CmdWrite(FirstLineAddress+lineNum); 
    glcd_CmdWrite(0x40); 
 
   } 
 } 
 
  glcd_DataWrite(0);
 cursor++;
    if(cursor==64)  /* Has the cursor reached end of page0 */
  {
    glcd_SelectPage1(); /*  then set it to beginning of page1 */
 glcd_CmdWrite(FirstLineAddress+lineNum); 
    glcd_CmdWrite(0x40); 
 
   } 
 }
 
 while(cursor < 128)
 {
 DELAY_us(10);
 cursor++;
 }
 DELAY_ms(20);
 }
 }
} 

void GLCD_Clear()
{
 unsigned char  line,cursor;
 for(line=0;line<8;line++)  /* loop through all the 8lines to clear the display */
 {
 glcd_SelectPage0();  /* Select page0 and set the cursor to first position */
 glcd_CmdWrite(0x40);
 glcd_CmdWrite(FirstLineAddress+line);
 for(cursor=0;cursor<128;cursor++) /* Clear all the 128 pixels of selected line */
 {
 if(cursor==64)  /* Has the cursor reached end of page0 */
 {
 glcd_SelectPage1(); /*  then set it to beginning of page1 */
 glcd_CmdWrite(0x40);
 glcd_CmdWrite(FirstLineAddress+line);
 }
 glcd_DataWrite(0x00); /* Clear each pixel by displaying blank */
 }
 }
 GLCD_GoToLine(0);
}
void GLCD_GoToPage(unsigned char  pageNumber)
{
 if((pageNumber==0) || (pageNumber ==1))
 { /* for 128/64 GLCD only page 0&1 are supported.
 Select the specified page and move the cursor accordingly */
 if(pageNumber == 0)
 {
 glcd_SelectPage0();
 }
 else
 {
 glcd_SelectPage1();
 }
 GLCDPageNum=pageNumber;
 GLCDCursorPos=0x40;
 glcd_CmdWrite(GLCDLineNum);
 glcd_CmdWrite(GLCDCursorPos);
 }
}
void  GLCD_GoToLine(unsigned char  lineNumber)
{
 if(lineNumber<8)
 {  /* If the line number is within range
  then move it to specified line on page0 and keep track*/
 GLCDLineNum = lineNumber+FirstLineAddress;
 GLCD_GoToPage(0);
 }
}
void  GLCD_GoToNextLine()
{
 /*Increment the current line number.
  In case it exceeds the limit, rool it back to first line */
 GLCDLineNum++;
 if(GLCDLineNum > LastLineAddress)
 GLCDLineNum = FirstLineAddress;
 GLCD_GoToPage(0); /* Finally move it to next line on page0 */
}

void GLCD_SetCursor(unsigned char  lineNumber,unsigned char  CursorPosition)
{
 unsigned char  pageNumber;
 if(((lineNumber >=0x00)  && (lineNumber <= GlcdLastLine))
 && ((CursorPosition>=0x00) && (CursorPosition <= 128)) )
 {
 pageNumber = CursorPosition / 64; //Divide the cursor pos by 64 to get the page
 CursorPosition = CursorPosition % 0x3f; // Cusror pos should be within 64(0x3f),
 if(pageNumber==0x00)  /* Check for page number and set accordingly */
 {
 glcd_SelectPage0();
 }
 else
 {
 glcd_SelectPage1();
 }
 GLCDPageNum = pageNumber; /* Keep the track of page selected */
 GLCDLineNum=lineNumber | FirstLineAddress; /* Select the specified line number */
 GLCDCursorPos=CursorPosition |0x40; /* Select the specified cursor position */
 glcd_CmdWrite(GLCDCursorPos); /* Command the LCD to move to specified page,line,cursor*/
 glcd_CmdWrite(GLCDLineNum);
 }
}
void glcd_CmdWrite( unsigned char cmd)
 {
 glcd_BusyCheck();
 LcdDataBus = cmd ;
 P0^0 = 0; // Select the Data Register by pulling RS LOW
 P0^1 = 0;  // Select the Write operation by pulling RW LOW
 P0^2 = 0;  // Send a High-to-Low Pulse at Enable Pin
 DELAY_us(1);
 P0^2 = 1;
 }
void glcd_DataWrite(unsigned char dat)
 {
 glcd_BusyCheck();
 LcdDataBus = dat;
 P0^0 = 1; // Select the Data Register by pulling RS LOW
 P0^1 = 0;   // Select the Write operation by pulling RW LOW
 P0^2 = 0;  // Send a High-to-Low Pulse at Enable Pin
 DELAY_us(1);
 P0^2 = 1;
 }
void glcd_SelectPage0()
 {
 P0^3 = 1;
 P0^4 = 0;
 }
void glcd_SelectPage1()
 {
 P0^3 = 0;
 P0^4 = 1;
 }
void glcd_BusyCheck()
 { 
 DELAY_us(100);
 }
void main(void)
 {
 GLCD_Init();
 GLCD_Clear();
 GLCD_DisplayString("Hello world!!!");
 while(1);
 
 }
 

Ian Rogers

Joined Dec 12, 2012
1,136
If it's "Set bit 0 of Port 0 low" then it's a format that I've never seen.
They use this format in GNU compiler chains... To use sfr or sbit on SDCC is a bit of a phaff so I do it this way..

#define RSL ( P0^0 = 0 ) // this just does what I've done above... It is more portable..
 

Thread Starter

@vajra

Joined May 2, 2018
154
They use this format in GNU compiler chains... To use sfr or sbit on SDCC is a bit of a phaff so I do it this way..

#define RSL ( P0^0 = 0 ) // this just does what I've done above... It is more portable..
I think I have to spend more time with Keil. I tried your two solution but It doesn't work
 
Top