昨晚瘋狂的打了一夜的LOL,感覺L多了,今天一天精神萎靡.還是繼續把顯示字符給看了,但是在猶豫要不要寫這篇文章
其實寫的東西也就是copy別人家的代碼,不想寫那麼多,就記錄下自己困惑的地方吧.或許改天回來看的時候能讓自己快速的明白
也或許能幫助到有些朋友..
看了奮鬥給的例子和偷偷去下了正點原子的例子,其實都是差不多的,只要稍微改下都可以通用的,原理就在那裏,跑不了.
奮鬥給的例子,都是人家的
void lcd_wr_zf(u16 StartX, u16 StartY, u16 X, u16 Y, u16 Color, u8 Dir, u8 *chr)
{ unsigned int temp=0,num,R_dis_mem=0,Size=0,x=0,y=0,i=0;
if(Dir==2) LCD_WR_CMD(0x0003,0x1010); //圖像顯示方向爲右下起 行遞減 列遞增 AM=0 I/D[1:0]=00 <--
else if(Dir==3) LCD_WR_CMD(0x0003,0x1028); //圖像顯示方向爲右上起 行遞減 列遞增 AM=1 I/D[1:0]=10 V
if(Dir==0){
LCD_WR_CMD(0x0003,0x1030); //圖像顯示方向爲左上起 行遞增 列遞增 AM=0 I/D[1:0]=11 -->
LCD_WR_CMD(0x0210, StartX); //水平顯示區起始地址 0-239
LCD_WR_CMD(0x0211, StartX+X-1); //水平顯示區結束地址 0-239
LCD_WR_CMD(0x0212, StartY); //垂直顯示區起始地址 0-399
LCD_WR_CMD(0x0213, StartY+Y-1); //垂直顯示區結束地址 0-399
LCD_WR_CMD(0x0200, StartX); //水平顯示區地址
LCD_WR_CMD(0x0201, StartY); //垂直顯示區地址
LCD_WR_REG(0x0202); //準備寫數據顯示區
Size=X*Y; //字符串或字符佔用的像素尺寸
while(i<Size){
temp=*chr++; //一個字節代表8個像素,因此加1代表索引到下8個像素
for(num=0; num<8; num++){ //數組的每個字節代表了8個像素
if((temp&0x80)>0){ //對字節的各位進行判斷,爲1的用帶入參數的16位顏色值標示,寫入到像素位置。
LCD_WR_Data(Color);
}
else{
LCD_WR_CMD(0x0200, StartX+x); //水平顯示區地址
LCD_WR_CMD(0x0201, StartY+y); //垂直顯示區地址
LCD_WR_REG(0x0202); //準備讀數據顯示區
R_dis_mem=LCD_RD_data(); //讀取背景色,爲疊加產生透明效果作準備
LCD_WR_Data(R_dis_mem); //對字節的各位進行判斷,爲0的用當前背景像素16位顏色值標示。
}
temp=temp<<1; //字節各位的移出
x++;
if(x>=X){x=0; y++;} //計算像素遞增爲當前的x和y,爲當前像素讀背景顏色做準備
i++;
}
}
}
else if(Dir==1){
LCD_WR_CMD(0x0003,0x1018); //圖像顯示方向爲左下起 行遞增 列遞減 AM=1 I/D[1:0]=01 A
LCD_WR_CMD(0x0210, StartY); //水平顯示區起始地址 0-239
LCD_WR_CMD(0x0211, StartY+Y-1); //水平顯示區結束地址 0-239
LCD_WR_CMD(0x0212, 399-(StartX+X-1)); //垂直顯示區起始地址 0-399
LCD_WR_CMD(0x0213, 399-StartX); //垂直顯示區結束地址 0-399
LCD_WR_CMD(0x0200, StartY); //水平顯示區地址
LCD_WR_CMD(0x0201, 399-StartX); //垂直顯示區地址
LCD_WR_REG(0x0202); //準備寫數據顯示區
Size=X*Y; //字符串或字符佔用的像素尺寸
while(i<Size){
temp=*chr++; //一個字節代表8個像素,因此加1代表索引到下8個像素
for(num=0; num<8; num++){ //數組的每個字節代表了8個像素
if((temp&0x80)>0){ //對字節的各位進行判斷,爲1的用帶入參數的16位顏色值標示,寫入到像素位置。
LCD_WR_Data(Color);
}
else{
LCD_WR_CMD(0x0200, StartY+y); //水平顯示區地址
LCD_WR_CMD(0x0201, 399-(StartX+x)); //垂直顯示區地址
LCD_WR_REG(0x0202); //準備讀數據顯示區
R_dis_mem=LCD_RD_data(); //讀取背景色,爲疊加產生透明效果作準備
LCD_WR_Data(R_dis_mem); //對字節的各位進行判斷,爲0的用當前背景像素16位顏色值標示。
}
temp=temp<<1; //字節各位的移出
x++;
if(x>=X){x=0; y++;} //計算像素遞增爲當前的x和y,爲當前像素讀背景顏色做準備
i++;
}
}
}
}
程序沒難麼難理解的地方,慢慢看也就能懂了. 只是感覺奮鬥給的例子不夠模塊化,搞得一個函數要寫這麼行,其實是可以分成幾部分功能函數來實現的...
當然奮鬥這個例子中的字符數組是直接用取模工具取得的,這樣的做是可以顯示漢字,而常用的字符、數字、符號有個ASCII字符表,這裏就截一部分圖給看吧
這表百度一下都有的.
(只是部分圖)
大小16x8的
上面兩幅圖代表了兩種表,都差不多,就是大小不一樣而已..
這裏需要我們注意的是偏移量,上面是偏移量,按我自己的理解是一個字符真正開始的地方距離數組開頭的長度,這裏是32,爲什麼是32?
第0~32號及第127號(共34個)是控制字符或通訊專用字符,如控制符:LF(換行)、CR(回車)、FF(換頁)、DEL(刪除)、BEL(振鈴)等;通訊專用字符:SOH(文頭)、EOT(文尾)、ACK(確認)等;第33~126號(共94個)是字符,其中第48~57號爲0~9十個阿拉伯數字;65~90號爲26個大寫英文字母,97~122號爲26個小寫英文字母,其餘爲一些標點符號、運算符號等
我沒去下原始的ASCII表來看,但上面正點原子給的代碼裏的表應該是把前32個字符去掉了的..
所以正點原子給的代碼中就有了num = num - ’ ‘這一行必須的代碼,要不然就會出現亂碼
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode)
{
#ifdef USE_HORIZONTAL
#define MAX_CHAR_POSX 312
#define MAX_CHAR_POSY 232
#else
#define MAX_CHAR_POSX 232
#define MAX_CHAR_POSY 312
#endif
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;
}
測試:LCD_ShowString(30,50,"Mini STM32 ^_^");
好了~ LCD篇差不多也要學完了, 就剩下FSMC的一些問題了.