//------------------------------------------------- // Shenzhen TOPWAY Technology Co.,Ltd. // System: AT89S52(12MHz) // LCD Module: Color 5.6" TFT 640x480 // Display Size: 640(x3)x480 (16bit color) // Driver/Controller: SSD1963 // Interface: generic mode 1bit_Add 16bit_data // with touch panel // by: Kenny // rev 01: 2011-12-01 // new // rev 02: 2013-05-29 // frame freq=68Hz for better display result // note: example program //------------------------------------------------- #include #include #include #include #define uchar unsigned char // 8bit, 0 ~ 255 #define uint unsigned int // 16bit, 0 ~ 65,535 #define ulong unsigned long // 32bit, 0 ~ 4,294,967,295 uchar xdata CmdPort _at_ 0x0000; uchar xdata DataPort _at_ 0x8000; // using 8051 RAM bus as // LCD.RS connect 8051.A15 // LCD.WR connect 8051.WR // LCD.RD connect 8051.RD // i.e. // pointer 0x0nnn for RS=0 // pointer 0x8nnn for RS=1 #define LCD_Data_Hi P1 // using IO as LCD.D8~LCD.D15 data bus sbit _CS = P3^2; sbit _RST = P3^4; sbit _TP_CS = P3^0; // TP.CS sbit TP_DCLK = P1^0; sbit TP_DIN = P1^1; // sbit TP_BUSY = P1^2; // no use this signal sbit TP_DOUT = P1^3; sbit _TP_PENQ= P3^3; // 0 = touched uchar bdata btemp; // create a bit accessable byte sbit btemp_b0 = btemp^0; sbit btemp_b3 = btemp^3; sbit btemp_b7 = btemp^7; uchar BL_Brightness; // 0~ff value (0%~100%) uchar TP_x; // TP data after touch uchar TP_y; #define RED 0xf800 #define GREEN 0x07e0 #define BLUE 0x001f #define YELLOW 0xffe0 #define CYAN 0x07ff #define MAGENTA 0xf81f #define BLACK 0x0000 #define WHITE 0xffff #define mid_re 0x8000 #define mid_or 0x8200 #define mid_ye 0x8400 #define mid_yg 0x4400 #define mid_gr 0x0400 #define mid_gc 0x0408 #define mid_cy 0x0410 #define mid_cb 0x0210 #define mid_bl 0x0010 #define mid_bm 0x4010 #define mid_ma 0x8010 #define mid_mr 0x8010 #define GRAY00 0x0000 #define GRAY01 0x1082 #define GRAY02 0x2104 #define GRAY03 0x3186 #define GRAY04 0x4208 #define GRAY05 0x528a #define GRAY06 0x630c #define GRAY07 0x738e #define GRAY08 0x8410 #define GRAY09 0x9492 #define GRAY10 0xa514 #define GRAY11 0xb596 #define GRAY12 0xc618 #define GRAY13 0xd69a #define GRAY14 0xe71c #define GRAY15 0xffff //----------------------------------- // delayms routine //----------------------------------- void delayms(uint m) // 12MHz Xtal, close to ms value { uint j; uint i; for(i=0; i>8; // prepare the high byte data // only hi byte to the port LCD_Data_Hi=temp; _CS=0; CmdPort = LCD_Data; // write the low byte (toggle /WR) _CS=1; } void SdData(uint LCD_Data) // Write LCD as RAM // for 16 bit access D0~D7 = for low 8bit // for 16 bit access D8~D15 = for high 8bit { uchar temp; temp=LCD_Data>>8; // prepare the high byte data // only hi byte to the port LCD_Data_Hi=temp; _CS=0; DataPort = LCD_Data; // write the low byte (toggle /WR) _CS=1; } //----------------------------------- // Touch Panel Commands //----------------------------------- uchar TP_IO8(uchar Command) // send a command // and return 8bit conversion result // Command bits(MSB to LSB): S,A2,A1,A0,MODE,SER/DFR,PD1,PD0 { uchar i; btemp=Command; // copy the command to a bit accessible variable btemp_b3=1; // set the MODE to 8bit only TP_DOUT=1; // pull up for read TP_DCLK=0; // prepare for data trans transfer _TP_CS=0; // select the touch panel IO for(i=0;i<8;i++) // write command with 1st to 8th DCLK { TP_DIN = btemp_b7; TP_DCLK=1; TP_DCLK=0; btemp=btemp<<1; } // delayms(1); // delay for 12bit conversion for(i=0;i<8;i++) // read data { btemp=btemp<<1; TP_DCLK=1; TP_DCLK=0; btemp_b0=TP_DOUT; } _TP_CS=1; for(i=0;i<8;i++) // PenIrq will be re-enable at 21st CLK { // thus 8 dummy clock provided TP_DCLK=1; TP_DCLK=0; } return(btemp); } void GetTouchResponse(void) { uchar x, y; uchar i, j ; uchar Verified_AD; // flag for verified AD uchar wait; // wait flag for deounced Verified_AD=0; wait=1; while (Verified_AD==0) { while(_TP_PENQ){} // ensure it is touched then start AD i = TP_IO8(0xd8)>>3; // X-Ch, 8bit, LoPw, with PenInt j = (TP_IO8(0x98)-0x02)>>3; // Y-Ch, 8bit, LoPw, with PenInt // offset Y result by 2 delayms(30); // de-bouncing while(_TP_PENQ){} // ensure it is touched then start AD x = TP_IO8(0xd8)>>3; // X-Ch, 8bit, LoPw, with PenInt y = (TP_IO8(0x98)-0x02)>>3; // Y-Ch, 8bit, LoPw, with PenInt // offset Y result by 2 delayms(30); // de-bouncing if ((i==x) && (j==y) && (!_TP_PENQ)) // ensure two results are the same { // and still touching Verified_AD=1; } } TP_x=x; TP_y=y; } //----------------------------------- // Draw Commands //----------------------------------- void Box140x100(uint X, Y, uint color) // fill a box with solid color { uint temp1, temp2; uint i; #define box_w 140 // (box_w * box_h) must be divisible by 8 #define box_h 100 SdCmd(0x002a); // set_column_address temp1 = X>>8; // move the upper byte to low byte temp2 = X&0x00ff; // mask the upper byte SdData(temp1); SdData(temp2); X=X+box_w-1; temp1 = X>>8; // move the upper byte to low byte temp2 = X&0x00ff; // mask the upper byte SdData(temp1); SdData(temp2); SdCmd(0x002b); // set_page_address temp1 = Y>>8; // move the upper byte to low byte temp2 = Y&0x00ff; // mask the upper byte SdData(temp1); SdData(temp2); Y=Y+box_h-1; temp1 = Y>>8; // move the upper byte to low byte temp2 = Y&0x00ff; // mask the upper byte SdData(temp1); SdData(temp2); SdCmd(0x002c);// write_memory_start _CS=0; // direct access the data port for speed LCD_Data_Hi=color>>8; for (i=0; i<((box_w*box_h)/8); i++) { DataPort=color; DataPort=color; DataPort=color; DataPort=color; // write the low byte (toggle /WR) DataPort=color; DataPort=color; DataPort=color; DataPort=color; // write the low byte (toggle /WR) } _CS=1; } void RadColorBox40x30(uint X_loc, Y_loc) // fill a box with solid color { uint temp1, temp2, color; uint X,Y; uint i; #define RCbox_w 40 // (RCbox_w* h) must be divisible by 8 #define RCbox_h 30 color= rand()+rand(); // set random foreground color if (X_loc==0) {X_loc=1;} if (Y_loc==0) {Y_loc=0;} X=X_loc; X=((X*(640/32)-(20))); // 20 is location offset Y=Y_loc; Y=((Y*(480/32))); SdCmd(0x002a); // set_column_address temp1 = X>>8; // move the upper byte to low byte temp2 = X&0x00ff; // mask the upper byte SdData(temp1); SdData(temp2); X=X+RCbox_w-1; temp1 = X>>8; // move the upper byte to low byte temp2 = X&0x00ff; // mask the upper byte SdData(temp1); SdData(temp2); SdCmd(0x002b); // set_page_address temp1 = Y>>8; // move the upper byte to low byte temp2 = Y&0x00ff; // mask the upper byte SdData(temp1); SdData(temp2); Y=Y+RCbox_h-1; temp1 = Y>>8; // move the upper byte to low byte temp2 = Y&0x00ff; // mask the upper byte SdData(temp1); SdData(temp2); SdCmd(0x002c);// write_memory_start _CS=0; // direct access the data port for speed LCD_Data_Hi=color>>8; for (i=0; i<((RCbox_w*RCbox_h)/8); i++) { DataPort=color; DataPort=color; DataPort=color; DataPort=color; // write the low byte (toggle /WR) DataPort=color; DataPort=color; DataPort=color; DataPort=color; // write the low byte (toggle /WR) } _CS=1; } void FullScnColor(uint color) // fill 640x480 with color { uint i; SdCmd(0x002a); // set_column_address SdData(0x0000); SdData(0x0000); // start address SdData(0x0002); SdData(0x007f); // end address SdCmd(0x002b); // set_page_address SdData(0x0000); SdData(0x0000); // start address SdData(0x0001); SdData(0x00df); // end address SdCmd(0x002c); // write_memory_start _CS=0; // direct access the data port for speed LCD_Data_Hi=color>>8; for (i=0; i<0x9600; i++) { DataPort=color; DataPort=color; DataPort=color; DataPort=color; // write the low byte (toggle /WR) DataPort=color; DataPort=color; DataPort=color; DataPort=color; // write the low byte (toggle /WR) } _CS=1; } //----------------------------------- // INIT Commands //----------------------------------- void init(void) { _RST=1; delayms(10); // wait for all power stable _RST=0; delayms(1); // reset pulse _RST=1; delayms(10); // wait till internal reset routine finish SdCmd(0x00e2); SdData(0x003B); SdData(0x0002); SdData(0x0004); delayms(10); // config PLL to 200MHz SdCmd(0x00e0); SdData(0x0001); delayms(10); // enable PLL SdCmd(0x00e0); SdData(0x0003); delayms(10); // switch to use PLL clock SdCmd(0x0011); // exit_sleep_mode SdCmd(0x0013); // enter_normal_mode (exit_partial_mode) SdCmd(0x0020); // exit_invert_mode SdCmd(0x0038); // exit_idle_mode (using full color) SdCmd(0x00B8); // set_gpio_conf SdData(0x000f); // GPIO[0~3] controlled by host SdData(0x0001); // GPIO0 as normal GPIO SdCmd(0x00ba); SdData(0x0001); delayms(10); // GPIO[0~3]=0001, enable DC-CD booster SdCmd(0x00ba); SdData(0x0003); delayms(10); // GPIO[0~3]=0011, enable backlight booster SdCmd(0x00f0); SdData(0x0003); // set_pixel_data_interface (MCU) 16bit(5:6:5) SdCmd(0x00b0); // set_lcd_mode SdData(0x0004); // 18bit, disable FRC or dithering, DCLK=rising edge SdData(0x0020); // HSYNC=active lo, VSYNC=active low, default TFT m SdData(0x0002); SdData(0x007f); // panel size 640-1 SdData(0x0001); SdData(0x00df); // panel size 480-1 SdCmd(0x00b4); // set_hori_period SdData(0x0003); SdData(0x001f); // total pluse per line, HT=800-1 SdData(0x0000); SdData(0x009f); // horizontal back porch, HPS=160-1 SdData(0x0007); // HPW=0x07(default), not use SdData(0x0000); SdData(0x0000); // LPS=0x0000(default), not use SdData(0x0000); // LPSPP=0x00(default), not use SdCmd(0x00b6); // set_vert_period SdData(0x0002); SdData(0x000c); // total line per frame, VT=525-1 SdData(0x0000); SdData(0x002c); // vertical back porch, VPS=45-1 SdData(0x0001); // VPW=0x01(default), not use SdData(0x0000); SdData(0x0000); // FPS=0x0000(default), not use // SdCmd(0x00e6); SdData(0x0001); SdData(0x00e0); SdData(0x0000);// config PCLK=40ns(PLL@200MHz) SdCmd(0x00e6); SdData(0x0002); SdData(0x0050); SdData(0x0000);// config PCLK=35ns(PLL@200MHz)68Hz SdCmd(0x0036); // set_address_mode SdData(0x0000); // top to bottom, left to right, RGB, normal SdCmd(0x00be); // set_pwm_conf SdData(0x0000); // PWM clock set to 3kHz (PLL@200MHz) SdData(150); // PWM width at 60% SdData(0x0001); // C[3]=0, non_DBC control; C[0]=1, enable PWM SdData(0x00f0); // DBC manual level at middle SdData(0x0000); // DBC minimum lever at middle SdData(0x0000); // disable the DBC response delay setting SdCmd(0x0029); // display on } //----------------------------------- // Main Program主程序 //----------------------------------- void main() { EA=0; // no interrupt _CS = 1; _RST = 1; _TP_CS = 1; // TP.CS TP_DCLK = 0; TP_DIN = 0; TP_DOUT = 1; _TP_PENQ= 1; // 0 = touched init(); FullScnColor(BLACK); Box140x100( 15, 15, mid_re); Box140x100(171, 15, mid_or); Box140x100(327, 15, mid_ye); Box140x100(483, 15, mid_yg); Box140x100(483,131, mid_gr); Box140x100(483,247, mid_gc); Box140x100(483,363, mid_cy); Box140x100(327,363, mid_cb); Box140x100(171,363, mid_bl); Box140x100( 15,363, mid_bm); Box140x100( 15,247, mid_ma); Box140x100( 15,131, mid_mr); while(1) { GetTouchResponse(); // ressult store in TP_x and TP_y RadColorBox40x30(TP_x, TP_y); delayms(100); } }