// GLCD.c driver 128x64 graphic LCD for 8051SBC V1.0 // W.SIRICHOTE #include "gfont.h" #define BUSY 0x80 #define write_command1 (*((unsigned char *)0x0404)) #define read_command1 (*((unsigned char *)0x0405)) #define write_data1 (*((unsigned char *)0x0406)) #define read_data1 (*((unsigned char *)0x0407)) #define write_command2 (*((unsigned char *)0x0408)) #define read_command2 (*((unsigned char *)0x0409)) #define write_data2 (*((unsigned char *)0x040A)) #define read_data2 (*((unsigned char *)0x040B)) #define LCD 0x0A #define left 1 #define right 0 /* LCD Registers */ #define X_ADRESS 0xB8 /* Adress base for Page 0 */ #define Y_ADRESS 0x40 /* Adress base for Y0 */ #define START_LINE 0xC0 /* Adress base for line 0 */ #define DISPLAY_ON 0x3F /* Turn display on */ #define DISPLAY_OFF 0x3E /* Turn display off */ char LcdReady1() { char flag; while((flag=read_command1&BUSY)) if(flag == 0xFF) return 0; return 1; } char LcdReady2() { char flag; while((flag=read_command2&BUSY)) { if(flag == 0xFF) return -1; } return 1; } void LcdInstructionWrite (char n,char k) { if(k==left) { LcdReady1(); write_command1 = n; } else { LcdReady2(); write_command2 = n; } } void LcdDataWrite (char n,char k) { if(k==left) { LcdReady1(); write_data1 = n; } else { LcdReady2(); write_data2 = n; } } char LcdDataRead(char k) { if(k==left) return read_data1; else return read_data2; } void GLCD_ClearScreen (void) { unsigned char u8Page, u8Column; u8Page = u8Column = 0; /* process the 8 pages of the LCD */ for (u8Page = 0; u8Page < 8; u8Page++) { LcdInstructionWrite(X_ADRESS | u8Page,left); /* Set the page number */ LcdInstructionWrite(Y_ADRESS,left); /* Set column to 0 */ /* process a page on both sides */ for (u8Column = 0; u8Column < 128; u8Column++) { if (u8Column == 64) { LcdInstructionWrite(X_ADRESS | u8Page,right); /* Set the page number */ LcdInstructionWrite(Y_ADRESS,right); /* Set column to 0 */ } LcdDataWrite(0x00,right); /* erase a column */ LcdDataWrite(0x00,left); } } } char GLCD_LcdInit(void) { if(LcdReady1()==0) return 0; printf("\n %02x",read_command1); LcdInstructionWrite(DISPLAY_OFF,left); /* Display OFF */ LcdInstructionWrite(START_LINE,left); LcdInstructionWrite(X_ADRESS,left); LcdInstructionWrite(Y_ADRESS,left); LcdInstructionWrite(DISPLAY_ON,left); /* Display ON */ if(LcdReady2()==0) return 0; printf("\n %02x",read_command2); LcdInstructionWrite(DISPLAY_OFF,right); /* Display OFF */ LcdInstructionWrite(START_LINE,right); LcdInstructionWrite(X_ADRESS,right); LcdInstructionWrite(Y_ADRESS,right); LcdInstructionWrite(DISPLAY_ON,right); /* Display ON */ GLCD_ClearScreen(); } void GLCD_DisplayPicture (char *au8PictureData) { unsigned char u8Page, u8Column; u8Page= u8Column=0; /* Send the left side */ for (u8Page = 0; u8Page < 8; u8Page++) /* loop on the 8 pages */ { LcdInstructionWrite(X_ADRESS | u8Page,left); /* Set the page */ for (u8Column = 0; u8Column < 64; u8Column++) LcdDataWrite(au8PictureData[(128*u8Page)+u8Column],left); } /* Send the right side */ for (u8Page = 0; u8Page < 8; u8Page++) /* loop on the 8 pages */ { LcdInstructionWrite(X_ADRESS | u8Page,right); /* Set the page */ for (u8Column = 64; u8Column < 128; u8Column++) LcdDataWrite(au8PictureData[(128*u8Page)+u8Column],right); } } void LcdSetDot (char u8Xaxis,char u8Yaxis) { unsigned char u8DataRead; u8DataRead=0; LcdInstructionWrite(START_LINE,left); /* Set adress for line 0 */ /* Left side */ if (u8Xaxis < 64) { LcdInstructionWrite (X_ADRESS + (u8Yaxis / 8),left); /* Select page number */ LcdInstructionWrite (Y_ADRESS + u8Xaxis,left); /* Select column */ u8DataRead = LcdDataRead(left); /* read the current location */ u8DataRead = LcdDataRead(left); /* on the LCD. dummy read */ LcdInstructionWrite (X_ADRESS + (u8Yaxis / 8),left); /* Select page number */ LcdInstructionWrite (Y_ADRESS + u8Xaxis,left); /* Select column */ LcdDataWrite (u8DataRead | (1 << (u8Yaxis % 8)),left);/* plot the dot */ } else /* Right side */ { LcdInstructionWrite (X_ADRESS + (u8Yaxis / 8),right); /* Select page number */ LcdInstructionWrite (Y_ADRESS + u8Xaxis - 64,right); /* Select column */ u8DataRead = LcdDataRead(right); /* read the current location */ u8DataRead = LcdDataRead(right); /* on the LCD. dummy read */ LcdInstructionWrite (X_ADRESS + (u8Yaxis / 8),right); /* Select page number */ LcdInstructionWrite (Y_ADRESS + u8Xaxis - 64,right); /* Select column */ LcdDataWrite (u8DataRead | (1 << (u8Yaxis % 8)),right);/* plot the dot */ } LcdInstructionWrite(START_LINE,left); /* Set adress for line 0 */ } /*------------------------------------------------------------------------------- Draw a rectangle on the LCD GLCD_Rectangle (U8 u8Xaxis1,U8 u8Yaxis1,U8 u8Xaxis2,U8 u8Yaxis2) u8Xaxis1 = absciss top-left (in pixels) u8Yaxis1 = ordinate top-left (in pixels) u8Xaxis2 = absciss bottom-right (in pixels) u8Yaxis2 = ordinate bottom-right (in pixels) -------------------------------------------------------------------------------*/ void GLCD_Rectangle(char u8Xaxis1,char u8Yaxis1,char u8Xaxis2,char u8Yaxis2) { char u8CurrentValue; u8CurrentValue=0; /* Draw the two horizontal lines */ for (u8CurrentValue = 0; u8CurrentValue < u8Xaxis2 - u8Xaxis1+ 1; u8CurrentValue++) { LcdSetDot(u8Xaxis1 + u8CurrentValue, u8Yaxis1); LcdSetDot(u8Xaxis1 + u8CurrentValue, u8Yaxis2); } /* draw the two vertical lines */ for (u8CurrentValue = 0; u8CurrentValue < u8Yaxis2 - u8Yaxis1 + 1; u8CurrentValue++) { LcdSetDot(u8Xaxis1, u8Yaxis1 + u8CurrentValue); LcdSetDot(u8Xaxis2, u8Yaxis1 + u8CurrentValue); } } /* Draw a circle on the LCD GLCD_Circle (char u8CenterX, char u8CenterY, char u8Radius) u8CenterX = Center absciss (in pixels) u8CenterY = Center ordinate (in pixels) u8Radius = Radius (in pixels) */ void GLCD_Circle(char u8CenterX,char u8CenterY,char u8Radius) { int s16tswitch, s16y,s16x; char u8d; s16tswitch = s16y=s16x=0; u8d = u8CenterY - u8CenterX; s16y = u8Radius; s16tswitch = 3 - 2 * u8Radius; while (s16x <= s16y) { LcdSetDot(u8CenterX + s16x, u8CenterY + s16y); LcdSetDot(u8CenterX + s16x, u8CenterY - s16y); LcdSetDot(u8CenterX - s16x, u8CenterY + s16y); LcdSetDot(u8CenterX - s16x, u8CenterY - s16y); LcdSetDot(u8CenterY + s16y - u8d, u8CenterY + s16x); LcdSetDot(u8CenterY + s16y - u8d, u8CenterY - s16x); LcdSetDot(u8CenterY - s16y - u8d, u8CenterY + s16x); LcdSetDot(u8CenterY - s16y - u8d, u8CenterY - s16x); if (s16tswitch < 0) s16tswitch += (4 * s16x + 6); else { s16tswitch += (4 * (s16x - s16y) + 10); s16y--; } s16x++; } } /*------------------------------------------------------------------------------- Print a char on the LCD GLCD_Putchar (U8 u8Char) u8Char = char to display -------------------------------------------------------------------------------*/ /* void LcdPutchar (char u8Char,FONT_DEF *toto) { static char u8CharColumn,u8RightSide; char u8UpperCharPointer,u8Page; u8CharColumn=u8RightSide=0; u8UpperCharPointer=1 u8Page=0; /* test for carrier return */ if (u8CursorX > 128 - (toto->u8Width) ) { u8CursorX = 0; u8CursorY++; if (u8CursorY == 8) u8CursorY = 0; } /* Select the side of the LCD */ if (u8CursorX < 64) { LcdInstructionWrite (Y_ADRESS + u8CursorX,left); } else { LcdInstructionWrite (Y_ADRESS + u8CursorX - 64,right); } /* Draw a char */ while (u8CharColumn < (toto->u8Width) ) { if ((toto->u8Height) > 8) { u8UpperCharPointer = 2; if (u8CursorX > 64) u8RightSide=64; LcdInstructionWrite (X_ADRESS + u8CursorY -1,right); LcdInstructionWrite (Y_ADRESS + u8CursorX -u8RightSide,right); LcdDataWrite ((toto->au8FontTable)[( (u8Char - 32) * u8UpperCharPointer * (toto->u8Width) ) + ((u8CharColumn * u8UpperCharPointer) + 1)],right); LcdInstructionWrite (Y_ADRESS + u8CursorX -u8RightSide,right); } LcdInstructionWrite (X_ADRESS + u8CursorY,right); LcdDataWrite ((toto->au8FontTable)[( (u8Char - 32) * u8UpperCharPointer * (toto->u8Width) ) + (u8CharColumn * u8UpperCharPointer)],right); u8CharColumn++; u8CursorX++; /* test if a char is wrote on both sides of LCD */ if (u8CursorX == 64) { u8RightSide=64; // LcdSelectSide (RIGHT); /* if yes, select right side */ LcdInstructionWrite (X_ADRESS + u8CursorY,right); LcdInstructionWrite (Y_ADRESS + u8CursorX -u8RightSide,right); } } /* Insert a space after a char */ if (u8CursorX < 128) /* Check if this is the last char of the line */ { if ((toto->u8Height) > 8) { LcdInstructionWrite (X_ADRESS + u8CursorY - 1,right); /* Select the page of the LCD */ LcdInstructionWrite (Y_ADRESS + u8CursorX,right); LcdDataWrite(0x00,right); LcdInstructionWrite (Y_ADRESS + u8CursorX -u8RightSide,right); } LcdInstructionWrite (X_ADRESS + u8CursorY,right); /* Select the page of the LCD */ LcdInstructionWrite (Y_ADRESS + u8CursorX,right ); LcdDataWrite(0x00,right); /* if not then insert a space before next letter */ } u8CharColumn++; u8CursorX++; } */