解放碑美美百货在哪:从外部FLASH读取字库

来源:百度文库 编辑:偶看新闻 时间:2024/05/02 13:39:04
 在ARM7系统中,都不会有足够大的程序存储器来存放大容量的汉字库,因此当系统中要用到汉字库时,需要将其存储在外部的FLASH Memory,而ucgui的字符显示函数是直接从程序存储器取数据的,因此需要在原始代码里增加一个接口,来指向外部的FLASH Memory。

简介: 

   ucgui中,字符显示的底层函数是 GUICharP.c 中的 void GUIPROP_DispChar(U16P c) 函数,我们将这个函数修改如下:

/*********************************************************************
*
* GUIPROP_DispChar
*
* Purpose:
* This is the routine that displays a character. It is used by all
* other routines which display characters as a subroutine.
*/


void GUIPROP_DispChar(U16P c) {
int BytesPerLine;
U8 BytesPerFont; //一个字的字节数
U32 base,oft; //字库的起始地址和偏移量

GUI_DRAWMODE DrawMode = GUI_Context.TextMode;
const GUI_FONT_PROP GUI_UNI_PTR * pProp = GUIPROP_FindChar(GUI_Context.pAFont->p.pProp, c);
if (pProp) {
GUI_DRAWMODE OldDrawMode;
const GUI_CHARINFO GUI_UNI_PTR * pCharInfo;
//支持3种字体==
if((GUI_Context.pAFont == &GUI_FontHZ16)||(GUI_Context.pAFont == &GUI_FontHZ24)||(GUI_Context.pAFont == &GUI_FontHZ32))
{
pCharInfo = pProp->paCharInfo;

base = (U32)pProp->paCharInfo->pData;
BytesPerFont = GUI_Context.pAFont->YSize * pProp->paCharInfo->BytesPerLine; //每个字模的数据字节数
if (BytesPerFont > BYTES_PER_FONT)
{
BytesPerFont = BYTES_PER_FONT;
}
if (c < 0x80) //英文字符地址偏移算法
{
oft = base + (c - 0x20) * BytesPerFont; //计算出字码在flash中的偏移地址
}
else //中文字符地址偏移算法
{
oft = base + (((c>>8) - 0xa1) * 94 + ((c&0xff) - 0xa1)) * BytesPerFont;

}
LCD_ReadFlashBit(oft, GUI_FontDataBuf, BytesPerFont);//取出字模数据

BytesPerLine = pCharInfo->BytesPerLine;
OldDrawMode = LCD_SetDrawMode(DrawMode);

LCD_DrawBitmap( GUI_Context.DispPosX,
GUI_Context.DispPosY,
pCharInfo->XSize,
GUI_Context.pAFont->YSize,
GUI_Context.pAFont->XMag,
GUI_Context.pAFont->YMag,
1, /* Bits per Pixel */
BytesPerLine,
GUI_FontDataBuf,
&LCD_BKCOLORINDEX
);
}
//--
else
{
pCharInfo = pProp->paCharInfo+(c-pProp->First);
BytesPerLine = pCharInfo->BytesPerLine;
OldDrawMode = LCD_SetDrawMode(DrawMode);
LCD_DrawBitmap( GUI_Context.DispPosX,
GUI_Context.DispPosY,
pCharInfo->XSize,
GUI_Context.pAFont->YSize,
GUI_Context.pAFont->XMag,
GUI_Context.pAFont->YMag,
1, /* Bits per Pixel */
BytesPerLine,
pCharInfo->pData,
&LCD_BKCOLORINDEX
);
}


/* Fill empty pixel lines */
if (GUI_Context.pAFont->YDist > GUI_Context.pAFont->YSize) {
int YMag = GUI_Context.pAFont->YMag;
int YDist = GUI_Context.pAFont->YDist * YMag;
int YSize = GUI_Context.pAFont->YSize * YMag;
if (DrawMode != LCD_DRAWMODE_TRANS) {
LCD_COLOR OldColor = GUI_GetColor();
GUI_SetColor(GUI_GetBkColor());
LCD_FillRect(GUI_Context.DispPosX,
GUI_Context.DispPosY + YSize,
GUI_Context.DispPosX + pCharInfo->XSize,
GUI_Context.DispPosY + YDist);
GUI_SetColor(OldColor);
}
}
LCD_SetDrawMode(OldDrawMode); /* Restore draw mode */
GUI_Context.DispPosX += pCharInfo->XDist * GUI_Context.pAFont->XMag;
}
}

