stm32 驅動 TFT LCD
阿新 • • 發佈:2019-01-02
#include "ili93xx.h" #include "font.h" #define USE_HORIZONTAL 0 //定義是否使用橫屏 //畫筆顏色,背景顏色 u16 POINT_COLOR = 0x0000,BACK_COLOR = 0xFFFF; u16 DeviceCode; void LCD_Delay_Us(u32 us) { u32 time=100*us/7; while(--time); } //LCD延時函式 10MS void LCD_Delay (u32 nCount) { volatile int i; for (i=0;i<nCount*100;i++); } //LCD_GPIO_DATA_PIN 模式設定 //u8 Mode : // 1 推輓輸出 // 0 上拉輸出 void LCD_Data_Pin_Mode(u8 Mode){ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = LCD_GPIO_DATA_PIN; if(Mode == 1) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推輓輸出 else GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; // 上拉輸入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LCD_GPIO_DATA_PORT, &GPIO_InitStructure); } //寫暫存器函式 void LCD_WR_REG(u8 data) { Clr_Rs;//寫地址 Clr_Cs; Write_Data(data); Clr_Wr; Set_Wr; Set_Cs; } //寫暫存器 void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue) { LCD_WR_REG(LCD_Reg); LCD_WR_DATA(LCD_RegValue); } //讀暫存器 u16 LCD_ReadReg(u8 LCD_Reg) { u16 t; LCD_WR_REG(LCD_Reg); //寫入要讀的暫存器號 LCD_Data_Pin_Mode(0); //上拉模式 Set_Rs; Clr_Cs; //讀取資料(讀暫存器時,並不需要讀2次) Clr_Rd; Set_Rd; t=Read_Data(); Set_Cs; LCD_Data_Pin_Mode(1); //推輓模式 Write_Data(0xffff); return t; } //開始寫GRAM void LCD_WriteRAM_Prepare(void) { LCD_WR_REG(R34); } //LCD寫GRAM void LCD_WriteRAM(u16 RGB_Code) { LCD_WR_DATA(RGB_Code);//寫十六位GRAM } //從ILI93xx讀出的資料為GBR格式,而我們寫入的時候為RGB格式。 //通過該函式轉換 //c:GBR格式的顏色值 //返回值:RGB格式的顏色值 u16 LCD_BGR2RGB(u16 c) { u16 r,g,b,rgb; b=(c>>0)&0x1f; g=(c>>5)&0x3f; r=(c>>11)&0x1f; rgb=(b<<11)+(g<<5)+(r<<0); return(rgb); } //讀取個某點的顏色值 //x:0~239 //y:0~319 //返回值:此點的顏色 u16 LCD_ReadPoint(u16 x,u16 y) { u16 t; if(x>=LCD_WIDTH||y>=LCD_HEIGHT)return 0;//超過了範圍,直接返回 LCD_SetCursor(x,y); LCD_WR_REG(R34); //選擇GRAM地址 LCD_Data_Pin_Mode(0); //上拉模式 Set_Rs; Clr_Cs; //讀取資料(讀GRAM時,需要讀2次) Clr_Rd; Set_Rd; LCD_Delay_Us(2); //dummy READ Clr_Rd; LCD_Delay_Us(2); Set_Rd; t=Read_Data(); Set_Cs; LCD_Data_Pin_Mode(1); //推輓模式 Write_Data(0xFFFF); if(DeviceCode==0X4531||DeviceCode==0X8989||DeviceCode==0XB505) return t;//4531驅動IC else return LCD_BGR2RGB(t); } //LCD開啟顯示 void LCD_DisplayOn(void) { LCD_WriteReg(R7, 0x0173); //26萬色顯示開啟 } //LCD關閉顯示 void LCD_DisplayOff(void) { LCD_WriteReg(R7, 0x0);//關閉顯示 } //設定游標位置 //Xpos:橫座標 //Ypos:縱座標 __inline void LCD_SetCursor(u8 Xpos, u16 Ypos) { #if USE_HORIZONTAL LCD_WriteReg(R32, Ypos); LCD_WriteReg(R33, 319-Xpos); #else LCD_WriteReg(R32, Xpos); LCD_WriteReg(R33, Ypos); #endif } //畫點 //x:0~239 //y:0~319 //POINT_COLOR:此點的顏色 void LCD_DrawPoint(u16 x,u16 y) { LCD_SetCursor(x,y);//設定游標位置 LCD_WR_REG(R34);//開始寫入GRAM LCD_WR_DATA(POINT_COLOR); } //初始化lcd void LCD_Config(void) { /*Set_Cs; Set_Rs; Set_Wr; Set_Rd; */ LCD_Delay(5); // LCD_Delay 50 ms LCD_WriteReg(0x0000,0x0001); LCD_Delay(5); // LCD_Delay 50 ms DeviceCode = LCD_ReadReg(0x0000); //printf("ID:%d\n",DeviceCode); if(DeviceCode==0x9325||DeviceCode==0x9328){ //ILI9325 LCD_WriteReg(0x00e7,0x0010); LCD_WriteReg(0x0000,0x0001);//開啟內部時鐘 LCD_WriteReg(0x0001,0x0100); LCD_WriteReg(0x0002,0x0700);//電源開啟 //LCD_WriteReg(0x0003,(1<<3)|(1<<4) ); //65K RGB //DRIVE TABLE(暫存器 03H) //BIT3=AM BIT4:5=ID0:1 //AM ID0 ID1 FUNCATION // 0 0 0 R->L D->U // 1 0 0 D->U R->L // 0 1 0 L->R D->U // 1 1 0 D->U L->R // 0 0 1 R->L U->D // 1 0 1 U->D R->L // 0 1 1 L->R U->D 正常就用這個. // 1 1 1 U->D L->R LCD_WriteReg(0x0003,(1<<12)|(3<<4)|(0<<3) );//65K LCD_WriteReg(0x0004,0x0000); LCD_WriteReg(0x0008,0x0207); LCD_WriteReg(0x0009,0x0000); LCD_WriteReg(0x000a,0x0000);//display setting LCD_WriteReg(0x000c,0x0001);//display setting LCD_WriteReg(0x000d,0x0000);//0f3c LCD_WriteReg(0x000f,0x0000); //電源配置 LCD_WriteReg(0x0010,0x0000); LCD_WriteReg(0x0011,0x0007); LCD_WriteReg(0x0012,0x0000); LCD_WriteReg(0x0013,0x0000); LCD_Delay(5); LCD_WriteReg(0x0010,0x1590); LCD_WriteReg(0x0011,0x0227); LCD_Delay(5); LCD_WriteReg(0x0012,0x009c); LCD_Delay(5); LCD_WriteReg(0x0013,0x1900); LCD_WriteReg(0x0029,0x0023); LCD_WriteReg(0x002b,0x000e); LCD_Delay(5); LCD_WriteReg(0x0020,0x0000); LCD_WriteReg(0x0021,0x013f); LCD_Delay(5); //伽馬校正 LCD_WriteReg(0x0030,0x0007); LCD_WriteReg(0x0031,0x0707); LCD_WriteReg(0x0032,0x0006); LCD_WriteReg(0x0035,0x0704); LCD_WriteReg(0x0036,0x1f04); LCD_WriteReg(0x0037,0x0004); LCD_WriteReg(0x0038,0x0000); LCD_WriteReg(0x0039,0x0706); LCD_WriteReg(0x003c,0x0701); LCD_WriteReg(0x003d,0x000f); LCD_Delay(5); LCD_WriteReg(0x0050,0x0000); //水平GRAM起始位置 LCD_WriteReg(0x0051,(LCD_WIDTH-1)); //水平GRAM終止位置 LCD_WriteReg(0x0052,0x0000); //垂直GRAM起始位置 LCD_WriteReg(0x0053,(LCD_HEIGHT-1)); //垂直GRAM終止位置 LCD_WriteReg(0x0060,0xa700); LCD_WriteReg(0x0061,0x0001); LCD_WriteReg(0x006a,0x0000); LCD_WriteReg(0x0080,0x0000); LCD_WriteReg(0x0081,0x0000); LCD_WriteReg(0x0082,0x0000); LCD_WriteReg(0x0083,0x0000); LCD_WriteReg(0x0084,0x0000); LCD_WriteReg(0x0085,0x0000); LCD_WriteReg(0x0090,0x0010); LCD_WriteReg(0x0092,0x0000); LCD_WriteReg(0x0093,0x0003); LCD_WriteReg(0x0095,0x0110); LCD_WriteReg(0x0097,0x0000); LCD_WriteReg(0x0098,0x0000); //開啟顯示設定 LCD_WriteReg(0x0007,0x0133); LCD_WriteReg(0x0020,0x0000); LCD_WriteReg(0x0021,0x013f); }else if(DeviceCode==0x9320||DeviceCode==0x9300){ LCD_WriteReg(0x00,0x0000); LCD_WriteReg(0x01,0x0100); //Driver Output Contral. LCD_WriteReg(0x02,0x0700); //LCD Driver Waveform Contral. LCD_WriteReg(0x03,0x1030);//Entry Mode Set. //LCD_WriteReg(0x03,0x1018); //Entry Mode Set. LCD_WriteReg(0x04,0x0000); //Scalling Contral. LCD_WriteReg(0x08,0x0202); //Display Contral 2.(0x0207) LCD_WriteReg(0x09,0x0000); //Display Contral 3.(0x0000) LCD_WriteReg(0x0a,0x0000); //Frame Cycle Contal.(0x0000) LCD_WriteReg(0x0c,(1<<0)); //Extern Display Interface Contral 1.(0x0000) LCD_WriteReg(0x0d,0x0000); //Frame Maker Position. LCD_WriteReg(0x0f,0x0000); //Extern Display Interface Contral 2. LCD_Delay(5); LCD_WriteReg(0x07,0x0101); //Display Contral. LCD_Delay(5); LCD_WriteReg(0x10,(1<<12)|(0<<8)|(1<<7)|(1<<6)|(0<<4)); //Power Control 1.(0x16b0) LCD_WriteReg(0x11,0x0007); //Power Control 2.(0x0001) LCD_WriteReg(0x12,(1<<8)|(1<<4)|(0<<0)); //Power Control 3.(0x0138) LCD_WriteReg(0x13,0x0b00); //Power Control 4. LCD_WriteReg(0x29,0x0000); //Power Control 7. LCD_WriteReg(0x2b,(1<<14)|(1<<4)); LCD_WriteReg(0x50,0); //Set X Star //水平GRAM終止位置Set X End. LCD_WriteReg(0x51,(LCD_WIDTH-1)); //Set Y Star LCD_WriteReg(0x52,0); //Set Y End.t. LCD_WriteReg(0x53,(LCD_HEIGHT-1)); // LCD_WriteReg(0x60,0x2700); //Driver Output Control. LCD_WriteReg(0x61,0x0001); //Driver Output Control. LCD_WriteReg(0x6a,0x0000); //Vertical Srcoll Control. LCD_WriteReg(0x80,0x0000); //Display Position? Partial Display 1. LCD_WriteReg(0x81,0x0000); //RAM Address Start? Partial Display 1. LCD_WriteReg(0x82,0x0000); //RAM Address End-Partial Display 1. LCD_WriteReg(0x83,0x0000); //Displsy Position? Partial Display 2. LCD_WriteReg(0x84,0x0000); //RAM Address Start? Partial Display 2. LCD_WriteReg(0x85,0x0000); //RAM Address End? Partial Display 2. LCD_WriteReg(0x90,(0<<7)|(16<<0)); //Frame Cycle Contral.(0x0013) LCD_WriteReg(0x92,0x0000); //Panel Interface Contral 2.(0x0000) LCD_WriteReg(0x93,0x0001); //Panel Interface Contral 3. LCD_WriteReg(0x95,0x0110); //Frame Cycle Contral.(0x0110) LCD_WriteReg(0x97,(0<<8)); // LCD_WriteReg(0x98,0x0000); //Frame Cycle Contral. LCD_WriteReg(0x07,0x0173); //(0x0173) }else if(DeviceCode==0x1505){ // second release on 3/5 ,luminance is acceptable,water wave appear during camera preview LCD_WriteReg(0x0007,0x0000); LCD_Delay(5); LCD_WriteReg(0x0012,0x011C);//0x011A why need to set several times? LCD_WriteReg(0x00A4,0x0001);//NVM LCD_WriteReg(0x0008,0x000F); LCD_WriteReg(0x000A,0x0008); LCD_WriteReg(0x000D,0x0008); //伽馬校正 LCD_WriteReg(0x0030,0x0707); LCD_WriteReg(0x0031,0x0007); //0x0707 LCD_WriteReg(0x0032,0x0603); LCD_WriteReg(0x0033,0x0700); LCD_WriteReg(0x0034,0x0202); LCD_WriteReg(0x0035,0x0002); //?0x0606 LCD_WriteReg(0x0036,0x1F0F); LCD_WriteReg(0x0037,0x0707); //0x0f0f 0x0105 LCD_WriteReg(0x0038,0x0000); LCD_WriteReg(0x0039,0x0000); LCD_WriteReg(0x003A,0x0707); LCD_WriteReg(0x003B,0x0000); //0x0303 LCD_WriteReg(0x003C,0x0007); //?0x0707 LCD_WriteReg(0x003D,0x0000); //0x1313//0x1f08 LCD_Delay(5); LCD_WriteReg(0x0007,0x0001); LCD_WriteReg(0x0017,0x0001);//開啟電源 LCD_Delay(5); //電源配置 LCD_WriteReg(0x0010,0x17A0); LCD_WriteReg(0x0011,0x0217);//reference voltage VC[2:0] Vciout = 1.00*Vcivl LCD_WriteReg(0x0012,0x011E);//0x011c //Vreg1out = Vcilvl*1.80 is it the same as Vgama1out ? LCD_WriteReg(0x0013,0x0F00);//VDV[4:0]-->VCOM Amplitude VcomL = VcomH - Vcom Ampl LCD_WriteReg(0x002A,0x0000); LCD_WriteReg(0x0029,0x000A);//0x0001F Vcomh = VCM1[4:0]*Vreg1out gate source voltage?? LCD_WriteReg(0x0012,0x013E);// 0x013C power supply on //Coordinates Control// LCD_WriteReg(0x0050,0x0000);//0x0e00 LCD_WriteReg(0x0051,(LCD_WIDTH-1)); LCD_WriteReg(0x0052,0x0000); LCD_WriteReg(0x0053,(LCD_HEIGHT-1)); //Pannel Image Control// LCD_WriteReg(0x0060,0x2700); LCD_WriteReg(0x0061,0x0001); LCD_WriteReg(0x006A,0x0000); LCD_WriteReg(0x0080,0x0000); //Partial Image Control// LCD_WriteReg(0x0081,0x0000); LCD_WriteReg(0x0082,0x0000); LCD_WriteReg(0x0083,0x0000); LCD_WriteReg(0x0084,0x0000); LCD_WriteReg(0x0085,0x0000); //Panel Interface Control// LCD_WriteReg(0x0090,0x0013);//0x0010 frenqucy LCD_WriteReg(0x0092,0x0300); LCD_WriteReg(0x0093,0x0005); LCD_WriteReg(0x0095,0x0000); LCD_WriteReg(0x0097,0x0000); LCD_WriteReg(0x0098,0x0000); LCD_WriteReg(0x0001,0x0100); LCD_WriteReg(0x0002,0x0700); LCD_WriteReg(0x0003,0x1030); LCD_WriteReg(0x0004,0x0000); LCD_WriteReg(0x000C,0x0000); LCD_WriteReg(0x000F,0x0000); LCD_WriteReg(0x0020,0x0000); LCD_WriteReg(0x0021,0x0000); LCD_WriteReg(0x0007,0x0021); LCD_Delay(20); LCD_WriteReg(0x0007,0x0061); LCD_Delay(20); LCD_WriteReg(0x0007,0x0173); LCD_Delay(20); }else if(DeviceCode==0xB505){ //stm32 正點原子 LCD 驅動IC LCD_WriteReg(0x0000,0x0000); LCD_WriteReg(0x0000,0x0000); LCD_WriteReg(0x0000,0x0000); LCD_WriteReg(0x0000,0x0000); LCD_WriteReg(0x00a4,0x0001); LCD_Delay(20); LCD_WriteReg(0x0060,0x2700); LCD_WriteReg(0x0008,0x0202); 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(0x0090,0x001a); LCD_WriteReg(0x0010,0x0000); LCD_WriteReg(0x0011,0x0007); LCD_WriteReg(0x0012,0x0000); LCD_WriteReg(0x0013,0x0000); LCD_Delay(20); LCD_WriteReg(0x0010,0x0730); LCD_WriteReg(0x0011,0x0137); LCD_Delay(20); LCD_WriteReg(0x0012,0x01b8); LCD_Delay(20); LCD_WriteReg(0x0013,0x0f00); LCD_WriteReg(0x002a,0x0080); LCD_WriteReg(0x0029,0x0048); LCD_Delay(20); LCD_WriteReg(0x0001,0x0100); LCD_WriteReg(0x0002,0x0700); LCD_WriteReg(0x0003,0x1230); LCD_WriteReg(0x0008,0x0202); LCD_WriteReg(0x000a,0x0000); LCD_WriteReg(0x000c,0x0000); LCD_WriteReg(0x000d,0x0000); LCD_WriteReg(0x000e,0x0030); LCD_WriteReg(0x0050,0x0000); LCD_WriteReg(0x0051,0x00ef); LCD_WriteReg(0x0052,0x0000); LCD_WriteReg(0x0053,0x013f); LCD_WriteReg(0x0060,0x2700); LCD_WriteReg(0x0061,0x0001); LCD_WriteReg(0x006a,0x0000); //LCD_WriteReg(0x0080,0x0000); //LCD_WriteReg(0x0081,0x0000); LCD_WriteReg(0x0090,0X0011); LCD_WriteReg(0x0092,0x0600); LCD_WriteReg(0x0093,0x0402); LCD_WriteReg(0x0094,0x0002); LCD_Delay(20); LCD_WriteReg(0x0007,0x0001); LCD_Delay(20); LCD_WriteReg(0x0007,0x0061); LCD_WriteReg(0x0007,0x0173); LCD_WriteReg(0x0020,0x0000); LCD_WriteReg(0x0021,0x0000); LCD_WriteReg(0x00,0x22); }else if(DeviceCode==0x8989){ LCD_WriteReg(0x0000,0x0001);LCD_Delay(5);//開啟晶振 LCD_WriteReg(0x0003,0xA8A4);LCD_Delay(5);//0xA8A4 LCD_WriteReg(0x000C,0x0000);LCD_Delay(5); LCD_WriteReg(0x000D,0x080C);LCD_Delay(5); LCD_WriteReg(0x000E,0x2B00);LCD_Delay(5); LCD_WriteReg(0x001E,0x00B0);LCD_Delay(5); LCD_WriteReg(0x0001,0x2B3F);LCD_Delay(5);//驅動輸出控制320*240 0x6B3F LCD_WriteReg(0x0002,0x0600);LCD_Delay(5); LCD_WriteReg(0x0010,0x0000);LCD_Delay(5); LCD_WriteReg(0x0011,0x6070);LCD_Delay(5);//定義資料格式 16位色 橫屏 0x6058 LCD_WriteReg(0x0005,0x0000);LCD_Delay(5); LCD_WriteReg(0x0006,0x0000);LCD_Delay(5); LCD_WriteReg(0x0016,0xEF1C);LCD_Delay(5); LCD_WriteReg(0x0017,0x0003);LCD_Delay(5); LCD_WriteReg(0x0007,0x0233);LCD_Delay(5);//0x0233 LCD_WriteReg(0x000B,0x0000);LCD_Delay(5); LCD_WriteReg(0x000F,0x0000);LCD_Delay(5);//掃描開始地址 LCD_WriteReg(0x0041,0x0000);LCD_Delay(5); LCD_WriteReg(0x0042,0x0000);LCD_Delay(5); LCD_WriteReg(0x0048,0x0000);LCD_Delay(5); LCD_WriteReg(0x0049,0x013F);LCD_Delay(5); LCD_WriteReg(0x004A,0x0000);LCD_Delay(5); LCD_WriteReg(0x004B,0x0000);LCD_Delay(5); LCD_WriteReg(0x0044,0xEF00);LCD_Delay(5); LCD_WriteReg(0x0045,0x0000);LCD_Delay(5); LCD_WriteReg(0x0046,0x013F);LCD_Delay(5); LCD_WriteReg(0x0030,0x0707);LCD_Delay(5); LCD_WriteReg(0x0031,0x0204);LCD_Delay(5); LCD_WriteReg(0x0032,0x0204);LCD_Delay(5); LCD_WriteReg(0x0033,0x0502);LCD_Delay(5); LCD_WriteReg(0x0034,0x0507);LCD_Delay(5); LCD_WriteReg(0x0035,0x0204);LCD_Delay(5); LCD_WriteReg(0x0036,0x0204);LCD_Delay(5); LCD_WriteReg(0x0037,0x0502);LCD_Delay(5); LCD_WriteReg(0x003A,0x0302);LCD_Delay(5); LCD_WriteReg(0x003B,0x0302);LCD_Delay(5); LCD_WriteReg(0x0023,0x0000);LCD_Delay(5); LCD_WriteReg(0x0024,0x0000);LCD_Delay(5); LCD_WriteReg(0x0025,0x8000);LCD_Delay(5); LCD_WriteReg(0x004f,0); //行首址0 LCD_WriteReg(0x004e,0); //列首址0 }else if(DeviceCode==0x4531){ LCD_WriteReg(0X00,0X0001); LCD_Delay(50); LCD_WriteReg(0X10,0X1628); LCD_WriteReg(0X12,0X000e);//0x0006 LCD_WriteReg(0X13,0X0A39); LCD_Delay(10); LCD_WriteReg(0X11,0X0040); LCD_WriteReg(0X15,0X0050); LCD_Delay(40); LCD_WriteReg(0X12,0X001e);//16 LCD_Delay(40); LCD_WriteReg(0X10,0X1620); LCD_WriteReg(0X13,0X2A39); LCD_Delay(10); LCD_WriteReg(0X01,0X0100); LCD_WriteReg(0X02,0X0300); LCD_WriteReg(0X03,0X1030);//改變方向的 LCD_WriteReg(0X08,0X0202); LCD_WriteReg(0X0A,0X0008); LCD_WriteReg(0X30,0X0000); LCD_WriteReg(0X31,0X0402); LCD_WriteReg(0X32,0X0106); LCD_WriteReg(0X33,0X0503); LCD_WriteReg(0X34,0X0104); LCD_WriteReg(0X35,0X0301); LCD_WriteReg(0X36,0X0707); LCD_WriteReg(0X37,0X0305); LCD_WriteReg(0X38,0X0208); LCD_WriteReg(0X39,0X0F0B); LCD_WriteReg(0X41,0X0002); LCD_WriteReg(0X60,0X2700); LCD_WriteReg(0X61,0X0001); LCD_WriteReg(0X90,0X0210); LCD_WriteReg(0X92,0X010A); LCD_WriteReg(0X93,0X0004); LCD_WriteReg(0XA0,0X0100); LCD_WriteReg(0X07,0X0001); LCD_WriteReg(0X07,0X0021); LCD_WriteReg(0X07,0X0023); LCD_WriteReg(0X07,0X0033); LCD_WriteReg(0X07,0X0133); LCD_WriteReg(0XA0,0X0000); } LCD_Delay(5000); Set_LED;//點亮背光 LCD_Clear(WHITE); } //清屏函式 //Color:要清屏的填充色 void LCD_Clear(u16 Color) { u32 index=0; LCD_SetCursor(0x00,0x0000);//設定游標位置 LCD_WriteRAM_Prepare(); //開始寫入GRAM for(index=0;index<76800;index++) { LCD_WR_DATA(Color); //向每個GRAM寫入資料 } } //在指定區域內填充指定顏色 //區域大小: // (xend-xsta)*(yend-ysta) void LCD_Fill(u8 xsta,u16 ysta,u8 xend,u16 yend,u16 color) { #if USE_HORIZONTAL //橫屏 u16 colortemp=POINT_COLOR; u16 ytemp=ysta; POINT_COLOR=color; for(;xsta<=xend;xsta++) { for(;ysta<=yend;ysta++)LCD_DrawPoint(xsta,ysta); ysta=ytemp; } POINT_COLOR=colortemp; #else //豎屏 u32 n; //設定視窗 LCD_WriteReg(R80, xsta); //水平方向GRAM起始地址 LCD_WriteReg(R81, xend); //水平方向GRAM結束地址 LCD_WriteReg(R82, ysta); //垂直方向GRAM起始地址 LCD_WriteReg(R83, yend); //垂直方向GRAM結束地址 LCD_SetCursor(xsta,ysta);//設定游標位置 LCD_WriteRAM_Prepare(); //開始寫入GRAM n=(u32)(yend-ysta+1)*(xend-xsta+1); while(n--){LCD_WR_DATA(color);}//顯示所填充的顏色. //恢復設定 LCD_WriteReg(R80, 0x0000); //水平方向GRAM起始地址 LCD_WriteReg(R81, (LCD_WIDTH-1)); //水平方向GRAM結束地址 LCD_WriteReg(R82, 0x0000); //垂直方向GRAM起始地址 LCD_WriteReg(R83, (LCD_HEIGHT-1)); //垂直方向GRAM結束地址 #endif } //畫線 //x1,y1:起點座標 //x2,y2:終點座標 void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2) { u16 t; int xerr=0,yerr=0,delta_x,delta_y,distance; int incx,incy,uRow,uCol; delta_x=x2-x1; //計算座標增量 delta_y=y2-y1; uRow=x1; uCol=y1; if(delta_x>0)incx=1; //設定單步方向 else if(delta_x==0)incx=0;//垂直線 else {incx=-1;delta_x=-delta_x;} //終點座標小於起始座標,反方向,將座標重新定位為正座標 if(delta_y>0)incy=1; else if(delta_y==0)incy=0;//水平線 else{incy=-1;delta_y=-delta_y;} //終點座標小於起始座標,反方向,將座標重新定位為正座標 if( delta_x>delta_y)distance=delta_x; //選取基本增量座標軸 else distance=delta_y; for(t=0;t<=distance+1;t++ )//畫線輸出 { LCD_DrawPoint(uRow,uCol);//根據座標畫點 xerr+=delta_x ; //X座標增量 yerr+=delta_y ; //Y座標增量 if(xerr>distance) { xerr-=distance; uRow+=incx; } if(yerr>distance) { yerr-=distance; uCol+=incy; } } } //畫矩形 void LCD_DrawRectangle(u8 x1, u16 y1, u8 x2, u16 y2) { LCD_DrawLine(x1,y1,x2,y1); LCD_DrawLine(x1,y1,x1,y2); LCD_DrawLine(x1,y2,x2,y2); LCD_DrawLine(x2,y1,x2,y2); } //在指定位置畫一個指定大小的圓 //(x,y):中心點 //r :半徑 void Draw_Circle(u8 x0,u16 y0,u8 r) { int a,b; int di; a=0;b=r; di=3-(r<<1); //判斷下個點位置的標誌 while(a<=b) { LCD_DrawPoint(x0-b,y0-a); //3 LCD_DrawPoint(x0+b,y0-a); //0 LCD_DrawPoint(x0-a,y0+b); //1 LCD_DrawPoint(x0-b,y0-a); //7 LCD_DrawPoint(x0-a,y0-b); //2 LCD_DrawPoint(x0+b,y0+a); //4 LCD_DrawPoint(x0+a,y0-b); //5 LCD_DrawPoint(x0+a,y0+b); //6 LCD_DrawPoint(x0-b,y0+a); a++; //使用Bresenham演算法畫圓 if(di<0){ di +=4*a+6; }else{ di+=10+4*(a-b); b--; } LCD_DrawPoint(x0+a,y0+b); } } //在指定位置顯示一個字元 //x:0~234 //y:0~308 //num:要顯示的字元:" "--->"~" //size:字型大小 12/16 //mode:疊加方式(1)還是非疊加方式(0) void LCD_ShowChar(u8 x,u16 y,u8 num,u8 size,u8 mode) { #if USE_HORIZONTAL #define MAX_CHAR_POSX 312 #define MAX_CHAR_POSY 232 u8 temp; u8 pos,t; u16 x0=x; u16 colortemp=POINT_COLOR; if(x>MAX_CHAR_POSX||y>MAX_CHAR_POSY)return; //設定視窗 num=num-' ';//得到偏移後的值 if(!mode) //非疊加方式 { for(pos=0;pos<size;pos++) { if(size==12) temp=asc2_1206[num][pos];//呼叫1206字型 else temp=asc2_1608[num][pos]; //呼叫1608字型 for(t=0;t<size/2;t++) { if(temp&0x01) POINT_COLOR=colortemp; else POINT_COLOR=BACK_COLOR; LCD_DrawPoint(x,y); temp>>=1; x++; } x=x0; y++; } }else{ //疊加方式 for(pos=0;pos<size;pos++) { if(size==12) temp=asc2_1206[num][pos];//呼叫1206字型 else temp=asc2_1608[num][pos]; //呼叫1608字型 for(t=0;t<size/2;t++) { if(temp&0x01)LCD_DrawPoint(x+t,y+pos);//畫一個點 temp>>=1; } } } POINT_COLOR=colortemp; #else #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_WriteReg(R80,x); //水平方向GRAM起始地址 LCD_WriteReg(R81,x+(size/2-1));//水平方向GRAM結束地址 LCD_WriteReg(R82,y); //垂直方向GRAM起始地址 LCD_WriteReg(R83,y+size-1); //垂直方向GRAM結束地址 LCD_SetCursor(x,y); //設定游標位置 LCD_WriteRAM_Prepare(); //開始寫入GRAM num=num-' ';//得到偏移後的值 if(!mode) //非疊加方式 { for(pos=0;pos<size;pos++) { if(size==12) temp=asc2_1206[num][pos];//呼叫1206字型 else temp=asc2_1608[num][pos]; //呼叫1608字型 for(t=0;t<size/2;t++) { if(temp&0x01){ LCD_WR_DATA(POINT_COLOR); }else{ LCD_WR_DATA(BACK_COLOR); } temp>>=1; } } }else{ //疊加方式 for(pos=0;pos<size;pos++) { if(size==12) temp=asc2_1206[num][pos]; //呼叫1206字型 else temp=asc2_1608[num][pos]; //呼叫1608字型 for(t=0;t<size/2;t++) { if(temp&0x01) LCD_DrawPoint(x+t,y+pos);//畫一個點 temp>>=1; } } } //恢復窗體大小 LCD_WriteReg(R80, 0x0000); //水平方向GRAM起始地址 LCD_WriteReg(R81, (LCD_WIDTH-1)); //水平方向GRAM結束地址 LCD_WriteReg(R82, 0x0000); //垂直方向GRAM起始地址 LCD_WriteReg(R83, (LCD_HEIGHT-1)); //垂直方向GRAM結束地址 #endif } //m^n函式 u32 mypow(u8 m,u8 n) { u32 result=1; while(n--)result*=m; return result; } //顯示數字 //x,y :起點座標 //len :數字的位數 //size:字型大小 //color:顏色 //num:數值(0~4294967295); void LCD_ShowNum(u8 x,u16 y,u32 num,u8 len,u8 size) { u8 t,temp; u8 enshow=0; for(t=0;t<len;t++) { temp=(num/mypow(10,len-t-1))%10; if(enshow==0&&t<(len-1)) { if(temp==0) { LCD_ShowChar(x+(size/2)*t,y,' ',size,0); continue; }else{ enshow=1; } } LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,0); } } //顯示字串 //x,y:起點座標 //*p:字串起始地址 //用16字型 void LCD_ShowString(u8 x,u16 y,const u8 *p) { while(*p!='\0') //字串到達結束 { if(x>MAX_CHAR_POSX){x=0;y+=16;} //換行 if(y>MAX_CHAR_POSY){y=x=0;LCD_Clear(WHITE);} //超出螢幕顯示範圍 LCD_ShowChar(x,y,*p,16,0); x+=8; p++; } }