void lcdFillRect_FSMC(JsGraphics *gfx, short x1, short y1, short x2, short y2) { if (x1>x2) { short l=x1; x1 = x2; x2 = l; } if (y1>y2) { short l=y1; y1 = y2; y2 = l; } // offscreen if (x1>=gfx->data.width || y1>=gfx->data.height || x2<0 || y2<0) return; // now clip if (x1<0) x1=0; if (y1<0) y1=0; if (x2>=gfx->data.width) x2=gfx->data.width-1; if (y2>=gfx->data.height) y2=gfx->data.height-1; // finally! if (x1==x2) { // special case for single vertical line - no window needed lcdSetCursor(gfx,x2,y1); LCD_WR_REG(0x22); // start data tx unsigned int i=0, l=(1+y2-y1); LCD_WR_Data_multi(gfx->data.fgColor, l); } else { lcdSetWindow(gfx,x1,y1,x2,y2); lcdSetCursor(gfx,x2,y1); LCD_WR_REG(0x22); // start data tx unsigned int i=0, l=(1+x2-x1)*(1+y2-y1); LCD_WR_Data_multi(gfx->data.fgColor, l); lcdSetFullWindow(gfx); } }
/************************************************* 函数名:LCD_SetWindows 功能:设置lcd显示窗口,在此区域写点数据自动换行 入口参数:xy起点和终点 返回值:无 *************************************************/ void LCD_SetWindows(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd) { #if USE_HORIZONTAL==1 //使用横屏 LCD_WR_REG(lcddev.setxcmd); LCD_WR_DATA(xStar>>8); LCD_WR_DATA(0x00FF&xStar+3); LCD_WR_DATA(xEnd>>8); LCD_WR_DATA(0x00FF&xEnd+3); LCD_WR_REG(lcddev.setycmd); LCD_WR_DATA(yStar>>8); LCD_WR_DATA(0x00FF&yStar+2); LCD_WR_DATA(yEnd>>8); LCD_WR_DATA(0x00FF&yEnd+2); #else LCD_WR_REG(lcddev.setxcmd); LCD_WR_DATA(xStar>>8); LCD_WR_DATA(0x00FF&xStar+2); LCD_WR_DATA(xEnd>>8); LCD_WR_DATA(0x00FF&xEnd+2); LCD_WR_REG(lcddev.setycmd); LCD_WR_DATA(yStar>>8); LCD_WR_DATA(0x00FF&yStar+3); LCD_WR_DATA(yEnd>>8); LCD_WR_DATA(0x00FF&yEnd+3); #endif LCD_WriteRAM_Prepare(); //开始写入GRAM }
/********************************************** 函数名:Lcd块选函数 功能:选定Lcd上指定的矩形区域 注意:xStart和 yStart随着屏幕的旋转而改变,位置是矩形框的四个角 入口参数:xStart x方向的起始点 ySrart y方向的终止点 xLong 要选定矩形的x方向长度 yLong 要选定矩形的y方向长度 返回值:无 ***********************************************/ void Lcd_SetBox(unsigned int xStart,unsigned int yStart,unsigned int xLong,unsigned int yLong) { #if ID_AM==000 LCD_SetCursor(xStart+xLong-1,312-yStart+yLong-1); #elif ID_AM==001 LCD_SetCursor(xStart+xLong-1,312-yStart+yLong-1); #elif ID_AM==010 LCD_SetCursor(xStart,312-yStart+yLong-1); #elif ID_AM==011 LCD_SetCursor(xStart,312-yStart+yLong-1); #elif ID_AM==100 LCD_SetCursor(xStart+xLong-1,312-yStart); #elif ID_AM==101 LCD_SetCursor(xStart+xLong-1,312-yStart); #elif ID_AM==110 LCD_SetCursor(xStart,312-yStart); #elif ID_AM==111 LCD_SetCursor(xStart,312-yStart); #endif LCD_WR_REG(0x0050,xStart);//水平 GRAM起始位置 LCD_WR_REG(0x0051,xStart+xLong-1);//水平GRAM终止位置 LCD_WR_REG(0x0052,312-yStart);//垂直GRAM起始位置 LCD_WR_REG(0x0053,312-yStart+yLong-1);//垂直GRAM终止位置 }
//读取个某点的颜色值 //x:0~239 //y:0~319 //返回值:此点的颜色 u16 LCD_ReadPoint(u16 x,u16 y) { u16 r,g,b; if(x>=LCD_W||y>=LCD_H)return 0; //超过了范围,直接返回 LCD_SetCursor(x,y); if(DeviceCode==0X9341)LCD_WR_REG(0X2E); //ILI9341发送读GRAM指令 else LCD_WR_REG(R34); //其他IC发送读GRAM指令 GPIOB->CRL=0X88888888; //PB0-7 上拉输入 GPIOB->CRH=0X88888888; //PB8-15 上拉输入 GPIOB->ODR=0XFFFF; //全部输出高 #if LCD_FAST_IO==1 //快速IO LCD_RS_SET; LCD_CS_CLR; //读取数据(读GRAM时,第一次为假读) LCD_RD_CLR; delay_us(1);//延时1us LCD_RD_SET; //dummy READ LCD_RD_CLR; delay_us(1);//延时1us LCD_RD_SET; r=DATAIN; if(DeviceCode==0X9341) { LCD_RD_CLR; LCD_RD_SET; b=DATAIN;//读取蓝色值 g=r&0XFF;//对于9341,第一次读取的是RG的值,R在前,G在后,各占8位 g<<=8; } LCD_CS_SET; #else LCD_RS=1; LCD_CS=0; //读取数据(读GRAM时,需要读2次) LCD_RD=0; LCD_RD=1; //dummy READ LCD_RD=0; LCD_RD=1; r=DATAIN; if(DeviceCode==0X9341) { LCD_RD=0; LCD_RD=1; b=DATAIN;//读取蓝色值 g=r&0XFF;//对于9341,第一次读取的是RG的值,R在前,G在后,各占8位 g<<=8; } LCD_CS=1; #endif GPIOB->CRL=0X33333333; //PB0-7 上拉输出 GPIOB->CRH=0X33333333; //PB8-15 上拉输出 GPIOB->ODR=0XFFFF; //全部输出高 if(DeviceCode==0X9325||DeviceCode==0X4535||DeviceCode==0X4531||DeviceCode==0X8989||DeviceCode==0XB505)return r; //这几种IC直接返回颜色值 else if(DeviceCode==0X9341)return (((r>>11)<<11)|((g>>10)<<5)|(b>>11)); //ILI9341需要公式转换一下 else return LCD_BGR2RGB(r); //其他IC
/******************************************************************************* Point_SCR: Set display position Input: X, Y *******************************************************************************/ void Point_SCR(unsigned short x0, unsigned short y0) { LCD_WR_REG(0x0020,y0); LCD_WR_REG(0x0021,x0); LDC_DATA_OUT=0x0022; //DRAM Reg. LCD_RS_LOW(); LCD_nWR_ACT(); //WR Cycle from 1 -> 0 -> 1 LCD_nWR_ACT(); //WR Cycle from 1 -> 0 -> 1 LCD_RS_HIGH(); }
void LCD_Address_set(uint x1,uint y1,uint x2,uint y2) { LCD_WR_REG(0x002A); LCD_WR_DATA(x1>>8); LCD_WR_DATA(x1&0x00ff); LCD_WR_DATA(x2>>8); LCD_WR_DATA(x2&0x00ff); LCD_WR_REG(0x002b); LCD_WR_DATA(y1>>8); LCD_WR_DATA(y1&0x00ff); LCD_WR_DATA(y2>>8); LCD_WR_DATA(y2&0x00ff); LCD_WR_REG(0x002c); }
//X,Y为窗口左下角座标,注意设置窗口后座标不要超出该范围 void LCD_Window(u16 Xpos, u16 Ypos, u16 Height, u16 Width) { LCD_WR_REG(0X2A); LCD_WR_Data(Xpos>>8); //start 起始位置的高8位 LCD_WR_Data(Xpos-((Xpos>>8)<<8)); //起始位置的低8位 LCD_WR_Data((Xpos+Width-1)>>8); //end 结束位置的高8位 LCD_WR_Data((Xpos+Width-1)-(((Xpos+Width-1)>>8)<<8)); //结束位置的低8位 LCD_WR_REG(0X2B); LCD_WR_Data(Ypos>>8); //start LCD_WR_Data(Ypos-((Ypos>>8)<<8)); LCD_WR_Data((Ypos+Height-1)>>8); //end LCD_WR_Data((Ypos+Height-1)-(((Ypos+Height-1)>>8)<<8)); }
void GUI_Point(unsigned int x, unsigned int y,unsigned int color) { LCD_WR_REG(0x0020,x);//Lcd光标GRAM水平起始位置 LCD_WR_REG(0x0021,y); //Lcd光标垂直GRAM起始位置 // LCD_WR_REG(0x0050,x);//水平 GRAM起始位置 // LCD_WR_REG(0x0051,x);//水平GRAM终止位置 // LCD_WR_REG(0x0052,y);//垂直GRAM起始位置 // LCD_WR_REG(0x0053,y);//垂直GRAM终止位置 LCD_WR_REG16(0x0022); LCD_WR_DATA16(color); }
static cell AMX_NATIVE_CALL amx_getcolumn(AMX *amx, const cell *params) { // getcolumn(x, y, pixels[], count); int x = params[1]; int y = params[2]; cell *pixels = (cell*)params[3]; int count = params[4]; // Seems like DSO Quad may use two different kinds of LCD's, with // slightly different command sets.. if (LCD_RD_Type() == LCD_TYPE_ILI9327) { __Point_SCR(x, y); LCD_WR_Ctrl(0x2E); // Dummy read always_read(LCD_PORT); // Use DMA to do the transfer DMA2_Channel1->CCR = 0x5980; DMA2_Channel1->CMAR = (uint32_t)pixels; DMA2_Channel1->CNDTR = count; DMA2_Channel1->CCR = 0x5981; __LCD_DMA_Ready(); LCD_WR_Ctrl(0x2C); } else { // I haven't been able to test this code path. __LCD_DMA_Ready(); // The R61509V doesn't automatically increment the address // when reading, which slows this down a bit... LCD_WR_REG(0x0201, x); while (count--) { LCD_WR_REG(0x0200, y++); LCD_WR_Ctrl(0x0202); always_read(LCD_PORT); *pixels++ = LCD_PORT; } } return 0; }
u16 LCD_ReadRAM(void) //read ram(must read two times) { u16 dummy; LCD_WR_REG(0X22); dummy = *(vu16*)Bank1_LCD_D; return *(vu16*)Bank1_LCD_D; }
//读寄存器 u16 LCD_ReadReg(u8 LCD_Reg) { u16 t; LCD_WR_REG(LCD_Reg); //写入要读的寄存器号 GPIOB->CRL=0X88888888; //PB0-7 上拉输入 GPIOB->CRH=0X88888888; //PB8-15 上拉输入 GPIOB->ODR=0XFFFF; //全部输出高 #if LCD_FAST_IO==1 //快速IO LCD_RS_SET; LCD_CS_CLR; //读取数据(读寄存器时,并不需要读2次) LCD_RD_CLR; delay_us(5);//FOR 8989,延时5us LCD_RD_SET; t=DATAIN; LCD_CS_SET; #else LCD_RS=1; LCD_CS=0; //读取数据(读寄存器时,并不需要读2次) LCD_RD=0; LCD_RD=1; t=DATAIN; LCD_CS=1; #endif GPIOB->CRL=0X33333333; //PB0-7 上拉输出 GPIOB->CRH=0X33333333; //PB8-15 上拉输出 GPIOB->ODR=0XFFFF; //全部输出高 return t; }
//6*12大小 //在指定位置显示一个字符 //x:0~234 //y:0~308 //num:要显示的字符:" "--->"~" void TFT_ShowChar(u8 x,u16 y,u8 num) { #define MAX_CHAR_POSX 232 #define MAX_CHAR_POSY 304 u8 temp; u8 pos,t; if(x>MAX_CHAR_POSX||y>MAX_CHAR_POSY)return; //设定一个字符所占的大小 //开辟空间 LCD_WR_CMD(0x0050, x); // Horizontal GRAM Start Address LCD_WR_CMD(0x0051, x+5); // Horizontal GRAM End Address LCD_WR_CMD(0x0052, y); // Vertical GRAM Start Address LCD_WR_CMD(0x0053, y+11); // Vertical GRAM Start Address LCD_WR_CMD(32, x); LCD_WR_CMD(33, y); LCD_WR_REG(34); num=num-' '; for(pos=0;pos<12;pos++) { temp=asc2_1206[num][pos]; for(t=0;t<6;t++) { if(temp&0x01)LCD_WR_Data(POINT_COLOR); else LCD_WR_Data(BACK_COLOR); temp>>=1; } } }
void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2) { LCD_WR_REG(0x2a); LCD_WR_DATA8(x1>>8); LCD_WR_DATA8(x1); LCD_WR_DATA8(x2>>8); LCD_WR_DATA8(x2); LCD_WR_REG(0x2b); LCD_WR_DATA8(y1>>8); LCD_WR_DATA8(y1); LCD_WR_DATA8(y2>>8); LCD_WR_DATA8(y2); LCD_WR_REG(0x2C); }
//设置光标位置 //Xpos:横坐标 //Ypos:纵坐标 void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos) { uint8_t temp; LCD_WR_REG(lcddev.setxcmd); LCD_WR_DATA8(Xpos>>8); LCD_WR_DATA8(Xpos&0XFF); Xpos = 159; LCD_WR_DATA8(Xpos>>8); LCD_WR_DATA8(Xpos&0XFF); LCD_WR_REG(lcddev.setycmd); LCD_WR_DATA8(Ypos>>8); LCD_WR_DATA8(Ypos&0XFF); Ypos = 127; LCD_WR_DATA8(Ypos>>8); LCD_WR_DATA8(Ypos&0XFF); }
void LCD_Clear(u16 Color) { u32 index=0; LCD_SetCursor(0x00,0x0000);//设置光标位置 LCD_WR_REG(R34); for(index=0;index<76800;index++) { LCD_WR_DATA(Color); } }
//-----------------读取个某点的颜色值 ----------------- u16 LCD_ReadPoint(u16 x,u16 y) { u16 r,g,b; if(x>=lcddev.width||y>=lcddev.height)return 0;//超过了范围,直接返回(返回值:此点的颜色) LCD_SetCursor(x,y);//x,y:坐标 if(lcddev.id==0X9341||lcddev.id==0X6804||lcddev.id==0X5310)LCD_WR_REG(0X2E);//9341/6804/5310发送读GRAM指令 else if(lcddev.id==0X5510)LCD_WR_REG(0X2E00); //5510 发送读GRAM指令 else LCD_WR_REG(R34);//其他IC发送读GRAM指令 GPIOB->CRL=0X88888888;//PB0-7上拉输入 GPIOB->CRH=0X88888888;//PB8-15上拉输入 GPIOB->ODR=0XFFFF;//全部输出高 LCD_RS_SET; LCD_CS_CLR; LCD_RD_CLR;//读取数据(读GRAM时,第一次为假读) delay_ms(1);//延时1ms LCD_RD_SET; LCD_RD_CLR;//dummy READ delay_ms(1);//延时1ms r=DATAIN;//实际坐标颜色 LCD_RD_SET; if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510) //9341/NT35310/NT35510要分2次读出 { LCD_RD_CLR; b=DATAIN;//读取蓝色值 LCD_RD_SET; g=r&0XFF;//对于9341,第一次读取的是RG的值,R在前,G在后,各占8位 g<<=8; }else if(lcddev.id==0X6804) { LCD_RD_CLR; LCD_RD_SET; r=DATAIN;//6804第二次读取的才是真实值 } LCD_CS_SET; GPIOB->CRL=0X33333333; //PB0-7 上拉输出 GPIOB->CRH=0X33333333; //PB8-15 上拉输出 GPIOB->ODR=0XFFFF; //全部输出高 if(lcddev.id==0X9325||lcddev.id==0X4535||lcddev.id==0X4531||lcddev.id==0X8989||lcddev.id==0XB505)return r; //这几种IC直接返回颜色值 else if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510)return (((r>>11)<<11)|((g>>10)<<5)|(b>>11));//ILI9341/NT35310/NT35510需要公式转换一下 else return LCD_BGR2RGB(r);//其他IC
int main() { Clr_BUFFER_FLAG(); alt_video_display Display; TOUCH_HANDLE *pTouch; printf("Hi There !\n"); // Write 0x3C on LED[6:0] through the dedicated custom IP IOWR(LED_CTRL_BASE, 0x0, 0x3C); // TOUCH INITIALIZATION pTouch = Touch_Init(LT24_TOUCH_SPI_BASE, LT24_TOUCH_PENIRQ_N_BASE, LT24_TOUCH_PENIRQ_N_IRQ); if (!pTouch){ printf("Failed to init touch\r\n"); }else{ printf("Init touch successfully\r\n"); } // LCD INITIALIZATION LCD_Init(); // Pattern example //LCD_Pattern_Horizon(); // Sleep 3s //usleep(3*1000*1000); Set_BUFFER_FLAG(); unsigned int X, Y; unsigned int posTamper =0; while(1){ if(Touch_GetXY(pTouch, &X, &Y)){ //printf("X: %d Y: %d\n",X,Y); LCD_WR_DATA(Y); LCD_WR_REG(X); //we can modify the character (the image become progressively red when we touch it), we might do the same for the background IOWR_16DIRECT(PIC_MEM_BASE,posTamper,0xF800); posTamper++; } } // Painter demo /*Clr_BUFFER_FLAG(); Display.interlace = 0; Display.bytes_per_pixel = 2; Display.color_depth = 16; Display.height = SCREEN_HEIGHT; Display.width = SCREEN_WIDTH; GUI(&Display, pTouch);*/ return 0; }
//读取个某点的颜色值 //x,y:坐标 //返回值:此点的颜色 u16 LCD_ReadPoint(u16 x,u16 y) { u16 r=0,g=0,b=0; if(x>=lcddev.width||y>=lcddev.height)return 0; //超过了范围,直接返回 LCD_SetCursor(x,y); if(lcddev.id==0X9341||lcddev.id==0X6804)LCD_WR_REG(0X2E);//9341/6804 发送读GRAM指令 else LCD_WR_REG(R34); //其他IC发送读GRAM指令 if(lcddev.id==0X9320)opt_delay(2); //FOR 9320,延时2us if(LCD->LCD_RAM)r=0; //dummy Read opt_delay(2); r=LCD->LCD_RAM; //实际坐标颜色 if(lcddev.id==0X9341)//9341要分2次读出 { opt_delay(2); b=LCD->LCD_RAM; g=r&0XFF;//对于9341,第一次读取的是RG的值,R在前,G在后,各占8位 g<<=8; }else if(lcddev.id==0X6804)r=LCD->LCD_RAM;//6804第二次读取的才是真实值 if(lcddev.id==0X9325||lcddev.id==0X4535||lcddev.id==0X4531||lcddev.id==0X8989||lcddev.id==0XB505)return r;//这几种IC直接返回颜色值 else if(lcddev.id==0X9341)return (((r>>11)<<11)|((g>>10)<<5)|(b>>11)); //ILI9341需要公式转换一下 else return LCD_BGR2RGB(r); //其他IC
void Test(void) { unsigned long n,i; LCD_WR_REG(0x0020,0x0000);//GRAM水平起始位置 LCD_WR_REG(0x0021,0x0000); for(i=0;i<7;i++) { LCD_WR_REG(0x0050,0x00);//水平 GRAM起始位置 LCD_WR_REG(0x0051,239);//水平GRAM终止位置 LCD_WR_REG(0x0052,0x00);//垂直GRAM起始位置 LCD_WR_REG(0x0053,319);//垂直GRAM终止位置 LCD_WR_REG16(0x0022); for(n=0;n<76800;n++) { if(i==0)LCD_WR_DATA16(BLUE); if(i==1)LCD_WR_DATA16(RED); if(i==2)LCD_WR_DATA16(GREEN); if(i==3)LCD_WR_DATA16(CYAN); if(i==4)LCD_WR_DATA16(MAGENTA); if(i==5)LCD_WR_DATA16(YELLOW); if(i==6)LCD_WR_DATA16(BLACK); } delay_ms(100); } }
/********************************************** 函数名:Lcd全屏擦除函数 功能:将Lcd整屏擦为指定颜色 入口参数:color 指定Lcd全屏颜色 RGB(5-6-5) 返回值:无 ***********************************************/ void LCD_Clear(unsigned int Color) { unsigned long index = 0; LCD_WR_REG(0x0020,0x0000);//GRAM水平起始位置 LCD_WR_REG(0x0021,00000); LCD_WR_REG(0x0050,0x00);//水平 GRAM起始位置 LCD_WR_REG(0x0051,239);//水平GRAM终止位置 LCD_WR_REG(0x0052,0x00);//垂直GRAM起始位置 LCD_WR_REG(0x0053,319);//垂直GRAM终止位置 LCD_WR_REG16(0x0022); LCD_RD_H(); LCD_RS_H(); LCD_CS_L(); for(index = 0; index < 76800; index++) { // LCD_WR_DATA16(Color); LCD_WR_L(); DATA_LCD_PORT=Color>>8; LCD_WR_H(); LCD_WR_L(); DATA_LCD_PORT=Color&0XFF; LCD_WR_H(); } LCD_CS_H(); }
/* Output a 1 bit bitmap */ void lcdBitmap1bit_FSMC(JsGraphics *gfx, short x1, short y1, unsigned short width, unsigned short height, unsigned char *data) { lcdSetWindow(gfx,x1,y1,x1+width-1,y1+height-1); lcdSetCursor(gfx,x1+width-1,y1); LCD_WR_REG(0x22); // start data tx unsigned int x,y; for(x=0;x<width;x++) { for(y=0;y<height;y++) { int bitOffset = x+(y*width); LCD_WR_Data(((data[bitOffset>>3]>>(bitOffset&7))&1) ? gfx->data.fgColor : gfx->data.bgColor); } } lcdSetFullWindow(gfx); }
//显示一副图片 //x,y:图片起始位置 //lenth:图片的宽度(0~240) //wide: 图片高度(0~320) //*p:图片首地址 //不带范围判断 void TFT_ShowBmp(u8 x,u16 y,u8 lenth,u16 wide,const u8 *p) { u32 size,temp; //开辟窗口 LCD_WR_CMD(0x0050, x); // Horizontal GRAM Start Address LCD_WR_CMD(0x0051, (u16)x+lenth-1); // Horizontal GRAM End Address LCD_WR_CMD(0x0052, y); // Vertical GRAM Start Address LCD_WR_CMD(0x0053, y+wide-1); // Vertical GRAM Start Address LCD_WR_REG(34); temp=(u32)lenth*wide*2; for(size=0;size<temp;size++)LCD_WR_Data_8(p[size]); }
//画点 //x:0~239 //y:0~319 //POINT_COLOR:此点的颜色 void TFT_DrawPoint(u8 x,u16 y) { LCD_WR_CMD(0x0050, x); // Horizontal GRAM Start Address LCD_WR_CMD(0x0051, 0x00EF); // Horizontal GRAM End Address LCD_WR_CMD(0x0052, y); // Vertical GRAM Start Address LCD_WR_CMD(0x0053, 0x013F); // Vertical GRAM Start Address LCD_WR_CMD(32, x); // Horizontal GRAM Start Address LCD_WR_CMD(33, y); // Vertical GRAM Start Address LCD_WR_REG(34); LCD_WR_Data(POINT_COLOR); }
void TFT_Clear(u8 x,u16 y,u8 len,u16 wid) { u32 n,temp; LCD_WR_CMD(0x0050, x); // Horizontal GRAM Start Address LCD_WR_CMD(0x0051, x+len-1); // Horizontal GRAM End Address LCD_WR_CMD(0x0052, y); // Vertical GRAM Start Address LCD_WR_CMD(0x0053, y+wid-1); // Vertical GRAM Start Address LCD_WR_REG(34); temp=(u32)len*wid; for(n=0;n<temp;n++) LCD_WR_Data(BACK_COLOR); }
//设置一个GRAM范围以进行连续读写 void LCD_SetWindow(u16 x1,u16 y1,u16 x2,u16 y2) { LCD_WR_REG(0x0046);LCD_WR_DATA((x2<<8)| x1); //水平方向起点(高8位)和终点(低8位)坐标 LCD_WR_REG(0x0047);LCD_WR_DATA(y2); //垂直方向终点坐标 LCD_WR_REG(0x0048);LCD_WR_DATA(y1); //垂直方向起始坐标 //设置起点 LCD_WR_REG(0x0020);LCD_WR_DATA(x1); //定位横坐标 LCD_WR_REG(0x0021);LCD_WR_DATA(y1); //定位纵坐标 //开始写 LCD_WR_REG(0x0022); }
/*** 说 明:图片取模格式为水平扫描,16位颜色模式,取模软件img2LCD ***/ static void LCD_DrawPicture(uint16_t StartX, uint16_t StartY, uint8_t Dir, uint8_t *Pic) { uint16_t temp; uint16_t x = 0, y = 0; uint32_t i = 8, len = 0; x = ((uint16_t)(Pic[2] << 8) + Pic[3]) - 1; //从图像数组里取出图像的宽度 y = ((uint16_t)(Pic[4] << 8) + Pic[5]) - 1; //从图像数组里取出图像的高度 if (Dir == 0) { LCD_WR_CMD(0x0003, 0x1030); //图像显示方向为左上起,行递增,列增加 LCD_WR_CMD(0x0210, StartX); //水平显示区起始地址 0 LCD_WR_CMD(0x0211, StartX + x); //水平显示区结束地址 239 LCD_WR_CMD(0x0212, StartY); //垂直显示区起始地址 0 LCD_WR_CMD(0x0213, StartY + y); //垂直显示区结束地址 399 LCD_WR_CMD(0x0200, StartX); //水平显示区地址 0 LCD_WR_CMD(0x0201, StartY); //垂直显示区地址 0 } else if (Dir == 1) { LCD_WR_CMD(0x0003, 0x1018); //图像显示方向为左下起,行递增,列递减 LCD_WR_CMD(0x0210, StartY); //水平显示区起始地址 0 LCD_WR_CMD(0x0211, StartY + y); //水平显示区结束地址 239 LCD_WR_CMD(0x0212, StartX); //垂直显示区起始地址 0 LCD_WR_CMD(0x0213, StartX + x); //垂直显示区结束地址 239 LCD_WR_CMD(0x0200, StartY); //水平显示区地址 LCD_WR_CMD(0x0201, StartX + x); //垂直显示区地址 } LCD_WR_REG(0x0202); //写数据到显示区 len = 2 * (x + 1) * (y + 1); //计算出图像所占的字节数 while (i < (len + 8)) //从图像数组的第9位开始递增 { temp = (uint16_t)((Pic[i] << 8) + Pic[i+1]); //16位总线,需要一次发送2个字节的数据 LCD_WR_Data(temp); //将取出的16位像素数据送入显示区 i += 2; //取模位置加2,以为获取下一个像素数据 } }
//读取个某点的颜色值 //x:0~239 //y:0~319 //返回值:此点的颜色 u16 LCD_ReadPoint(u16 x,u16 y) { u16 t; if(x>=LCD_W||y>=LCD_H)return 0;//超过了范围,直接返回 LCD_SetCursor(x,y); LCD_WR_REG(R34); //选择GRAM地址 GPIOB->CRL=0X88888888; //PB0-7 上拉输入 GPIOB->CRH=0X88888888; //PB8-15 上拉输入 GPIOB->ODR=0XFFFF; //全部输出高 #if LCD_FAST_IO==1 //快速IO LCD_RS_SET; LCD_CS_CLR; //读取数据(读GRAM时,需要读2次) LCD_RD_CLR; LCD_RD_SET; delay_us(2);//FOR 9320,延时2us //dummy READ LCD_RD_CLR; delay_us(2);//FOR 8989,延时2us LCD_RD_SET; t=DATAIN; LCD_CS_SET; #else LCD_RS=1; LCD_CS=0; //读取数据(读GRAM时,需要读2次) LCD_RD=0; LCD_RD=1; //dummy READ LCD_RD=0; LCD_RD=1; t=DATAIN; LCD_CS=1; #endif GPIOB->CRL=0X33333333; //PB0-7 上拉输出 GPIOB->CRH=0X33333333; //PB8-15 上拉输出 GPIOB->ODR=0XFFFF; //全部输出高 if(DeviceCode==0X4535||DeviceCode==0X4531||DeviceCode==0X8989||DeviceCode==0XB505)return t;//这几种IC直接返回颜色值 else return LCD_BGR2RGB(t); }
/******************************************************************** * * LcdWriteReg * * Function description: * Sets display register */ static void LcdWriteReg(U16 Data) { // ... TBD by user LCD_WR_REG(Data); }
//开始写GRAM void LCD_WriteRAM_Prepare(void) { if(DeviceCode==0X9341)LCD_WR_REG(0x2C);//ILI9341是以0X2C开始的 else LCD_WR_REG(R34); }
//读寄存器 //LCD_Reg:寄存器编号 //返回值:读到的值 u16 LCD_ReadReg(u8 LCD_Reg) { LCD_WR_REG(LCD_Reg); //写入要读的寄存器号 return LCD_RD_DATA(); }