6027|6

4996

帖子

19

TA的资源

裸片初长成(初级)

楼主
 

一个显示函数实现不同字体在LCD上的显示 [复制链接]

 
本帖最后由 zhaojun_xf 于 2015-8-28 14:16 编辑

有一点LCD显示基础的读者都知道,我们在提前任何字体的字库时,实际上字符都是按照一点的点阵方块构成,常见的英文字符有8x8,8x16等,而比较常见的中文字符有12x12,16x16等,不管是多大点阵的字符,其存储模式基本都是以一定的点阵模式进行存储。在我们取字摸的时候,根据显示的方向,可以有自上而下,从左往右等等。不管是那种取摸方式,只要写点的顺序和取摸的方向一致就可以正确显示了。















        例如:下面一个是“1”,一个是“中”,采用比较直观的取摸方式获得:

  ________,

  ___X____,

  _XXX____,

  ___X____,

  ___X____,

  ___X____,

  ___X____,

  ___X____,

  ___X____,

  _XXXXX__,

  ________




  _____X__,________,

  _____X__,________,

  _____X__,________,

  _XXXXXXX,XX______,

  _X___X__,_X______,

  _X___X__,_X______,

  _X___X__,_X______,

  _XXXXXXX,XX______,

  _X___X__,_X______,

  _____X__,________,

  _____X__,________,

  _____X__,________






     总结:


     从上面的描述不难发现一点,不管什么字体,什么字符,只要按照顺序把通过字摸软件获取的字摸数据,按照顺序一行一行的显示出来就可以实现任何字符的显示了。而不同字体不同的只是其行的像素点和款的像素点以及其字摸数据的不同而已。

    实现:

    既然不同字符或字体的显示都有共性,那么我们进行高度提炼,把它们的不同的地方用一个结构图进行定义,在生成不同的字摸时进行定义就可以了。

typedef struct
{
    U8  Width;                                                                  // 字体宽度
    U8  Height;                                                                 // 高度
    U8  FstChr;                                                                 // 起始字符
    UC8 *Dat;                                                                   // 字库起始地址

} TFT_FNT;


例如:定义16x32的字库【可以是上面那种直观的数据,也可以是下面这中十六进制数据】
const u8 ST16x32[] = {
    /* @0  (16x32,H)@ [suki software]*/
    0x00,0x00,  0x00,0x00,  0x00,0x00,  0x00,0x00,  
    0x00,0x00,  0x00,0x00,  0x00,0x00,  0x00,0x00,  
    0x00,0x00,  0x00,0x00,  0x00,0x00,  0x00,0x00,  
    0x00,0x00,  0x00,0x00,  0x00,0x00,  0x00,0x00,  
    0x00,0x00,  0x00,0x00,  0x00,0x00,  0x00,0x00,  
    0x00,0x00,  0x00,0x00,  0x00,0x00,  0x00,0x00,  
    0x00,0x00,  0x00,0x00,  0x00,0x00,  0x00,0x00,  
    0x00,0x00,  0x00,0x00,  0x00,0x00,  0x00,0x00,


。。。
};

TFT_FNT FNT16x32 =
{
    16,                                            // 宽为16
    32,                                            // 高为32
    0x20,                                        // 从0x20开始,表示0x20的特色字符我们没有取字摸
    ST16x32,                                // 点阵数据
};


例如:定义16x32的字库48x64