然后再加入FLASH操作的底层驱动(这里用的是SPI FLASH)

/*********************************************************************
*
* Static code
*
**********************************************************************
*/
//字模数据的暂存数组,以单个字模的最大字节数为设定值
#define BYTES_PER_FONT 4*32 //最大支持32*32的汉字
static U8 GUI_FontDataBuf[BYTES_PER_FONT];


/*********************************************************************
*
* 读FLASH中的字库
*/
#include "spi_flash.h"
#include "ssp.h"

void LCD_ReadFlashBit(U32 addr,U8* buf,U8 Bytes)
{
U8 i;
SPI_FLASH_StartReadSequence(addr); //设置起始地址
for(i=0;i {
buf[i] = SPI_FLASH_SendByte(0xa5);
}
SPI_FLASH_CS_HIGH();
}

我们知道,ucgui访问字库的时候,是根据字库文件的索引表来查找汉字数据地址的,因此汉字库文件中的索引也要修改,以汉字库32为例

/*
******************************************************


File Name : hzk32.C
Compiler :
Author : Liu_xf
Version : V1.0
Date : 2011-3-28 11:25:54
Description :
ucgui的中文字库,与uc工具生成的字库文件不同的是,可以将
大容量的汉字数组存入到外部的FALSH里
当然这个也是由uc工具生成的文件修改而来的。
*******************************************************
Structure :

History:

*******************************************************
*/

#include "..\core\GUI.H"
#ifndef GUI_FLASH
#define GUI_FLASH
#endif
extern GUI_FLASH const GUI_FONT GUI_FontHZ32;

/*
GUI_FLASH const GUI_CHARINFO GUI_FontHZ32_CharInfo[] = {
{ 10, 10, 1, (void GUI_FLASH *)0}, // 字符在FLASH中的偏移量
{ 16, 16, 2, (void GUI_FLASH *)3840}, //汉字在FLASH中的偏移量
};
*/

GUI_FLASH const GUI_CHARINFO GUI_FontHZ32_CharInfo[] = {
// Y X X_BYTE
{ 16, 8, 1, (void GUI_FLASH *)0}, // FLASH里没有存字符,这里为0
{ 32, 32, 4, (void GUI_FLASH *)GUI_FontHZ32_Flash_BaseAddr}, //GUI_FontHZ32_Flash_BaseAddr在GUI.h中定义
};

//汉字和字符索引表//////////////////////////////////

/*鳌--齄*/

GUI_FLASH const GUI_FONT_PROP GUI_FontHZ32_Propf7a1= {
0xf7a1,
0xf7fe,
&GUI_FontHZ32_CharInfo[1],
(void *)0
};
//.....这里省略若干,详见符件里的代码

/* --〓*/
GUI_FLASH const GUI_FONT_PROP GUI_FontHZ32_Propa1a1= {
0xa1a1,
0xa1fe,
&GUI_FontHZ32_CharInfo[1],
(void *)&GUI_FontHZ32_Propa2a1
};
//ASC字符
/* --*/
GUI_FLASH const GUI_FONT_PROP GUI_FontHZ32_Prop0020= {
0x0020,
0x007f,
&GUI_FontHZ32_CharInfo[0],
(void *)&GUI_FontHZ32_Propa1a1
};
GUI_FLASH const GUI_FONT GUI_FontHZ32 = {
GUI_FONTTYPE_PROP_SJIS,
32,
32,
1,
1,
(void GUI_FLASH *)&GUI_FontHZ32_Prop0020
};

在GUI.H中添加汉字库在flash中的首地址,及字库声明

/*汉字*/
//汉字库在FLASH中的首地址
#define GUI_FontHZ16_Flash_BaseAddr 0x0
#define GUI_FontHZ24_Flash_BaseAddr 0x00045080
#define GUI_FontHZ32_Flash_BaseAddr 0x000E05A0

extern GUI_CONST_STORAGE GUI_FONT GUI_FontHZ16;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontHZ24;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontHZ32;

    然后将字库下载到SPI FLASH中,注意三个字库的起始地址与GUI.h中定义的应该是一样的。还有字库生成时,也应该是标准的汉字库,满足 oft = base + (((c>>8) - 0xa1) * 94 + ((c&0xff) - 0xa1)) * BytesPerFont; 的计算方式。

 

结语: 

   有了将汉字库定义到外部FLASH的方法,则可以定义任意汉字库,不受程序FLASH大小的限制了。