/* * 液晶モジュールドライバ for PIC32MX1xx/2xx * 対応液晶モジュール * 2.4インチ液晶モジュール M024C9320TP 液晶コントローラ R61505 * 2.0インチ液晶モジュール AT020QVS   液晶コントローラ ILI9325 * 2.6インチ液晶モジュール TFT1N3204-E 液晶コントローラ R61505W * * システムクロック48MHz、周辺クロック48MHz * * 下記サイトのプログラムを参照 * http://blog.tkjelectronics.dk/2010/03/arduino-mega-and-ili9320-display/ * http://miha.jugem.cc/?eid=118 * http://nemuisan.blog.bai.ne.jp/?eid=192848 * * 8bit mode接続 * D8 RB0 * D9 RB1 * D10 RB2 * D11 RB3 * D12 RB4 * D13 RB5 * D14 RB7 * D15 RB8 * RS RB9 * WR RB10 * CS RB11 * RD RB13 * RESET RB14 */ #include #include "LCDdriver.h" volatile unsigned short drawcount; volatile unsigned short delaytimerflag; /********************** * Timer2 割り込み処理関数 ***********************/ void __ISR(8, ipl4) T2Handler(void) { drawcount++; IFS0bits.T2IF = 0; // T2割り込みフラグクリア } /********************** * Timer5 割り込み処理関数 ***********************/ void __ISR(20, ipl4) T5Handler(void) { delaytimerflag=1; IFS0bits.T5IF = 0; // T5割り込みフラグクリア } void delay_us(int t){ // tマイクロ秒のウェイト delaytimerflag=0; PR5 = 48*t; // tマイクロ秒 T5CONSET=0x8000; while(delaytimerflag==0) asm("wait"); // sleepで待機 T5CONCLR=0x8000; } void delay_ms(int t){ while(t>0){ delay_us(1000); t--; } } void inline LCD_set_dat(unsigned char c){ LCD_DATCLR=LCD_DAT_MASK; LCD_DATSET=((c<<1)&0x180)+(c&0x3f); } unsigned char LCD_get_dat(void){ unsigned short d; d=PORTB & LCD_DAT_MASK; return ((d&0x180)>>1)+(d&0x3f); } void LCD_WriteIndex(unsigned char index){ // Write Index LCD_RS_LO; LCD_set_dat(0); LCD_WR_LO; asm("nop"); LCD_WR_HI; LCD_set_dat(index); LCD_WR_LO; asm("nop"); LCD_WR_HI; } void LCD_WriteData(unsigned short data) { // Write Data LCD_RS_HI; LCD_set_dat(data>>8); LCD_WR_LO; asm("nop"); LCD_WR_HI; LCD_set_dat((unsigned char)data); LCD_WR_LO; asm("nop"); LCD_WR_HI; } unsigned short LCD_ReadData(void) { // Read Data unsigned short d; TRISBSET=LCD_DAT_MASK; LCD_RS_HI; LCD_RD_LO; asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); d=LCD_get_dat(); LCD_RD_HI; asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); LCD_RD_LO; asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); d=(d<<8)+LCD_get_dat(); LCD_RD_HI; asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); TRISBCLR=LCD_DAT_MASK; return d; } void LCD_WriteReg(unsigned char index, unsigned short data) { // Write Index LCD_WriteIndex(index); // Write Data LCD_WriteData(data); } unsigned short LCD_ReadReg(unsigned char index) { // Write Index LCD_WriteIndex(index); // Read Data return LCD_ReadData(); } void LCD_Init() { int id; LCD_CS_HI; // Disable LCD LCD_RESET_LO; // Hold in reset LCD_RS_LO; LCD_RD_HI; LCD_WR_HI; // Reset controller LCD_RESET_LO; delay_ms(2); LCD_RESET_HI; delay_ms(2); LCD_CS_LO; // Enable LCD id=LCD_ReadReg(0); switch(id){ case 0x9328: // S95417AAA (読み出されるid=0x9328になるが、ILI9325互換なので同じ設定でOK) // これを追記しないと、defultの、R61505の設定になり、上下左右逆さ表示になってしまう。170422 N.Ishii case 0x9325: //AT020QVS (ILI9325) #if LCD_ALIGNMENT == VERTICAL LCD_WriteReg(0x01, 0x0100); //Driver output control (1) LCD_WriteReg(0x03, 0x1030); //Entry mode #elif LCD_ALIGNMENT == HORIZONTAL LCD_WriteReg(0x01, 0x0000); //Driver output control (1) LCD_WriteReg(0x03, 0x1028); //Entry mode #endif LCD_WriteReg(0x02, 0x0700); //LCD driving control LCD_WriteReg(0x04, 0x0000); //Resize control LCD_WriteReg(0x08, 0x0202); //Display control (2) LCD_WriteReg(0x09, 0x0000); //Display control (3) /*** Power Control ***/ LCD_WriteReg(0x10, 0x0000); LCD_WriteReg(0x11, 0x0007); //power control 2 DC, VC LCD_WriteReg(0x12, 0x0000); //power control 3 VRH LCD_WriteReg(0x13, 0x0000); //power control 4 VCOM amplitude delay_ms(200); LCD_WriteReg(0x10, 0x16B0); //power control 1 BT,AP LCD_WriteReg(0x11, 0x0227); //power control 2 DC,VC delay_ms(50); LCD_WriteReg(0x12, 0x001c); //power control 3 VRH delay_ms(50); LCD_WriteReg(0x13, 0x0A00); //power control 4 vcom amplitude LCD_WriteReg(0x29, 0x000F); //power control 7 VCOMH LCD_WriteReg(0x2b, 0x000d); //Frame rate delay_ms(50); LCD_WriteReg(0x20, 0x0000); //Horizontal GRAM Address Set LCD_WriteReg(0x21, 0x0000); //Vertical GRAM Address Set LCD_WriteReg(0x50, 0x0000); //Horizontal Address Start Position LCD_WriteReg(0x51, 0x00EF); //Horizontal Address end Position (239) LCD_WriteReg(0x52, 0x0000); //Vertical Address Start Position LCD_WriteReg(0x53, 0x013F); //Vertical Address end Position (319) LCD_WriteReg(0x60, 0xa700); //Driver Output Control 2 // LCD_WriteReg(0x61, 0x0001); //Base Image Display Control LCD_WriteReg(0x61, 0x0003); //Base Image Display Control LCD_WriteReg(0x6a, 0x0000); //Base Image Display Control LCD_WriteReg(0x90, 0x0010); //Panel Interface Control 1 LCD_WriteReg(0x92, 0x0000); //Panel Interface Control 2 LCD_WriteReg(0x93, 0x0000); //Panel Interface Control 3 /*** GAMMA Control ***/ LCD_WriteReg(0x30, 0x0007); LCD_WriteReg(0x31, 0x0403); LCD_WriteReg(0x32, 0x0404); LCD_WriteReg(0x35, 0x0002); LCD_WriteReg(0x36, 0x0707); LCD_WriteReg(0x37, 0x0606); LCD_WriteReg(0x38, 0x0106); LCD_WriteReg(0x39, 0x0007); LCD_WriteReg(0x3c, 0x0700); LCD_WriteReg(0x3d, 0x0707); LCD_WriteReg(0x07, 0x0173); break; case 0xc505: //TFT1N3204-E (R61505W) LCD_WriteReg(0x0000, 0x0001); LCD_WriteReg(0x0007, 0x0000); LCD_WriteReg(0x0010, 0x0410); LCD_WriteReg(0x0011, 0x0237); LCD_WriteReg(0x0012, 0x0199); LCD_WriteReg(0x0013, 0x1100); delay_ms(150); LCD_WriteReg(0x0012, 0x01b9); LCD_WriteReg(0x0002, 0x0200); #if LCD_ALIGNMENT == VERTICAL LCD_WriteReg(0x01, 0x0100); //Driver output control (1) LCD_WriteReg(0x03, 0x1030); //Entry mode #elif LCD_ALIGNMENT == HORIZONTAL LCD_WriteReg(0x01, 0x0000); //Driver output control (1) LCD_WriteReg(0x03, 0x1028); //Entry mode #endif LCD_WriteReg(0x0008, 0x0808); LCD_WriteReg(0x0009, 0x0001); LCD_WriteReg(0x000a, 0x0000); LCD_WriteReg(0x000c, 0x0000); LCD_WriteReg(0x000d, 0x0000); LCD_WriteReg(0x000e, 0x0030); LCD_WriteReg(0x0030, 0x0214); LCD_WriteReg(0x0031, 0x3715); LCD_WriteReg(0x0032, 0x0604); LCD_WriteReg(0x0033, 0x0e16); LCD_WriteReg(0x0034, 0x2211); LCD_WriteReg(0x0035, 0x1500); LCD_WriteReg(0x0036, 0x8507); LCD_WriteReg(0x0037, 0x1407); LCD_WriteReg(0x0038, 0x1403); LCD_WriteReg(0x0039, 0x0020); LCD_WriteReg(0x0050, 0x0000); LCD_WriteReg(0x0051, 0x00ef); LCD_WriteReg(0x0052, 0x0000); LCD_WriteReg(0x0053, 0x013f); LCD_WriteReg(0x0060, 0x2700); LCD_WriteReg(0x0061, 0x0003); LCD_WriteReg(0x006a, 0x0000); LCD_WriteReg(0x0090, 0x0015); LCD_WriteReg(0x0092, 0x0100); LCD_WriteReg(0x0093, 0x0701); LCD_WriteReg(0x0020, 0x0000); LCD_WriteReg(0x0021, 0x0000); delay_ms(80); LCD_WriteReg(0x0007, 0x0100); break; default: //M024C9320TP (R61505) LCD_WriteReg(0x0000, 0x0001); LCD_WriteReg(0x0007, 0x0001); delay_ms(5); LCD_WriteReg(0x0017, 0x0001); delay_ms(5); LCD_WriteReg(0x0010, 0x17b0); LCD_WriteReg(0x0011, 0x0007); LCD_WriteReg(0x0012, 0x011a); LCD_WriteReg(0x0013, 0x0f00); LCD_WriteReg(0x0015, 0x0000); LCD_WriteReg(0x0029, 0x0009); LCD_WriteReg(0x00fd, 0x0000); delay_ms(5); LCD_WriteReg(0x0012, 0x013a); delay_ms(50); LCD_WriteReg(0x0001, 0x0100); LCD_WriteReg(0x0002, 0x0700); #if LCD_ALIGNMENT == VERTICAL LCD_WriteReg(0x01, 0x0100); //Driver output control (1) LCD_WriteReg(0x03, 0x1030); //Entry mode #elif LCD_ALIGNMENT == HORIZONTAL LCD_WriteReg(0x01, 0x0000); //Driver output control (1) LCD_WriteReg(0x03, 0x1028); //Entry mode #endif LCD_WriteReg(0x0008, 0x0808); LCD_WriteReg(0x0009, 0x0000); LCD_WriteReg(0x000a, 0x0000); LCD_WriteReg(0x000c, 0x0000); LCD_WriteReg(0x000d, 0x0000); LCD_WriteReg(0x0030, 0x0000); LCD_WriteReg(0x0031, 0x0000); LCD_WriteReg(0x0032, 0x0000); LCD_WriteReg(0x0033, 0x0000); LCD_WriteReg(0x0034, 0x0000); LCD_WriteReg(0x0035, 0x0000); LCD_WriteReg(0x0036, 0x0000); LCD_WriteReg(0x0037, 0x0707); LCD_WriteReg(0x0038, 0x0707); LCD_WriteReg(0x0039, 0x0707); LCD_WriteReg(0x003a, 0x0303); LCD_WriteReg(0x003b, 0x0303); LCD_WriteReg(0x003c, 0x0707); LCD_WriteReg(0x003d, 0x0808); LCD_WriteReg(0x0050, 0x0000); LCD_WriteReg(0x0051, 0x00ef); LCD_WriteReg(0x0052, 0x0000); LCD_WriteReg(0x0053, 0x013f); LCD_WriteReg(0x0060, 0x2700); LCD_WriteReg(0x0061, 0x0003); LCD_WriteReg(0x006a, 0x0000); LCD_WriteReg(0x0090, 0x0010); LCD_WriteReg(0x0092, 0x0000); LCD_WriteReg(0x0093, 0x0000); LCD_WriteReg(0x0007, 0x0021); delay_ms(1); LCD_WriteReg(0x0007, 0x0061); delay_ms(50); LCD_WriteReg(0x0007, 0x0173); LCD_WriteReg(0x0020, 0x0000); LCD_WriteReg(0x0021, 0x0000); LCD_WriteReg(0x0022, 0x0000); LCD_WriteReg(0x0030, 0x0707); LCD_WriteReg(0x0031, 0x0407); LCD_WriteReg(0x0032, 0x0203); LCD_WriteReg(0x0033, 0x0303); LCD_WriteReg(0x0034, 0x0303); LCD_WriteReg(0x0035, 0x0202); LCD_WriteReg(0x0036, 0x001f); LCD_WriteReg(0x0037, 0x0707); LCD_WriteReg(0x0038, 0x0407); LCD_WriteReg(0x0039, 0x0203); LCD_WriteReg(0x003a, 0x0303); LCD_WriteReg(0x003b, 0x0303); LCD_WriteReg(0x003c, 0x0202); LCD_WriteReg(0x003d, 0x001f); LCD_WriteReg(0x0020, 0x0000); LCD_WriteReg(0x0021, 0x0000); } LCD_CS_HI; delay_ms(30); LCD_CS_LO; } void LCD_SetCursor(unsigned short x, unsigned short y) { #if LCD_ALIGNMENT == VERTICAL LCD_WriteReg(0x20, x); LCD_WriteReg(0x21, y); #elif LCD_ALIGNMENT == HORIZONTAL LCD_WriteReg(0x20, y); // LCD_WriteReg(0x20, Y_RES-1-y); LCD_WriteReg(0x21, x); #endif } void LCD_continuous_output(unsigned short x,unsigned short y,unsigned short color,int n) { //High speed continuous output int i; unsigned char d1,d2; LCD_SetCursor(x,y); LCD_WriteIndex(0x22); LCD_RS_HI; d1=color>>8; d2=(unsigned char)color; for (i=0; i < n ; i++){ LCD_set_dat(d1); LCD_WR_LO; asm("nop"); LCD_WR_HI; LCD_set_dat(d2); LCD_WR_LO; asm("nop"); LCD_WR_HI; } } void LCD_Clear(unsigned short color) { LCD_continuous_output(0,0,color,X_RES*Y_RES); } void drawPixel(unsigned short x, unsigned short y, unsigned short color) { LCD_SetCursor(x,y); LCD_WriteIndex(0x22); LCD_WriteData(color); } unsigned short getColor(unsigned short x, unsigned short y) { unsigned short d; LCD_SetCursor(x,y); LCD_WriteIndex(0x22); LCD_ReadData(); //dummy read d=LCD_ReadData(); return (d>>11)+(d&0x7e0)+((d&0x1f)<<11); //swap R and B }