const u8 AB48x64[] = {
    /* @0 0(48x64,H)@ [suki software]*/
    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x1F,0xF8,0x00,0x00,  0x00,0x00,0xFF,0xFE,0x00,0x00,  
    0x00,0x03,0xFF,0xFF,0x80,0x00,  0x00,0x07,0xFF,0xFF,0xE0,0x00,  0x00,0x0F,0xFF,0xFF,0xF0,0x00,  0x00,0x1F,0xFF,0xFF,0xF8,0x00,  
    0x00,0x3F,0xFF,0xFF,0xF8,0x00,  0x00,0x7F,0xF8,0x3F,0xFC,0x00,  0x00,0x7F,0xE0,0x0F,0xFE,0x00,  0x00,0xFF,0xC0,0x03,0xFE,0x00,  
    0x00,0xFF,0x80,0x01,0xFF,0x00,  0x01,0xFF,0x00,0x01,0xFF,0x00,  0x01,0xFE,0x00,0x00,0xFF,0x00,  0x01,0xFE,0x00,0x00,0x7F,0x80,  
    0x03,0xFE,0x00,0x00,0x7F,0x80,  0x03,0xFC,0x00,0x00,0x7F,0x80,  0x03,0xFC,0x00,0x00,0x3F,0xC0,  0x03,0xFC,0x00,0x00,0x3F,0xC0,  
    0x07,0xF8,0x00,0x00,0x3F,0xC0,  0x07,0xF8,0x00,0x00,0x3F,0xC0,  0x07,0xF8,0x00,0x00,0x3F,0xC0,  0x07,0xF8,0x00,0x00,0x3F,0xC0,  
    0x07,0xF8,0x00,0x00,0x3F,0xE0,  0x07,0xF8,0x00,0x00,0x3F,0xE0,  0x07,0xF8,0x00,0x00,0x1F,0xE0,  0x07,0xF8,0x00,0x00,0x1F,0xE0,  
    0x07,0xF8,0x00,0x00,0x1F,0xE0,  0x07,0xF8,0x00,0x00,0x1F,0xE0,  0x07,0xF8,0x00,0x00,0x1F,0xE0,  0x07,0xF8,0x00,0x00,0x1F,0xE0,  
    0x07,0xF8,0x00,0x00,0x1F,0xE0,  0x07,0xF8,0x00,0x00,0x1F,0xE0,  0x07,0xF8,0x00,0x00,0x1F,0xE0,  0x07,0xF8,0x00,0x00,0x1F,0xE0,  
    0x07,0xF8,0x00,0x00,0x1F,0xE0,  0x07,0xF8,0x00,0x00,0x3F,0xE0,  0x07,0xF8,0x00,0x00,0x3F,0xC0,  0x07,0xF8,0x00,0x00,0x3F,0xC0,  
    0x07,0xF8,0x00,0x00,0x3F,0xC0,  0x07,0xF8,0x00,0x00,0x3F,0xC0,  0x07,0xF8,0x00,0x00,0x3F,0xC0,  0x03,0xFC,0x00,0x00,0x3F,0xC0,  
    0x03,0xFC,0x00,0x00,0x7F,0xC0,  0x03,0xFC,0x00,0x00,0x7F,0x80,  0x03,0xFC,0x00,0x00,0x7F,0x80,  0x01,0xFE,0x00,0x00,0x7F,0x80,  
    0x01,0xFE,0x00,0x00,0xFF,0x80,  0x01,0xFF,0x00,0x01,0xFF,0x00,  0x00,0xFF,0x80,0x01,0xFF,0x00,  0x00,0xFF,0xC0,0x03,0xFE,0x00,  
    0x00,0x7F,0xE0,0x0F,0xFE,0x00,  0x00,0x7F,0xF8,0x3F,0xFC,0x00,  0x00,0x3F,0xFF,0xFF,0xF8,0x00,  0x00,0x1F,0xFF,0xFF,0xF8,0x00,  
    0x00,0x0F,0xFF,0xFF,0xF0,0x00,  0x00,0x07,0xFF,0xFF,0xE0,0x00,  0x00,0x03,0xFF,0xFF,0x80,0x00,  0x00,0x00,0xFF,0xFE,0x00,0x00,  
    0x00,0x00,0x1F,0xF8,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  
}


TFT_FNT FNT48x64 =
{
    48,                                             // 宽为48
    64,                                             // 高为64
    0x30,                                         // 从0x30开始,表示0x30的特色字符我们没有取字摸
    AB48x64,                                 // 点阵数据

};


那么下面我们对这两种不同的字库数据进行显示


