这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 分享一次用无字库12864的经历

共2条 1/1 1 跳转至

分享一次用无字库12864的经历

高工
2015-06-17 16:19:38     打赏

在做一个项目时选用的是带字库的12864液晶,液晶控制型号是ST7920  这种估计是最常用的了,带有汉字字库,可串并行通信。

在使用这款型号液晶时,由于显示数据地址固定

所以函数都整成下面这个形式:

void  LcdDispChar(u8 addr,u8 chr);

void  LcdDispString(u8 addr,u8 *pStr);

显示字符串和单个字符时入口参数就是 显示地址和数据。

下面主角来啦....

在做同一系列的一个项目时,由于结构问题,需要选用尺寸小一点的液晶咯。1602液晶实在是太小了就被排除咯,最终选定的是一个无字库的12864液晶,液晶控制型号是KS0108

左半屏和右半屏操作时写的地址其实是一样的,那么只能通过片选CS1CS2来选择哪半个屏了,相当于两块64x64的液晶了


同一系列的项目,程序整体结构改动不大,现在就需要能够像操作有字库液晶那样来操作这块无字库的12864液晶。那么就开工了,在Proteus上仿真实验,保证显示函数的形式不变。

首先定义了一个这样的结构体来做地址转换

typedef  enum  
{
	LCD_None,
	LCD_A,
	LCD_B,
	LCD_All,
}LCD_Select;

typedef  struct
{
    u8  LCD_Address;
	u8  LCD_AddrRow;
	u8  LCD_AddrPage;
	LCD_Select   LCD_AddrSelect;
}LCD_AddrTypedef;





code  LCD_AddrTypedef  	gLcdAddrTable[32] = 
{
  {0x80,0,0,LCD_A},
  {0x81,16,0,LCD_A},
  {0x82,32,0,LCD_A},
  {0x83,48,0,LCD_A},
  {0x84,0,0,LCD_B},
  {0x85,16,0,LCD_B},
  {0x86,32,0,LCD_B},
  {0x87,48,0,LCD_B},

  {0x88,0,4,LCD_A},
  {0x89,16,4,LCD_A},
  {0x8a,32,4,LCD_A},
  {0x8b,48,4,LCD_A},
  {0x8c,0,4,LCD_B},
  {0x8d,16,4,LCD_B},
  {0x8e,32,4,LCD_B},
  {0x8f,48,4,LCD_B},

  {0x90,0,2,LCD_A},
  {0x91,16,2,LCD_A},
  {0x92,32,2,LCD_A},
  {0x93,48,2,LCD_A},
  {0x94,0,2,LCD_B},
  {0x95,16,2,LCD_B},
  {0x96,32,2,LCD_B},
  {0x97,48,2,LCD_B},

  {0x98,0,6,LCD_A},
  {0x99,16,6,LCD_A},
  {0x9a,32,6,LCD_A},
  {0x9b,48,6,LCD_A},
  {0x9c,0,6,LCD_B},
  {0x9d,16,6,LCD_B},
  {0x9e,32,6,LCD_B},
  {0x9f,48,6,LCD_B},


};

 

将带有字库的12864液晶的显示地址与无字库液晶上的像素点联系起来。

开始完成显示字符和字符串函数:

void  LcdDispChar(u8 addr,u8 chr)
{
     u8  i,j;
	 u8  page = gLcdAddrTable[(addr - 0x80)].LCD_AddrPage;
	 u8  row = gLcdAddrTable[(addr - 0x80)].LCD_AddrRow;
	 LcdSelectScreen(gLcdAddrTable[(addr - 0x80)].LCD_AddrSelect);
	 //根据结构体数组里面的信息得出行列地址以及选择左或右半屏
	 for(i = 0;i < 2;i++)
	 {
	 	   LcdSetPageRow(page + i,row); 
		   for(j = 0;j < 8;j++)
		   {
		        LcdWriteFuncion(ASCII816[chr - 0x20][(i * 8 + j)],LCD_Data);
		   }   
	 }  
}

 

在显示字符串中会有汉字的出现,所以需要判断一个字符串中,哪些是汉字哪些是字符。下面是显示字符串的函数,字符串中可以汉字与字符并存。

void   LcdDispString(u8 addr,u8 *pStr)
{
     u8 cntChr = 0;
	 u8 wCnt,n1,n2;
     while(*pStr != '\0')
	 {
          if(*pStr & 0x80)
		  {
		  	   n1 = *pStr;
			   pStr++;
			   if(*pStr & 0x80)
			   {
			        n2 = *pStr;
			   		pStr++;
					wCnt = 	GDKtoNumber(n1,n2);
					if(wCnt != ERR_NUMBER)
					{
					     LcdGotoXY((addr + cntChr / 2)); 
						 LcdWriteWord(gHZTable[wCnt * 2]); 
						 cntChr += 2;    
					}
			   }
		  
		  }
		  else
		  {
		       if((cntChr % 2) == 0)
			   {
			       LcdDispChar((addr + cntChr / 2),*pStr); 
			   }
			   else
			   {
			   	   LcdGotoXY2(addr + (cntChr / 2));
				   LcdWriteChar(*pStr);
			   
			   } 
		  	   pStr++;
			   cntChr++;
		  }          	      
	 
	 }      

}

 

还有一点就是,汉字的字模怎么与汉字对应呢,采用了如下方法:

#define  MAX_WORD_NUMBER   (84)   //汉字个数
#define  ERR_NUMBER        (MAX_WORD_NUMBER + 1)

code  u8  gHZTable[MAX_WORD_NUMBER * 2][16] = 
{
 {0x20,0x20,0x20,0x3C,0x28,0x68,0xD9,0x56,0x74,0x94,0x9C,0x94,0x10,0x10,0x00,0x00},
{0x00,0x20,0x24,0x15,0x15,0x0D,0x04,0x7F,0x06,0x0A,0x12,0x32,0x20,0x20,0x00,0x00},/*"案",1*/
   //添加字模 
}





code u8  GBKCodeTable[MAX_WORD_NUMBER][2] = 
{
     {"案"},
     //添加所填加的汉字,与字模的顺序一致
};

 

下面是根据汉字查找字模:

u8   GDKtoNumber(u8 n1,u8 n2)
{
     u8 i = 0;
	 for(i = 0;i < MAX_WORD_NUMBER;i++)
	 {
	       if(n1 == GBKCodeTable[i][0])
		   {
		        if(n2 == GBKCodeTable[i][1])
				{
				     return i;
				}
		   }
	 }          
	 return ERR_NUMBER;
}

 


下面是主函数内容,与仿真效果:

void main()
{

	LcdInitConfig();

    LcdDispString(0x90,"www.eepw.com.cn ");
    LcdDispString(0x88,"信息------------");
    LcdDispString(0x98,"****************");
    while(1)
	{
	}

}

 

 

用无字库12864替换带字库液晶.rar



关键词: 分享     无字库     12864     经历    

院士
2015-06-18 09:17:19     打赏
2楼

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]