• STM32学习之路-LCD(4)<显示字符>


    昨晚疯狂的打了一夜的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的一些问题了.



  • 相关阅读:
    Java多线程实现1,继承Thread类
    Java学习笔记二:初始化(一)
    Java学习笔记一:对象与存储
    数据结构学习笔记4.5--二叉树效率
    数据结构学习笔记4.4--删除节点
    数据结构学习笔记4.3--遍历树
    数据结构学习笔记4.2--插入节点
    数据结构学习笔记4.1--查找节点
    数据结构学习笔记3.2—快速排序
    数据结构学习笔记3.1--划分
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/7106754.html
Copyright © 2020-2023  润新知