1. 程式人生 > >STM32學習之路-LCD(4)<顯示字符>

STM32學習之路-LCD(4)<顯示字符>

計算 ack 字節 ring oid ng- 透明 標點符號 函數

昨晚瘋狂的打了一夜的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的一些問題了.



STM32學習之路-LCD(4)&lt;顯示字符&gt;