///////////////////////////////////////////////////////////////////////// //// //// //// This file contains drivers for using a Tosiba T6963C controller //// //// in parallel/8080(intel) mode. The T6963C is 240 pixels across //// //// and 128 pixels down. The driver treats the upper left pixel 0,0 //// //// MPU is Microchip PIC16F887 in PICkit2 44-pin Demo Board //// //// //// ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// //// //// //// Connections are as follows: //// //// /CE - - C3 //// //// /WR - - C4 //// //// /RD - - C5 //// //// C/D - - C6 //// //// /RST- - C7 //// //// DATA0-7 - - PORTD0-7 //// //// LCD's FS is tied low (FS = 0 is 8x8 font) //// //// //// ///////////////////////////////////////////////////////////////////////// // 240 x 128 in the 8x8 font mode means that 30 characters across by // 8 rows of characters may be displayed // // Note: // A zero on FS will place a 5x7 pixel character in a 8x8 field.(30 char/line)<---this program // A one on FS will place a 5x7 pixel character in a 6x8 field. (240/6=40 char /line) #include <16F887.h> #device *=16 #use delay(clock=8000000) #fuses INTRC_IO, NOWDT, PUT, NOPROTECT, NOBROWNOUT #use fast_io(D) #define set_tris_lcd(x) set_tris_d(x) //TRIS DataBus=x, note:control bus (PORTC) always outputs const int16 TextHome=0x0F00; //(240*128)/8=3840-->0x0F00 const int8 TextArea=0x001E; // how many bytes before a new line (30 bytes) const int16 GraphicsHome=0x0000; const int8 GraphicsArea=0x001E; // how many bytes before a new line (30 bytes) const int8 AutoModeWrite=0xB0; //DataAutoWrite const int8 AutoModeRead=0xB1; //DataAutoRead const int8 AutoModeReset=0xB2; //Auto reset const int8 LCDModeSet = 0x80; // send this OR'd with the following const int8 LCDMode_OR = 0b0000; const int8 LCDMode_XOR = 0b0001; const int8 LCDMode_AND = 0b0010; const int8 LCDMode_TA = 0b0100; // TEXT ATTRIBUTE mode. const int8 LCDMode_RAM = 0b1000; // 1=CG RAM, 0=internal CG ROM const int8 LCDSetCursorPtr = 0x21; // cursor address const int8 LCDSetCursorSize = 0xA0; // 1 line cursor const int8 LCDDispMode = 0x90; // send this OR'd with the following const int8 LCDDisp_BLK = 0b0011; // Blink Cursor const int8 LCDDisp_CUR = 0b0010; // Add Cursor const int8 LCDDisp_TXT = 0b0100; //Text-OK,Graphic-NG const int8 LCDDisp_GRH = 0b1000; //Text-NG,Graphic-OK const int8 LCDBitSet = 0xF8; const int8 LCDBitReset = 0xF0; struct lcd_pin_def //Struct type bitfield { int1 unused1 :1; // C0 int1 unused2 :1; // C1 int1 unused3 :1; // C2 int1 ce :1; // C3 Chip enable active low int1 w_bar :1; // C4 Write bar active low int1 r_bar :1; // C5 Read bar active low int1 cd :1; // C6 Command/Data BAR 1=command 0=data int1 reset_bar :1; // C7 Reset active low int8 data :8; // PortD=Data bus(address=8) }; struct lcd_pin_def LCD; #byte LCD = 7 // portC address=7 on 16F887 //Prototyping int glcd_ReadByte(void); void glcd_WriteByte(int1 cd, int data); void glcd_WriteByteAuto(int data); void glcd_WriteCmd2(int16 data, int cmd); void glcd_WriteCmd1(int data, int cmd); void glcd_gotoxy(int x, int y, int1 text); #include "samurai.c" /////////////////////////////////////// bitmap data table [samurai] g_image1[n]~g_image16[n] void glcd_init(void) { int16 counter; set_tris_lcd(0x00); //TRIS DATA bus(PORT D),note:control bus always outputs LCD.ce=0; //INITIAL STATES OF CONTROL PINS LCD.w_bar=1; // LCD.r_bar=1; // LCD.cd=1; // command LCD.reset_bar=0; // perform a reset delay_us(10); // delay for a reset LCD.reset_bar = 1; // run // Set up the graphics and text areas glcd_WriteCmd2(TextHome, 0x40); //TextHomeAddress Set glcd_WriteCmd2(TextArea, 0x41); //TextArea column Set glcd_WriteCmd2(GraphicsHome, 0x42); //GraphicHomeAddress Set glcd_WriteCmd2(GraphicsArea, 0x43); //GraphicArea column Set // set AddressPointer to 0 glcd_WriteCmd2(0x0000, 0x24); //Set AddressPointer to 0 // Clear all RAM of LCD (32k) glcd_WriteByte(1, AutoModeWrite); //Set Data Auto Write for (counter = 0; counter < 0x7fff; counter++) //0x7FFF=32767 bytes { glcd_WriteByteAuto(0); // fill everything with zeros } glcd_WriteByte(1, AutoModeReset); } void glcd_WriteByte(int1 cd, int data) //Write PORTD as command or data in "Normal" mode. { int status = 0, temp = 0; set_tris_lcd(0xff); // All inputs LCD.ce = 1; LCD.w_bar = 1; LCD.r_bar= 1; LCD.cd = 1;//defaults while (status != 0x03) { // is LCD busy? LCD.r_bar= 0; LCD.ce = 0; //After 150ns read the data on D0-7 #asm nop #endasm temp = LCD.data; LCD.ce = 1; LCD.r_bar = 1; status = temp & 0x03; //Masking } set_tris_lcd(0x00); // All outputs LCD.cd = cd; // Command/Data bar (1=command 0=data) LCD.data = data; // Put data on data bus LCD.ce = 0; LCD.r_bar = 1; // not read LCD.w_bar = 0; // write LCD.ce = 1; LCD.w_bar = 1; // release } void glcd_WriteByteAuto(int data) //Write PORTD as data in "Auto" mode. { int status = 0, temp = 0; // WHEN Auto mode,the status bits ARE DIFFERENT BITS THAN NORMAL MODE set_tris_lcd(0xff); // All inputs LCD.ce = 1; LCD.w_bar = 1; LCD.r_bar = 1; LCD.cd = 1; // defaults while (status != 0x08) // is LCD busy? Checking STA3! { LCD.r_bar = 0; LCD.ce =0; //After 150ns read the data on D0-7 #asm nop #endasm temp = LCD.data; LCD.ce = 1; LCD.r_bar = 1; status = temp & 0x08; //Masking } set_tris_lcd(0x00); // All outputs LCD.cd = 0; // This is always data LCD.data = data; // Put data on data bus LCD.ce = 0; LCD.r_bar = 1; // not read LCD.w_bar = 0; // write LCD.ce = 1; LCD.w_bar = 1; // release } void glcd_WriteCmd1(int data, int cmd) { glcd_WriteByte(0, data); glcd_WriteByte(1, cmd); } void glcd_WriteCmd2(int16 data, int cmd) { glcd_WriteByte(0, data & 0xff); //masking,LSB Set glcd_WriteByte(0, data>>8); //shift right 8bir,MSB Set glcd_WriteByte(1, cmd); } int glcd_ReadByte(void) { int data = 0, status = 0, temp = 0; set_tris_lcd(0xff); // All inputs LCD.ce = 1; LCD.w_bar = 1; LCD.r_bar = 1; LCD.cd = 1; // defaults #asm nop #endasm while (status != 0x03) // is LCD busy? { LCD.r_bar = 0; LCD.ce = 0; temp = LCD.data; LCD.ce = 1; LCD.r_bar = 1; status = temp & 0x03; //Masking } LCD.cd = 0; // Command/Data bar LCD.ce = 0; LCD.r_bar = 0; // read ///////////////////////////////////////////////////////// #asm nop #endasm // THIS PAUSE IS VERY NESSESARY !!!// ///////////////////////////////////////////////////////// data = LCD.data; LCD.r_bar = 1; LCD.ce = 1; LCD.cd = 1; return data; // Return the read data } void glcd_putc(char c) { glcd_WriteCmd1(c - 0x20, 0xc0); //c-0x20=Transfer from Ascii Code, Data Write UP. } void glcd_gotoxy(int x, int y, int1 text) { // sets memory location to screen location x, y // location 1,1 is upper left corner; // text = 1 (text area), text = 0 (graphics area) int16 location, home; int line; if (!text) { home = GraphicsHome; line = GraphicsArea; } else { home = TextHome; line = TextArea; } location = home + (((int16)y - 1) * line) + x - 1; glcd_WriteCmd2(location, 0x24); } Void clear_screen(void){ //very simular to the glcd_init(void) int16 counter; // set address to 0 glcd_WriteCmd2(0x0000, 0x24); //Set AddressPointer to 0 // Clear all RAM of LCD (32k) glcd_WriteByte(1, AutoModeWrite); //Set Data Auto Write for (counter = 0; counter < 0x7fff; counter++) //0x7fff=32767 bytes { glcd_WriteByteAuto(0); // fill everything with zeros } glcd_WriteByte(1, AutoModeReset); } unsigned int8 i; //General Purpouse variable // glcd_pixel8(x,y,px8) sets 8 pixels in line. void glcd_pixel8(unsigned int8 x, unsigned int8 y, int8 pixel8){ unsigned int8 x_H; x_H = (x / 8); glcd_gotoxy(x_H+1,y,0); glcd_WriteCmd1(pixel8,0xc0); //Write data and increament } // glcd_pixel(x,y,c) sets pixel x,y with c color void glcd_pixel(unsigned int8 x, unsigned int8 y, int1 c){ unsigned int8 x_H; unsigned int8 x_L=0; x_H = (x / 8); x_L = 7 - (x - 8*x_H); glcd_gotoxy(x_H+1,y,0); if(c){ glcd_WriteCmd1(1,(LCDBitSet|x_L)); } else { glcd_WriteCmd1(1,(LCDBitReset|x_L)); } } // glcd_line(x0,y0, x1,y1, c) puts line from (x0, y0) to (x1, y1) with c color //#separate void glcd_line(signed int16 x0, signed int16 y0, signed int16 x1, signed int16 y1 , int1 c){ int16 x; int16 y; unsigned int16 n; int1 m_case; x=abs(x1-x0); y=abs(y1-y0); if (y > x){ n=(y1-y0); m_case=1; } else { n=(x1-x0); m_case=0; } for(i=0 ; i<=n ; i++){ if (m_case){ y=i + y0; x=(y*(x1-x0))/(y1-y0) + x0; } else { x=i + x0; y=(x*(y1-y0))/(x1-x0) + y0; } glcd_pixel(x, y,c); } } // glcd_square(x0,y0,x1,y1, c) sets square void glcd_square( unsigned int8 x0, unsigned int8 y0, unsigned int8 x1, unsigned int8 y1 , int1 c){ glcd_line(x0,y0, x1,y0, c); glcd_line(x1,y0, x1,y1, c); glcd_line(x0,y1, x1,y1, c); glcd_line(x0,y0, x0,y1, c); } // glcd_box(x0,y0,x1,y1, c) void glcd_box( unsigned int8 x0, unsigned int8 y0, unsigned int8 x1, unsigned int8 y1 , int1 c){ unsigned int8 x; unsigned int8 y; for(y=y0; y<=y1;y++){ for(x=x0; x<=x1;x++){ if((!(x%8)) && ((x1-x)>8)){ glcd_pixel8(x,y,0xFF*c); //Same time to write 8 pixel x +=7 ; } else { glcd_pixel(x,y,c); } } } } //glcd_image8 (*Pic, x, y, size_x, size_y) void glcd_image8(int8 *pic_px, unsigned int8 x, unsigned int8 y, unsigned int8 size_x, unsigned int8 size_y){ unsigned int8 px_y; unsigned int8 px_x; unsigned int8 px=0; for(px_y=y; px_y<(y+size_y); px_y++){ for(px_x=x; px_x<(x+size_x); px_x+=8){ glcd_pixel8(px_x, px_y, *(pic_px+px)); px+=1; } } } void image_drawing(void) // Free image file drawing { int n; glcd_WriteCmd2(0x0000, 0x24); //Set AddressPointer to 0 for (n=0; n<240 ; n++) //最上位の240*128dots分を描画 { glcd_WriteCmd1(g_image1[n],0xc0); //Write data and increament }n=0; for (n=0; n<240 ; n++) //2段目描画 { glcd_WriteCmd1(g_image2[n],0xc0); }n=0; for (n=0; n<240 ; n++) //3段目描 { glcd_WriteCmd1(g_image3[n],0xc0); }n=0; for (n=0; n<240 ; n++) //4段目描画 { glcd_WriteCmd1(g_image4[n],0xc0); }n=0; for (n=0; n<240 ; n++) //5段目描画 { glcd_WriteCmd1(g_image5[n],0xc0); }n=0; for (n=0; n<240 ; n++) //6段目描画 { glcd_WriteCmd1(g_image6[n],0xc0); }n=0; for (n=0; n<240 ; n++) //7段目描画 { glcd_WriteCmd1(g_image7[n],0xc0); }n=0; for (n=0; n<240 ; n++) //8段目描画 { glcd_WriteCmd1(g_image8[n],0xc0); } for (n=0; n<240 ; n++) //9段目描画 { glcd_WriteCmd1(g_image9[n],0xc0); }n=0; for (n=0; n<240 ; n++) //10段目描 { glcd_WriteCmd1(g_image10[n],0xc0); }n=0; for (n=0; n<240 ; n++) //11段目描画 { glcd_WriteCmd1(g_image11[n],0xc0); }n=0; for (n=0; n<240 ; n++) //12段目描画 { glcd_WriteCmd1(g_image12[n],0xc0); }n=0; for (n=0; n<240 ; n++) //13段目描画 { glcd_WriteCmd1(g_image13[n],0xc0); }n=0; for (n=0; n<240 ; n++) //14段目描画 { glcd_WriteCmd1(g_image14[n],0xc0); }n=0; for (n=0; n<240 ; n++) //15段目描画 { glcd_WriteCmd1(g_image15[n],0xc0); }n=0; for (n=0; n<240 ; n++) //16段目描画 { glcd_WriteCmd1(g_image16[n],0xc0); }n=0; } /////////////////////////////////////////////////////////////////////////// void main() { int8 bt_logo[11] = { //8x11 picture 0b00100000, // XX 0b00110000, // XXXX 0b00111000, // XXXXXX 0b11111100, // XXXXXXXXXXXX 0b11111110, // XXXXXXXXXXXXXX 0b11111111, // XXXXXXXXXXXXXXXX 0b11111110, // XXXXXXXXXXXXXX 0b11111100, // XXXXXXXXXXXX 0b00111000, // XXXXXX 0b00110000, // XXXX 0b00100000 // XX }; set_tris_c(0x00); // graphic lcd control lines always output glcd_init(); //Initialization glcd_WriteByte(1, (LCDModeSet|LCDMode_XOR)); //XOR-Mode glcd_WriteByte(1, (LCDDispMode|LCDDisp_TXT|LCDDisp_GRH)); //Text and Graphic-Mode delay_ms(200); While (1) { //"Santech...." beginning at screen location column 3, row 2 // 1 = text area of memory; note that there are only 8 rows of text possible glcd_gotoxy(3,1,1); glcd_putc("Santech Display Co.,Ltd."); glcd_gotoxy(7,2,1); glcd_putc("P/N:SD-G240128A"); glcd_gotoxy(1,3,1); glcd_putc("240*128dots STN-LCD module"); glcd_gotoxy(1,4,1); glcd_putc("Built-in negative voltage and YellowGreen LED Backlight"); glcd_gotoxy(1,5,1); glcd_putc("Controller : Toshiba T6963C"); glcd_gotoxy(1,6,1); glcd_putc("Standard 128-word Character Generator ROM"); glcd_gotoxy(1,7,1); glcd_putc("32KB External Display S-RAM"); glcd_gotoxy(1,8,1); glcd_putc("View Area:114.0*64.0mm"); glcd_gotoxy(4,9,1); glcd_putc("www.santechdisplay.co.jp"); glcd_gotoxy(1,10,1); glcd_putc("E-Mail lcdinfo@santechdisplay.co.jp"); glcd_gotoxy(1,11,1); glcd_putc("Addr:Sendai-City,Miyagi,Japan"); glcd_box(12,80,40,110,1); glcd_box(22,90,32,100,0); glcd_square(50,90,70,120,1); glcd_line(80,105,150,105,1); glcd_line(80,100,80,110,1); glcd_line(150,100,150,110,1); glcd_image8(&bt_logo[0],160,100,8,11); glcd_image8(&bt_logo[0],180,100,8,11); glcd_image8(&bt_logo[0],200,100,8,11); glcd_image8(&bt_logo[0],220,100,8,11); delay_ms(3000); clear_screen(); image_drawing(); //240*128dotsのフル画像描画 Draw Samrai delay_ms(5000); clear_screen(); } }