使用虛擬顯存方式操作12864液晶
通常操作12864液晶時,畫點函數(shù)沒有TFT那么方便,我一直都是使用內(nèi)存虛擬一個顯存方式,畫點函數(shù)將使用內(nèi)存的一個bit,然后更新到實際屏幕上。12864液晶將需要1KB的內(nèi)存,我使用的256128需要4KB的內(nèi)存作為顯存。
這樣做的好處是,畫點函數(shù)非常靈活,可以隨意在屏幕的任意位置畫點,并且不受LCD廠家限制,對于UI的移植會非常方便。
//C文件
/************************************************************************************************************* ?*?文件名: LCD256128.c ?*?功能: JLX12864G-0088?LCD256128液晶驅(qū)動 ?*?作者: cp1300@139.com ?*?郵箱: cp1300@139.com ?*?創(chuàng)建時間: 2017年02月25日08:58 ?*?最后修改時間:2017年02月25日 ?*?詳細(xì): 漢字模取模方式:陰碼,逐行式,順向,高字節(jié)在前 ASCII字符取模方式:陰碼,列行式,逆向,低字節(jié)在前 2017-07-19:增加12x24大小的ASCII字符顯示 *************************************************************************************************************/ #include?"LCD256128.h" #include?"ascii_8x16.h" #if(LCD_ASCII_12X24_EN)?//12X24大小字符顯示 #include?"ASCII_12x24.h" #endif?//LCD_ASCII_12X24_EN //保存LCD對比度 static?u8?LCD_Cont?=?40; //LCD對比度調(diào)節(jié) #if?LCD_BUFF_ENABLE static?u8?LCD_BUFF[16][256];//顯存 #endif //漢字支持 #define?CHINESE_ENABLE 1 #if CHINESE_ENABLE #include?"fontlib.h" #endif #if?LCD_BUFF_ENABLE //使能了顯存 //獲取顯存地址 //2016-02-01:增加獲取顯存函數(shù) u8?*LCD256128_GetGramBuff(void) { return?(u8?*)&LCD_BUFF[0][0]; } //上電狀態(tài) static?bool?isPowerStatus?=?FALSE; #endif //LCD掉電,將所有的IO設(shè)置為下拉輸入模式 //喚醒后需要重新初始化 void?LCD256128_PowerDown(void) { LCD256128_DEFAULT(); isPowerStatus?=?FALSE; //屏幕掉電了 } //獲取上電狀態(tài) bool?LCD256128_GetPowerStatus(void) { return?isPowerStatus; } /************************************************************************************************************************* *?函數(shù) : void?LCD256128_WriteData(u8?data) *?功能 : 向LCD256128寫入一字節(jié)數(shù)據(jù) *?參數(shù) : data:數(shù)據(jù) *?返回 : 無 *?依賴 : 底層宏定義 *?作者 : cp1300@139.com *?時間 : 20120530 *?最后修改時間?:?20120530 *?說明 :? CD=1,時鐘上升沿數(shù)據(jù)有效,先發(fā)送高位 *************************************************************************************************************************/ void?LCD256128_WriteData(u8?data) { u8?i; LCD_CS_L(); nop;nop;nop; LCD_CD?=?1; nop;nop;nop; for(i?=?0;i?<?8;i?++) { ?LCD_SCK?=?0; ? ?LCD_SDA?=? (data?&?0x80)???1?:?0; ?nop;nop; ?LCD_SCK?=?1; ?nop;nop; ?data?<<=?1; nop;nop;nop;nop; } LCD_SCK?=?0; LCD_CS_H(); } /************************************************************************************************************************* *?函數(shù) : void?LCD256128_WriteCommand(u8?cmd) *?功能 : 向LCD256128寫入一字節(jié)命令 *?參數(shù) : cmd:命令 *?返回 : 無 *?依賴 : 底層宏定義 *?作者 : cp1300@139.com *?時間 : 20120530 *?最后修改時間?:?20120530 *?說明 :? CD=0,時鐘上升沿數(shù)據(jù)有效,先發(fā)送高位 *************************************************************************************************************************/ void?LCD256128_WriteCommand(u8?cmd) { u8?i; LCD_CS_L(); nop;nop;nop; LCD_CD?=?0; nop;nop;nop; for(i?=?0;i?<?8;i?++) { LCD_SCK?=?0; ? ?LCD_SDA?=? (cmd?&?0x80)???1?:?0; ?nop;nop; ?LCD_SCK?=?1; ?nop;nop; ?cmd?<<=?1; ?nop;nop;nop;nop; } LCD_SCK?=?0; LCD_CS_H(); } /************************************************************************************************************************* *?函數(shù) : static?void?LCD256128_SetAddress(u8?StartX,u8?StartY,?u8?EndX,u8?EndY) *?功能 : 設(shè)置光標(biāo)地址 *?參數(shù) : StartX:開始列地址;StartY:開始行地址;EndX:結(jié)束列地址;EndY:結(jié)束行地址 *?返回 : 無 *?依賴 : 底層宏定義 *?作者 : cp1300@139.com *?時間 : 2017-02-25 *?最后修改時間? :? 2017-02-25 *?說明 :? 16行(每行8點陣),256列,從0開始 *************************************************************************************************************************/ static?void?LCD256128_SetAddress(u8?StartX,u8?StartY,?u8?EndX,u8?EndY) { LCD256128_WriteCommand(0x15);? //設(shè)置列地址 LCD256128_WriteData(StartX); //起始地址 LCD256128_WriteData(EndX); //結(jié)束地址 LCD256128_WriteCommand(0x75);? //設(shè)置頁地址 LCD256128_WriteData(StartY); //起始地址 LCD256128_WriteData(EndY); //結(jié)束地址 LCD256128_WriteCommand(0x30);? //擴展指令1 LCD256128_WriteCommand(0x5c);? //寫數(shù)據(jù) } /************************************************************************************************************************* *?函數(shù) : void?LCD256128_ClearAll(void) *?功能 : LCD256128液晶清屏 *?參數(shù) : 無 *?返回 : 無 *?依賴 : 底層宏定義 *?作者 : cp1300@139.com *?時間 : 20120530 *?最后修改時間?:?20120530 *?說明 :? 無 *************************************************************************************************************************/ void?LCD256128_ClearAll(void) { u16?i,j; LCD256128_SetAddress(0,0,?255,16); for(i?=?0;i?<?17;i?++) { for(j?=?0;j?<?256;j?++) { LCD256128_WriteData(0x00); } } } /************************************************************************************************************************* *?函數(shù) : void?LCD256128_ShowChar(u8?x,u8?y,char?CHAR,u8?FontSize) *?功能 : 在指定位置顯示一個字符 *?參數(shù) : x:列地址,共256列;y:行地址,共16行,CHAR:需要顯示的字符,FontSize:字體大小 *?返回 : 無 *?依賴 : 底層宏定義 *?作者 : cp1300@139.com *?時間 : 20120530 *?最后修改時間? :? 2017-02-25 *?說明 :? 顯示一個ASCII字符 *************************************************************************************************************************/ void?LCD256128_ShowChar(u8?x,u8?y,char?CHAR,u8?FontSize) { const?unsigned?char?*p; u16?i; u16?xend,yend; u16?size; CHAR?-=?32; if(CHAR?>?ASCII_MAX?-?1) return; if(FontSize?==?12) { p?=?ASCII_8X12[CHAR]; //12號 xend?=?x+8-1; yend?=?y+2-1; size?=?2*8; } else?if(FontSize==16) { p?=?ASCII_8X16[CHAR]; //16號 xend?=?x+8-1; yend?=?y+2-1; size?=?2*8; } #if(LCD_ASCII_12X24_EN)?//12X24大小字符顯示 else?if(FontSize==24) { p?=?ASCII_12X24[CHAR]; //24號 xend?=?x+12-1; yend?=?y+3-1; size?=?3*12; } #endif?//LCD_ASCII_12X24_EN else { p?=?ASCII_8X12[CHAR]; //12號 xend?=?x+8-1; yend?=?y+2-1; size?=?2*8; } LCD256128_SetAddress(x,y,?xend,?yend); for(i?=?0;i?<?size;i?++) { LCD256128_WriteData(p[i]); } } /************************************************************************************************************************* *?函數(shù) : void?LCD_PrintfChar(u8?PageAdd,u8?LineAdd,const?char?*p,u8?FontSize) *?功能 : 在指定位置顯示字符串 ?? *?參數(shù) : x:列地址,共256列;y:行地址,共16行,;p:字符指針,FontSize:子大小;16或者12 *?返回 : 無 *?依賴 : LCD256128_ShowChar *?作者 : cp1300@139.com *?時間 : 20120601 *?最后修改時間? :? 2017-02-25 *?說明 :? FontSize?=?16或者?12 *************************************************************************************************************************/ void?LCD_PrintfChar(u8?x,u8?y,const?char?*p,u8?FontSize) { u8?width; switch(FontSize) { case?12:width=8;break; case?16:width=8;break; case?24:width=12;break; default:width=8;break; } while(*p?!=?0)? { LCD256128_ShowChar(x,y,*p,FontSize); p?++; x?+=?width; } } /************************************************************************************************************************* *?函數(shù) : void?LCD256128_SetConAdj(u8?cont) *?功能 : 設(shè)置液晶的對比度 *?參數(shù) : cont:對比度值 *?返回 : 無 *?依賴 : 底層宏定義 *?作者 : cp1300@139.com *?時間 : 2014-08-24 *?最后修改時間?:?2014-08-24 *?說明 :? 需要先初始化LCD *************************************************************************************************************************/ void?LCD256128_SetConAdj(u8?cont) { if(cont?>?63)?cont?=?63; LCD256128_WriteCommand(0x81);?//設(shè)置對比度,“0x81”不可改動,緊跟著的2?個數(shù)據(jù)是可改的,但“先微調(diào)后粗調(diào)”這個順序別亂了 LCD256128_WriteData(cont);?//對比度微調(diào),可調(diào)范圍0x00~0x3f,共64?級 LCD256128_WriteData(0x04);?//對比度粗調(diào),可調(diào)范圍0x00~0x07,共8?級 LCD_Cont?=?cont; //更新對比度 } /************************************************************************************************************************* *?函數(shù) : void?LCD256128_Init(void) *?功能 : 初始化LCD256128液晶 *?參數(shù) : 無 *?返回 : 無 *?依賴 : 底層宏定義 *?作者 : cp1300@139.com *?時間 : 20120530 *?最后修改時間?:?20120530 *?說明 :? 初始化LCD256128液晶 *************************************************************************************************************************/ void?LCD256128_Init(u8?LCDCont) { LCD256128_DeInit(); //初始化液晶IO LCD_RST?=?0;?? //液晶復(fù)位開始 Delay_MS(1); LCD_RST?=?1;?? //液晶復(fù)位結(jié)束 Delay_MS(1); LCD256128_WriteCommand(0x30);? //EXT1=0,EXT0=0,表示選擇了“擴展指令表1” LCD256128_WriteCommand(0x94);? //退出睡眠 LCD256128_WriteCommand(0x31); //EXT=1 LCD256128_WriteCommand(0xD7);? //Autoread?disable LCD256128_WriteData(0X9F);? // LCD256128_WriteCommand(0x32);? //LCD?偏壓比設(shè)置 LCD256128_WriteData(0x00);? //振蕩頻率的調(diào)整 LCD256128_WriteData(0x01);? //升壓電容器的頻率->6KHz LCD256128_WriteData(0x04);? //Bias=1/11 LCD256128_WriteCommand(0x20);? //灰度設(shè)置 LCD256128_WriteData(0x01); LCD256128_WriteData(0x03); LCD256128_WriteData(0x05); LCD256128_WriteData(0x07); LCD256128_WriteData(0x09); LCD256128_WriteData(0x0b); LCD256128_WriteData(0x0d); LCD256128_WriteData(0x10); LCD256128_WriteData(0x11); LCD256128_WriteData(0x13); LCD256128_WriteData(0x15); LCD256128_WriteData(0x17); LCD256128_WriteData(0x19); LCD256128_WriteData(0x1b); LCD256128_WriteData(0x1d); LCD256128_WriteData(0x1f); LCD256128_WriteCommand(0x30);?//?EXT1=0,EXT0=0,表示選擇了“擴展指令表1” LCD256128_WriteCommand(0x75);?//?頁地址設(shè)置 LCD256128_WriteData(0X00);?//?起始頁地址:YS=0X00 LCD256128_WriteData(0X1f);?//?結(jié)束頁地址:YE=0x1F?每4?行為一頁,第0~3?行為第0?頁,第124~127?行為第31?頁(31=0x1f) LCD256128_WriteCommand(0x15);?//?列地址設(shè)置 LCD256128_WriteData(0X00);?//?起始列地址:XS=0 LCD256128_WriteData(0Xff);?//?結(jié)束列地址:XE=256(0xff) LCD256128_WriteCommand(0xBC);?//數(shù)據(jù)掃描方向 LCD256128_WriteData(0x00);?//MX.MY=Normal LCD256128_WriteData(0xA6); LCD256128_WriteCommand(0x0c);?//數(shù)據(jù)格式選擇,0x0C?是低位在前D0-D7,0x08?是高位在前D7-D0 LCD256128_WriteCommand(0xCA);?//顯示控制 LCD256128_WriteData(0X00);?//設(shè)置CL?驅(qū)動頻率:CLD=0 LCD256128_WriteData(0X7F);?//占空比:Duty=128 LCD256128_WriteData(0X20);?//N?行反顯:Nline=off LCD256128_WriteCommand(0xF0);?//顯示模式 LCD256128_WriteData(0X10);?//如果設(shè)為0x11:表示選擇4?灰度級模式,如果設(shè)為0x10:表示選擇黑白模式 LCD256128_WriteCommand(0x81);?//設(shè)置對比度,“0x81”不可改動,緊跟著的2?個數(shù)據(jù)是可改的,但“先微調(diào)后粗調(diào)”這個順序別亂了 LCD256128_WriteData(0x10);?//對比度微調(diào),可調(diào)范圍0x00~0x3f,共64?級 LCD256128_WriteData(0x04);?//對比度粗調(diào),可調(diào)范圍0x00~0x07,共8?級 LCD256128_WriteCommand(0x20);?//Power?control LCD256128_WriteData(0x0B);?//D0=regulator?;?D1=follower?;?D3=booste,?on:1?off:0 LCD256128_SetConAdj(LCDCont); Delay_US(100); LCD256128_WriteCommand(0xAF);?//打開顯示 LCD256128_ClearAll(); //清屏 //#if(LCD_ROTATE_180) //旋轉(zhuǎn)180度顯示 // LCD256128_WriteCommand(0xc0);?/*行掃描順序:從下到上*/ // LCD256128_WriteCommand(0xa1);?/*列掃描順序:從右到左*/ //#else // LCD256128_WriteCommand(0xc8);?/*行掃描順序:從上到下*/ // LCD256128_WriteCommand(0xa0);?/*列掃描順序:從左到右*/ //#endif LCD_LED_ON(); //開液晶背光 LCD_Cont?=?LCDCont; isPowerStatus?=?TRUE; //上電完成 } #if?LCD_BUFF_ENABLE //使能了顯存 /************************************************************************************************************************* *?函數(shù) : void?GRAM_DrawPoint(u8?x,u8?y) *?功能 : 在顯存里面指定位置畫點 *?參數(shù) : x:X坐標(biāo),0-127;y:y坐標(biāo),0-63 *?返回 : 無 *?依賴 : 底層宏定義 *?作者 : cp1300@139.com *?時間 : 20120531 *?最后修改時間?:?20120531 *?說明 :? 無 *************************************************************************************************************************/ void?GRAM_DrawPoint(u8?x,u8?y) { if(y?>?127) return; LCD_BUFF[y?/?8][x]?|=?(1?<<?(y?%?8)); } /************************************************************************************************************************* *?函數(shù) : void?GRAM_ClearPoint(u8?x,u8?y) *?功能 : 擦除顯存里面指定位置的點 *?參數(shù) : x:X坐標(biāo),0-127;y:y坐標(biāo),0-63 *?返回 : 無 *?依賴 : 底層宏定義 *?作者 : cp1300@139.com *?時間 : 20120531 *?最后修改時間?:?20120531 *?說明 :? 無 *************************************************************************************************************************/ void?GRAM_ClearPoint(u8?x,u8?y) { if(y?>?127) return; LCD_BUFF[y?/?8][x]?&=?~(1?<<?(y?%?8)); } /************************************************************************************************************************* *?函數(shù) : void?GRAM_ClearAll(void) *?功能 : 清除全部顯存 *?參數(shù) : 無 *?返回 : 無 *?依賴 : 底層宏定義 *?作者 : cp1300@139.com *?時間 : 20120531 *?最后修改時間?:?20120531 *?說明 :? 無 *************************************************************************************************************************/ void?GRAM_ClearAll(void) { u16?i,j; for(i?=?0;i?<?16;i?++) { for(j?=?0;j?<?256;j?++) { ? LCD_BUFF[i][j]?=?0x00; } } } /************************************************************************************************************************* *?函數(shù) : void?GRAM_Up(u8?x1,u8?y1,u8?x2,u8?y2) *?功能 : 更新顯存至液晶 *?參數(shù) : x1,y1:起始坐標(biāo);x2,y2:終點坐標(biāo) *?返回 : 無 *?依賴 : 底層宏定義 *?作者 : cp1300@139.com *?時間 : 20120531 *?最后修改時間?:?20120531 *?說明 :? y坐標(biāo)會頁對齊 *************************************************************************************************************************/ void?GRAM_Up(u8?x1,u8?y1,u8?x2,u8?y2) { ? u16?i,j; // static?u8?cnt?=?0; y1?/=?8;??//計算頁地址 y2?/=?8; /*cnt?++; if(cnt?>?3) { LCD_RST?=?0;?? //液晶復(fù)位開始 Delay_US(1); LCD_RST?=?1;?? //液晶復(fù)位結(jié)束 LCD256128_WriteCommand(0xe2);?//軟復(fù)位 LCD256128_WriteCommand(0x2c);?//升壓步聚1 LCD256128_WriteCommand(0x2e);?//升壓步聚2 LCD256128_WriteCommand(0x2f);?//升壓步聚3 LCD256128_WriteCommand(0x23);?//粗調(diào)對比度,可設(shè)置范圍20~27 LCD256128_SetConAdj(LCD_Cont); LCD256128_WriteCommand(0xa2);?//1/9?偏壓比(bias) LCD256128_WriteCommand(0xaf);?//開顯示 cnt?=?0; #if(LCD_ROTATE_180) //旋轉(zhuǎn)180度顯示 LCD256128_WriteCommand(0xc0);?//行掃描順序:從下到上 LCD256128_WriteCommand(0xa1);?//列掃描順序:從右到左 #else LCD256128_WriteCommand(0xc8);?//行掃描順序:從上到下 LCD256128_WriteCommand(0xa0);?//列掃描順序:從左到右 #endif LCD256128_WriteCommand(0x40);?//初始化顯示行為0 }*/ LCD256128_SetAddress(x1,y1,?x2,y2); for(i?=?0;i?<?(y2?-?y1?+?1);i?++) { for(j?=?0;j?<?(x2?-?x1?+?1);j?++) { LCD256128_WriteData(LCD_BUFF[y1?+?i][x1?+?j]); } } } /************************************************************************************************************************* *?函數(shù) : void?GRAM_ShowChina(u8?x,u8?y,const?u8?*p,FONT_MODE?FontMode) *?功能 : 在指定位置顯示一個指定大小的漢字? *?參數(shù) : x,y:顯示開始坐標(biāo),p:漢子點陣緩沖區(qū); FontMode:漢子顯示模式, 0x80:疊加顯示,0x40:反顯,?0:16號字體;1:12號字體 *?返回 : 無 *?依賴 : 畫點函數(shù) *?作者 : cp1300@139.com *?時間 : 20120531 *?最后修改時間?:?20120531 *?說明 :? FontSize?=?16或者?12 *************************************************************************************************************************/ void?GRAM_ShowChina(u8?x,u8?y,const?u8?*p,FONT_MODE?FontMode) { u8?i,j; u8?FontSize?=?(u8)FontMode?&?0x3f; //獲取字體大小 void?(*DrawPoint)(u8?i,u8?j); void?(*ClearPoint)(u8?i,u8?j); if(FontMode?&?0x40) //反顯 { DrawPoint?=?GRAM_ClearPoint; ClearPoint?=??GRAM_DrawPoint; } else?//正常模式 { ClearPoint?=??GRAM_ClearPoint; DrawPoint?=??GRAM_DrawPoint; } if(FontMode?&?0x80) //疊加顯示 { for(i?=?0;i?<?FontSize;i?++) { ? for(j?=?0;j?<?8;j?++) { ? if(*p?&?0x80?>>?j) (*DrawPoint)(x?+?j,y?+?i); } p?++; for(j?=?0;j?<?FontSize?-?8;j?++) { if(*p?&?0x80?>>?j) (*DrawPoint)(x?+?j?+?8,y?+?i); } p?++; } } else //非疊加顯示 { for(i?=?0;i?<?FontSize;i?++) { ? for(j?=?0;j?<?8;j?++) { ? if(*p?&?0x80?>>?j) (*DrawPoint)(x?+?j,y?+?i); else (*ClearPoint)(x?+?j,y?+?i); } p?++; for(j?=?0;j?<?FontSize?-?8;j?++) { if(*p?&?0x80?>>?j) (*DrawPoint)(x?+?j?+?8,y?+?i); else (*ClearPoint)(x?+?j?+?8,y?+?i); } p?++; } } } /************************************************************************************************************************* *?函數(shù) : void?GRAM_ShowChar(u8?x,u8?y,char?,FONT_MODE?FontMode) *?功能 : 在指定位置顯示一個指定大小的字符 *?參數(shù) : x,y:顯示開始坐標(biāo),p:漢子點陣緩沖區(qū); FontMode:漢子顯示模式, 0x80:疊加顯示,0x40:反顯,?0:16號字體;1:12號字體 *?返回 : 無 *?依賴 : 畫點函數(shù) *?作者 : cp1300@139.com *?時間 : 20120603 *?最后修改時間?:?20120603 *?說明 :? FontSize?=?16或者?12 *************************************************************************************************************************/ void?GRAM_ShowChar(u8?x,u8?y,u8?CHAR,FONT_MODE?FontMode) { u8?i,j,k; u8?FontSize?=?(u8)FontMode&0x3f; //獲取字體大小 u8?*p; u8?rows; //一個字符占用幾個8行 u8?column; //列數(shù)量 u8?temp; void?(*DrawPoint)(u8?i,u8?j); void?(*ClearPoint)(u8?i,u8?j); CHAR?-=?32; if(CHAR?>?ASCII_MAX?-?1) return; if(FontSize==12) { rows?=?2; column?=?8; p?=?(u8?*)ASCII_8X12[CHAR]; //12號 } else?if(FontSize?==?16) { rows?=?2; column?=?8; p?=?(u8?*)ASCII_8X16[CHAR]; //16號 } #if(LCD_ASCII_12X24_EN)?//12X24大小字符顯示 else?if(FontSize==24) { rows?=?3; column?=?12; p?=?(u8?*)ASCII_12X24[CHAR]; //24號 } #endif?//LCD_ASCII_12X24_EN else? { rows?=?2; column?=?8; p?=?(u8?*)ASCII_8X12[CHAR]; //12號 } if(FontMode?&?0x40) //反顯 { DrawPoint?=?GRAM_ClearPoint; ClearPoint?=??GRAM_DrawPoint; } else?//正常模式 { ClearPoint?=??GRAM_ClearPoint; DrawPoint?=??GRAM_DrawPoint; } temp?=?8; if(FontMode?&?0x80) //疊加顯示 { for(k?=?0;k?<?rows;k?++) { for(j?=?0;j?<?column;j?++) { for(i?=?0;i?<?temp;i?++) { if(*p?&?(1?<<?i)) (*DrawPoint)(x?+?j,k*8+y?+?i); } p?++; } FontSize?-=?8; if(FontSize?>=?8)?temp?=?8; else?temp?=?FontSize; } /*for(j?=?0;j?<?8;j?++) { ? for(i?=?0;i?<?FontSize?-?8;i?++) { if(*p?&?(1?<<?i)) (*DrawPoint)(x?+?j,y?+?8?+?i); } p?++; }*/ } else //非疊加顯示 { for(k?=?0;k?<?rows;k?++) { for(j?=?0;j?<?column;j?++) { for(i?=?0;i?<?temp;i?++) { if(*p?&?(1?<<?i)) (*DrawPoint)(x?+?j,k*8+y?+?i); else (*ClearPoint)(x?+?j,k*8+y?+?i); } p?++; } FontSize?-=?8; if(FontSize?>=?8)?temp?=?8; else?temp?=?FontSize; } /* for(j?=?0;j?<?8;j?++) { ? for(i?=?0;i?<?FontSize?-?8;i?++) { if(*p?&?(1?<<?i)) (*DrawPoint)(x?+?j,y?+?8?+?i); else (*ClearPoint)(x?+?j,y?+?8?+?i); } p?++; }*/ } } /************************************************************************************************************************* *?函數(shù) : void?LCD_Fill(u16?xStart,?u16?xEnd,?u16?yStart,?u16?yEnd) *?功能 : 指定位置填充顏色 *?參數(shù) : 位置坐標(biāo) *?返回 : 無 *?依賴 : 底層函數(shù) *?作者 : cp1300@139.com *?時間 : 20110920 *?最后修改時間?:?20110920 *?說明 :? 無 *************************************************************************************************************************/ void?GRAM_Fill(u16?xStart,?u16?yStart,u16?xEnd,??u16?yEnd) { ? u16?i,j; for(i?=?xStart;i?<?(xEnd+1);?i?++) { for(j?=?yStart;j?<?(yEnd+1);j?++) { GRAM_DrawPoint(i,j); } } } /************************************************************************************************************************* *?函數(shù) : void?GRAM_Clear(u16?xStart,?u16?yStart,?u16?xEnd,?u16?yEnd) *?功能 : 清除指定位置 *?參數(shù) : 位置坐標(biāo) *?返回 : 無 *?依賴 : 底層函數(shù) *?作者 : cp1300@139.com *?時間 : 20110920 *?最后修改時間?:?20110920 *?說明 :? 無 *************************************************************************************************************************/ void?GRAM_Clear(u16?xStart,?u16?yStart,?u16?xEnd,?u16?yEnd) { ? u16?i,j; for(i?=?xStart;i?<?(xEnd+1);?i?++) { for(j?=?yStart;j?<?(yEnd+1);j?++) { GRAM_ClearPoint(i,j); } } } /************************************************************************************************************************* *?函數(shù) : void?GRAM_DrawLine(u16?x1,?u16?y1,?u16?x2,?u16?y2) *?功能 : 畫線函數(shù) *?參數(shù) : 起點終點坐標(biāo) *?返回 : 無 *?依賴 : 畫點函數(shù) *?作者 : cp1300@139.com *?時間 : 20110920 *?最后修改時間?:?20110920 *?說明 :? 無 *************************************************************************************************************************/? void?GRAM_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; //TFT_LCD_SetRamAddr(0,239,0,319);//設(shè)置顯示窗口? delta_x=x2-x1;?//計算坐標(biāo)增量? delta_y=y2-y1;? uRow=x1;? uCol=y1;? if(delta_x>0)incx=1;?//設(shè)置單步方向? 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;?//選取基本增量坐標(biāo)軸? else?distance=delta_y;? for(t=0;tdistance)? {? xerr-=distance;? uRow+=incx;? }? if(yerr>distance)? {? yerr-=distance;? uCol+=incy;? }? }?? } ? ??? /************************************************************************************************************************* *?函數(shù) : void?GRAM_DrawRectangle(u16?x1,?u16?y1,?u16?x2,?u16?y2) *?功能 : 在指定位置畫一個矩形 *?參數(shù) : 多邊形的兩個坐標(biāo) *?返回 : 無 *?依賴 : 畫線函數(shù) *?作者 : cp1300@139.com *?時間 : 20110920 *?最后修改時間?:?20110920 *?說明 :? 無 *************************************************************************************************************************/ void?GRAM_DrawRectangle(u16?x1,?u16?y1,?u16?x2,?u16?y2) { GRAM_DrawLine(x1,y1,x2,y1); GRAM_DrawLine(x1,y1,x1,y2); GRAM_DrawLine(x1,y2,x2,y2); GRAM_DrawLine(x2,y1,x2,y2); } /************************************************************************************************************************* *?函數(shù) : void?GRAM_ShowString(u16?x,u16?y,const?u8?*pStr,FONT_MODE?Font_MODE) *?功能 : 在顯存指定位置顯示字符串 *?參數(shù) : x,y:顯示開始坐標(biāo),pStr:字符串緩沖區(qū); FontMode:顯示模式, 0x80:疊加顯示,0x40:反顯,?0:16號字體;1:12號字體 *?返回 : 無 *?依賴 : 畫點函數(shù) *?作者 : cp1300@139.com *?時間 : 2014-08-20 *?最后修改時間?:?2014-08-20 *?說明 :? FontSize?=?16或者?12 *************************************************************************************************************************/ void?GRAM_ShowString(u16?x,u16?y,const?char?*pStr,FONT_MODE?Font_MODE) { u8?Font_Size?=?Font_MODE?&?0x3f; u8?width; #if CHINESE_ENABLE u8?buff[32]; #endif switch(Font_Size) { case?12:width=16;break; case?16:width=16;break; case?24:width=24;break; default:width=16;break; } while(*pStr?!=?0) { #if CHINESE_ENABLE if(*pStr?>?0x80)//漢字 { FONT_GetFontLattice(buff,?(u8*)pStr,?ST16X16); //獲取漢字點陣 ? GRAM_ShowChina(x,y,buff,Font_MODE); //顯示漢字 pStr?+=?2; if(x?>?256?-?16)??//自動換行 { ? x?=?0; y?+=?Font_Size; } else { x?+=?width; } } else?//ASCII #endif { GRAM_ShowChar(x,y,*pStr,Font_MODE); pStr++; if(x?>?256?-?8)??//自動換行 { ? x?=?0; y?+=?Font_Size; } else { x?+=?width/2; } } } } /************************************************************************************************************************* *?函數(shù) : void?GRAM_ShowLattice(u16?x,u16?y,u16?width,?u16?height,?const?u8?LatticeBuff[],?bool?isInvert) *?功能 : 在指定位置顯示一個指定大小的點陣數(shù)據(jù) *?參數(shù) : x,y:顯示開始坐標(biāo),width:點陣寬度;height:點陣高度;LatticeBuff:點陣數(shù)據(jù)緩沖區(qū);isInvert:是否反色顯示 *?返回 : 無 *?依賴 : 畫點函數(shù) *?作者 : cp1300@139.com *?時間 : 2016-03-25 *?最后修改時間? :? 2016-03-25 *?說明 :? 用于顯示自定義字符 字符高度任意,寬度不足8的倍數(shù)需要補充為8的倍數(shù)進行存儲,但是不顯示 字模取模方式:陰碼,逐行式,順向,高字節(jié)在前 *************************************************************************************************************************/ void?GRAM_ShowLattice(u8?x,u8?y,u16?width,?u16?height,?const?u8?LatticeBuff[],?bool?isInvert) { u16?i,j,k; u8?*p; void?(*DrawPoint)(u8?i,u8?j); u16?w?=?width?/?8; //計算整數(shù)行 u16?res?=?width?%?8; //計算非整數(shù)行 p?=?(u8?*)LatticeBuff; if(isInvert) //反顯 { DrawPoint?=?GRAM_ClearPoint; //清除點函數(shù) GRAM_Fill(x,y,x+width-1,y+height-1); //填充滿區(qū)域 } else?//正常模式 { DrawPoint?=??GRAM_DrawPoint; //畫點函數(shù) GRAM_Clear(x,y,x+width-1,y+height-1); //清空顯示區(qū)域 } for(i?=?0;i?<?height;i?++) //逐行繪制 { for(j?=?0;j?<?w;j?++) //整8的倍數(shù)的列先進行繪制 { for(k?=?0;k?<?8;k?++) { if(*p?&?(0x80?>>?k)) (*DrawPoint)(x?+?j*8+k,y?+?i); } p?++; } for(k?=?0;k?<?res;k?++) { if(*p?&?(0x80?>>?k)) (*DrawPoint)(x?+?w*8+k,y?+?i); } if(res?>?0)?p?++; } /* for(i?=?0;i?<?16;i?++) { for(j?=?0;j?<?8;j?++) { if(*p?&?0x80?>>?j) (*DrawPoint)(x?+?j,y?+?i); } p?++; for(j?=?0;j?<?16?-?8;j?++) { if(*p?&?0x80?>>?j) (*DrawPoint)(x?+?j?+?8,y?+?i); } p?++; } */ } #endif
//H文件
/************************************************************************************************************* ?*?文件名: LCD256128.H ?*?功能: JLX12864G-0088?LCD256128液晶驅(qū)動 ?*?作者: cp1300@139.com ?*?郵箱: cp1300@139.com ?*?創(chuàng)建時間: 2017年02月25日08:58 ?*?最后修改時間:2017年02月25日 ?*?詳細(xì): *************************************************************************************************************/ #ifndef?_LCD256128_H_ #define?_LCD256128_H_ #include?"system.h" #include?"gpio_init.h" #include?"delay.h" //LCD型號 #define? JLX256128G_256 0 #if(BOARD_SUPPORT) //需要板級支持 #include?"board.h"? #else //默認(rèn)支持 #define?LCD_SDA PFout(6) //數(shù)據(jù)線 #define?LCD_SCK PFout(7) //串行時鐘 #define?LCD_CD PFout(8) //H:數(shù)據(jù)寄存器;L:指令寄存器 #define?LCD_RST PFout(9) //復(fù)位,低電平有效 //片選,低電平有效 #define?LCD_CS_H() #define?LCD_CS_L() //液晶背光,高電平有效 #define?LCD_LED_H() #define?LCD_LED_L() //液晶硬件IO初始化函數(shù) #define?LCD256128_DeInit() { DeviceClockEnable(DEV_GPIOF,?ENABLE); GPIOx_Init(GPIOF?,BIT6?|?BIT7?|?BIT8?|?BIT9,?OUT_PP,SPEED_50M); LCD_SDA=LCD_SCK=LCD_CD=LCD_RST=1; LCD_CS_H(); } //液晶硬件IO低功耗模式 #define?LCD256128_DEFAULT() { GPIOx_Init(GPIOF?,BIT6?|?BIT7?|?BIT8?|?BIT9,?IN_IPT,IN_IN); } //旋轉(zhuǎn)180度顯示 #define? LCD_ROTATE_180 0 //LCD型號 #define?LCD256128_MODEL JLX256128G_256 #endif //LCD?列坐標(biāo)偏移,某些LCD旋轉(zhuǎn)180度后X坐標(biāo)需要偏移 #if((LCD256128_MODEL==JLX256128G_256)&&LCD_ROTATE_180) #define?LCD256128_X_OFFSET 4 #else #define?LCD256128_X_OFFSET 0 #endif #define?LCD_ASCII_12X24_EN 0 //是否使能12x24大小字符顯示 #define?LCD_BUFF_ENABLE 1 //使能顯存 //關(guān)背光 #define?LCD_LED_OFF() LCD_LED_L() //開背光 #define?LCD_LED_ON() LCD_LED_H() void?LCD256128_PowerDown(void); //掉電 void?LCD256128_Init(u8?LCDCont); //初始化12864 void?LCD256128_ClearAll(void?); void?LCD_PrintfChar(u8?x,u8?y,const?char?*p,u8?FontSize); //字符串顯示函數(shù) void?LCD256128_SetConAdj(u8?cont); #if?LCD_BUFF_ENABLE //使能了顯存 typedef?enum { FONT24_DEFAULT? =?(0x80+24), //24號,疊加顯示 FONT16_DEFAULT? =?(0x80+16), //16號,疊加顯示 FONT12_DEFAULT? =?(0x80+12), //12號,疊加顯示 FONT24_COVER? =? (24), //16號,覆蓋顯示 FONT16_COVER? =? (16), //16號,覆蓋顯示 FONT12_COVER? =? (12), //12號,覆蓋顯示 FONT24_REVERSE? =?(0x40+24), //24號,反顯顯示 FONT16_REVERSE? =?(0x40+16), //16號,反顯顯示 FONT12_REVERSE? =?(0x40+12), //12號,反顯顯示 }FONT_MODE; void?GRAM_DrawPoint(u8?x,u8?y); //顯存寫點 void?GRAM_ClearPoint(u8?x,u8?y);? //顯存擦點 void?GRAM_ClearAll(void); //清除顯存 void?GRAM_Up(u8?x1,u8?y1,u8?x2,u8?y2); //更新顯存 #define?GRAM_UpAll() GRAM_Up(0,0,255,127) //更新全部顯存 void?GRAM_ShowChina(u8?x,u8?y,const?u8?*p,FONT_MODE?FontMode); //漢子顯示 void?GRAM_ShowChar(u8?x,u8?y,u8?CHAR,FONT_MODE?FontMode); //ASCII顯示 void?GRAM_Fill(u16?xStart,?u16?yStart,u16?xEnd,??u16?yEnd); void?GRAM_Clear(u16?xStart,?u16?xEnd,?u16?yStart,?u16?yEnd); void?GRAM_DrawLine(u16?x1,?u16?y1,?u16?x2,?u16?y2); void?GRAM_DrawRectangle(u16?x1,?u16?y1,?u16?x2,?u16?y2); void?GRAM_ShowString(u16?x,u16?y,const?char?*pStr,FONT_MODE?Font_MODE); u8?*LCD256128_GetGramBuff(void);//獲取顯存地址 //獲取上電狀態(tài) bool?LCD256128_GetPowerStatus(void); void?GRAM_ShowLattice(u8?x,u8?y,u16?width,?u16?height,?const?u8?LatticeBuff[],?bool?isInvert); #endif #endif //_LCD256128_H_
//ASCII編碼
#ifndef?_ASCII_8X16_H_ #define?_ASCII_8X16_H_ //字模取模方式:陰碼,列行式,逆向,低字節(jié)在前 //?!"#$%&'()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~ #define?ASCII_MAX 95 const?unsigned?char??ASCII_8X16[ASCII_MAX][16] =?{ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"?",0*/ {0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00},/*"!",1*/ {0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/ {0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00},/*"#",3*/ {0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00},/*"$",4*/ {0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00},/*"%",5*/ {0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10},/*"&",6*/ {0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/ {0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00},/*"(",8*/ {0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00},/*")",9*/ {0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00},/*"*",10*/ {0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00},/*"+",11*/ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00},/*",",12*/ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01},/*"-",13*/ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00},/*".",14*/ {0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00},/*"/",15*/ {0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00},/*"0",16*/ {0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},/*"1",17*/ {0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},/*"2",18*/ {0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00},/*"3",19*/ {0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00},/*"4",20*/ {0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00},/*"5",21*/ {0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00},/*"6",22*/ {0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00},/*"7",23*/ {0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},/*"8",24*/ {0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00},/*"9",25*/ {0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00},/*":",26*/ {0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00},/*";",27*/ {0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00},/*"<",28*/ {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00},/*"=",29*/ {0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00},/*">",30*/ {0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00},/*"?",31*/ {0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00},/*"@",32*/ {0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20},/*"A",33*/ {0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00},/*"B",34*/ {0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00},/*"C",35*/ {0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00},/*"D",36*/ {0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00},/*"E",37*/ {0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00},/*"F",38*/ {0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00},/*"G",39*/ {0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20},/*"H",40*/ {0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},/*"I",41*/ {0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00},/*"J",42*/ {0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00},/*"K",43*/ {0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00},/*"L",44*/ {0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00},/*"M",45*/ {0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00},/*"N",46*/ {0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00},/*"O",47*/ {0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00},/*"P",48*/ {0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00},/*"Q",49*/ {0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20},/*"R",50*/ {0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00},/*"S",51*/ {0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},/*"T",52*/ {0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},/*"U",53*/ {0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00},/*"V",54*/ {0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00},/*"W",55*/ {0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20},/*"X",56*/ {0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},/*"Y",57*/ {0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x2