找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6162|回复: 0
打印 上一主题 下一主题
收起左侧

如何设计自定义的标准字符显示

[复制链接]
跳转到指定楼层
楼主
ID:75263 发表于 2015-6-9 03:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  各类液晶显示模块,都需要显示字符、中文、英文等信息。而且显示的方法也很多种多样,笔者通过学习探究,设计总结符合国标文字的显示方式,简便易移植。


图1 OLED液晶显示器
   其实字库显示的根本就是存储的组织性读入与读出,如果按照一定的标准组织自定义字库,则读就会事半功倍。因为存储的关系,字库一般存储在Flash代码区,就得声明存储形式,比如C51的code或者MDK的const。下面是举例的ASCII字库存储方式和底层驱动程序。
   ASCII目前标准的字体为256个,因此可以整个字库取模以方便调用,但值得注意的是,除去一些不常用的特殊符号后,我们整体需要的连续字符为100来个,为了节省空间,笔者从ASCII字符的第0x20个字符开始取模,取模软件可用PCtoLCD2002来取模,如下:



图2  PCtoLCD2002字母取模

#ifndef __ASCII_H__
#define __ASCII_H__

uchar code ASCII8x16[]=
{
// (0) !(1) "(2) #(3) $(4) %(5) &(6) '(7) ((8) )(9) *(10) +(11),(12) -(13) .(14) /(15)

// 0(16) 1(17) 2(18)3(19) 4(20) 5(21) 6(22) 7(23) 8(24) 9(25) :(26) ;(27) <(28)=(29) >(30) ?(31)
//@(32) A(33) B(34)C(35) D(36) E(37) F(38) G(39) H(40) I(41) J(42) K(43) L(44) M(45)N(46) O(47)
//P(48) Q(49) R(50) S(51) T(52) U(53) V(54) W(55)X(56) Y(57) Z(58) [(59) \(60) ](61) ^(62) _(63)
// `(64) a(65) b(66) c(67) d(68) e(69) f(70) g(71)h(72) i(73) j(74) k(75) l(76) m(77) n(78) o(79)
//p(80) q(81) r(82) s(83) t(84) u(85) v(86) w(87)x(88) y(89) z(90) {(91) |(92) }(93) ~(94)


x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,
0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,
0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,
0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,
0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,
0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,
0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,
0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,
0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,
0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,
0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,
0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,
0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,
0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,
0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,
0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,
0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,
0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,
0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,
0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,
0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,
0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,
0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,
0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,
0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,
0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,
0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,
0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,
0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,
0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,
0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,
0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,
0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,
0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,
0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,
0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,
0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,
0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,
0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,
0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,
0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,
0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,
0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,
0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,
0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,
0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,
0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,
0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,
0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,
0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,
0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,
0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,
0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,
0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,
0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,
0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

};
   对应的底层驱动函数只有一个,为:
   //显示字符
void LCD_PutChar(uint x, uint y, charc)
{
uintm=(c-0x20)*16;//提取c字符的第c个字节,c减去0x20是由于Ascii码库中的0~1f被去掉
……//将ASCII的第m个偏移字母显示出来

//如:display_graphic_8x16(x,y,&ASCII8x16[m]);
}
   对于中文显示来说就比较棘手,中国汉字博大精深,不可能意图将全部的字库添加到单片机内。因此,笔者模拟标准字库,用结构体虚构出一个自定义的字库出来,具体的组织方式如下:
   组织字库的方式被设计成汉字内码索引和点阵数据,如果设计一个函数,输入汉字,则函数能通过算法索引到对应的字体,则中文字体显示成功。用户可自行定义用到的字体,对于深度嵌入式的设计来说,这种设计方式非常省事。取模软件可用晓奇工作室取模软件,如图:



图3  晓奇工作室取模软件

#ifndef __GB_FONT_H__
#define __GB_FONT_H__

structtypFNT_GB16                      // 汉字字模数据结构
{
      ucharIndex[2];                      // 汉字内码索引
      ucharMsk[32];                      // 点阵码数据
};