/**************************************************************************************
* FunctionName   : TFTSetFont()
* Description    : 设置字体
* EntryParameter : None
* ReturnValue    : None
**************************************************************************************/
void TFTSetFont(TFT_FNT *pFnt)
{
    memcpy(&TFTFnt, pFnt, sizeof(TFT_FNT));
}


先告诉显示函数,我们现在要显示的字库是那种,以便于采用不同的参数进行显示:

/**************************************************************************************
* FunctionName   : TFTDisCharAt()
* Description    : 在指定座标显示字符
* EntryParameter : x - 行坐标;y - 列坐标;chClr - 字符的颜色;bkClr - 字符背景颜色
* ReturnValue    : None
**************************************************************************************/
void TFTDisCharAt(u16 x, u16 y, u8 chr, u16 chClr, u16 bkClr)
{
    u8 font;
    u16 tmpLen;

    tmpLen = (TFTFnt.Width/8) * TFTFnt.Height;                                  // 单个字符的字节数
    TFTSetWindow(x, y, x+TFTFnt.Width-1, y+TFTFnt.Height-1);      // 设置窗口大小

    for (u16 i=0; i
    {
        font = TFTFnt.Dat[((chr-TFTFnt.FstChr)*tmpLen) + i];               // 对以字节点阵数据
        for (u8 n=0; n<8; n++)
        {
            TFT_WR_DAT(((font << n) & 0x80) ? chClr : bkClr);             // 一点一点的显示
        }
    }
}


         显示原来其实非常简单,我们先定义一个显示字符的窗口,告诉LCD屏接下来需要显示的窗口。完成后,只要取窗口刚好能够显示的点阵数据发给LCD即可。这样显示是效率是非常高的,利用了LCD的地址自加功能,而不需要每次都告诉LCD的显示地址。当然,如果提前字库的方向与LCD的自加方向是不同的,这时就只能使用写点函数进行一个点一个点的写了。


接下来就简单了,显示哪一种字库,只需要在显示之前进行一些说明就可以了:

TFTSetFont(&FNT48x64);
TFTDisCharAt(0, 0, ’1‘, TFT_BLACK, TFT_WHITE);


        怎么样,是不是非常简单,我们不需要为不同的字体,不同的字符编写每一种显示函数了,就一个显示函数就可以显示所以点阵字符。


此帖出自stm32/stm8论坛

最新回复

挤挤。。。  详情 回复 发表于 2015-9-1 19:57
点赞 关注(6)
个人签名我的博客
 

回复
举报

1万

帖子

203

TA的资源

管理员

沙发
 
多谢楼主分享,好东西呀
此帖出自stm32/stm8论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身

点评

挤挤。。。  详情 回复 发表于 2015-9-1 19:57
 
个人签名玩板看这里:
https://bbs.eeworld.com.cn/elecplay.html
EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!
 

回复

82

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
楼主所提到的emWin,以及他的前身ucGUI就是采用的这种方法。
此帖出自stm32/stm8论坛

点评

是的,最近在用ucgui突然领会到这种方法,不过,我没有看看ucgui的源代码,不知道是否和我一样。  详情 回复 发表于 2015-8-28 16:57
 
 

回复

4996

帖子

19

TA的资源

裸片初长成(初级)

4
 
STM32F103 发表于 2015-8-28 16:42
楼主所提到的emWin,以及他的前身ucGUI就是采用的这种方法。

是的,最近在用ucgui突然领会到这种方法,不过,我没有看看ucgui的源代码,不知道是否和我一样。
此帖出自stm32/stm8论坛
 
个人签名我的博客
 
 

回复

954

帖子

0

TA的资源

纯净的硅(初级)

5
 
好方法,跟当初看ucgui所使用的方法很像
此帖出自stm32/stm8论坛
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(中级)

6
 
好像跟我接触到的显示是一样一样的
此帖出自stm32/stm8论坛
 
 
 

回复

1891

帖子

2

TA的资源

纯净的硅(中级)

7
 
okhxyyo 发表于 2015-8-28 13:24
多谢楼主分享,好东西呀

挤挤。。。
此帖出自stm32/stm8论坛
 
个人签名
分享铸就美好未来。。。




 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表