/////////////////////////////////////////////////////////////////////////
//汉字字模表                                                         //
// 汉字库: 宋粗体16.dot纵向取模上高位,数据排列:从上到下从左到右      //
/////////////////////////////////////////////////////////////////////////
code struct typFNT_GB16 GB_16[]=         // 数据表
{
"欢", 0x04,0x34,0xC4,0x04,0xC4,0x3C,0x20,0x10,
     0x0F,0xE8,0x08,0x08,0x28,0x18,0x00,0x00,
     0x10,0x08,0x06,0x01,0x82,0x8C,0x40,0x30,
     0x0C,0x03,0x0C,0x10,0x60,0xC0,0x40,0x00,

"迎",0x40,0x42,0x44,0xC8,0x00,0xFC,0x04,0x02,
     0x82,0xFC,0x04,0x04,0x04,0xFE,0x04,0x00,
     0x00,0x40,0x20,0x1F,0x20,0x47,0x42,0x41,
     0x40,0x7F,0x40,0x42,0x44,0x63,0x20,0x00,

"使",0x40,0x20,0xF8,0x07,0x04,0xF4,0x14,0x14,
     0x14,0xFF,0x14,0x14,0x14,0xF6,0x04,0x00,
     0x00,0x00,0xFF,0x00,0x80,0x43,0x45,0x29,
     0x19,0x17,0x21,0x21,0x41,0xC3,0x40,0x00,

"用",0x00,0x00,0xFE,0x22,0x22,0x22,0x22,0xFE,
     0x22,0x22,0x22,0x22,0xFF,0x02,0x00,0x00,
     0x80,0x60,0x1F,0x02,0x02,0x02,0x02,0x7F,
     0x02,0x02,0x42,0x82,0x7F,0x00,0x00,0x00,

};
#endif
    注意:由于国家汉字基本大于2000,所以国家标准(GBK)制定的索引为一个字节(16位),可索引字体数达65536个,因此索引参数为ucharc[2]),对应的底层驱动函数:
void LCD_PutGBK(uint x,uint  y, uchar c[2])//显示汉字
{
uint k;
for (k=0;k
{
  if((GB_16[k].Index[0]==c[0])&&(GB_16[k].Index[1]==c[1]))
    {
        //显示对于索引的字库数据

        //如:display_graphic_16x16(x,y,&GB_16[k].Msk[0]);
    }
}
}   

   到此,我们可以通过这两个函数显示单个字符和中文了,但是一般应用的显示为字符串,因此我们可以通过字符串函数来显示,核心是通过判断参数char*s是否为8位还是16位来判断调入的参数是否为字符还是中文,函数如下:
//显示字符串
void LCD_PutString(uint x, uint y, char*s)
{
uint l=0;//显示屏位置增量
while(*s)
{
  if( (unsigned char)*s <0x80)//判断s指向的字符串中的某字符的编码值是否小于128,如果小于,即为ASCII字符
  {
   LCD_PutChar(x,y+l,*s);//显示该字符
      s++;//指针+1
   l+=8;      
  }
  else
  {
   LCD_PutGBK(x,y+l,(unsignedchar*)s);//显示该汉字
   s+=2; //因为汉字为编码为2字节,指针加2
   l+=16;//显示16x16所以位置加16  
  }
}
}

   至此,我们可以通过调用字符串显示函数来实现中英文字符串的显示,
底层完善后,调用非常直观和简便。如:
LCD_PutString(2, 0,"欢迎使用空调系统");//显示字符串
   另外,笔者认为光一个字符串显示函数还不能满足大部分日常所需,还需要专门设计一个数字显示的函数,方便显示各类变动的参数,比如电压表(ADC)跳动的数据等。实现如下
//m^n函数,用于LCD_PutNum()函数的计算
long mypow(uchar m,uchar n)
{
long result=1;
while(n--)result*=m;   
return result;
}

//函数:LCD_PutNum()
//描述:在显示屏中显示一个数字值,默认为覆盖模式
//参数:num:数值(0~4294967295);
//  uint8_tlen:需要显示数值的长度,如果长度与小于实际数值的长度,则会自动裁剪
//返回:void
void LCD_PutNum(uint x, uint y,long num,uchar len)
{         
uchar t,temp;
ucharenshow=0;        
for(t=0;t
{
  temp=(num/mypow(10,len-t-1));
  if(enshow==0&&t<(len-1))
  {
   if(temp==0)
   {
    LCD_PutChar(x,y+(8)*t,'0');
    continue;
   }elseenshow=1;
   
  }
  LCD_PutChar(x,y+(8)*t,temp+'0');
}
}

   可以做一个简单的测试:
int main()
{
   int a=0;
   LCD_PutString(2, 0, "欢迎使用空调系统");//显示字符串
   while(1)
   {
        LCD_PutNum(2, 4,a,6);//显示a的值
   }
}
  此时,你会发现显示器上有一个数字一直在动0-1-2……,恭喜你成功了

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表