各類液晶顯示模塊,都需要顯示字符、中文、英文等信息。而且顯示的方法也很多種多樣,筆者通過學(xué)習(xí)探究,設(shè)計總結(jié)符合國標(biāo)文字的顯示方式,簡便易移植。
圖1 OLED液晶顯示器
其實字庫顯示的根本就是存儲的組織性讀入與讀出,如果按照一定的標(biāo)準(zhǔn)組織自定義字庫,則讀就會事半功倍。因為存儲的關(guān)系,字庫一般存儲在Flash代碼區(qū),就得聲明存儲形式,比如C51的code或者M(jìn)DK的const。下面是舉例的ASCII字庫存儲方式和底層驅(qū)動程序。
ASCII目前標(biāo)準(zhǔn)的字體為256個,因此可以整個字庫取模以方便調(diào)用,但值得注意的是,除去一些不常用的特殊符號后,我們整體需要的連續(xù)字符為100來個,為了節(jié)省空間,筆者從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,
};
對應(yīng)的底層驅(qū)動函數(shù)只有一個,為:
//顯示字符
void LCD_PutChar(uint x, uint y, charc)
{
uintm=(c-0x20)*16;//提取c字符的第c個字節(jié),c減去0x20是由于Ascii碼庫中的0~1f被去掉
……//將ASCII的第m個偏移字母顯示出來
//如:display_graphic_8x16(x,y,&ASCII8x16[m]);
}
對于中文顯示來說就比較棘手,中國漢字博大精深,不可能意圖將全部的字庫添加到單片機(jī)內(nèi)。因此,筆者模擬標(biāo)準(zhǔn)字庫,用結(jié)構(gòu)體虛構(gòu)出一個自定義的字庫出來,具體的組織方式如下:
組織字庫的方式被設(shè)計成漢字內(nèi)碼索引和點陣數(shù)據(jù),如果設(shè)計一個函數(shù),輸入漢字,則函數(shù)能通過算法索引到對應(yīng)的字體,則中文字體顯示成功。用戶可自行定義用到的字體,對于深度嵌入式的設(shè)計來說,這種設(shè)計方式非常省事。取模軟件可用曉奇工作室取模軟件,如圖:
圖3 曉奇工作室取模軟件
#ifndef __GB_FONT_H__
#define __GB_FONT_H__
structtypFNT_GB16 // 漢字字模數(shù)據(jù)結(jié)構(gòu)
{
ucharIndex[2]; // 漢字內(nèi)碼索引
ucharMsk[32]; // 點陣碼數(shù)據(jù)
};
/////////////////////////////////////////////////////////////////////////
//漢字字模表 //
// 漢字庫: 宋粗體16.dot縱向取模上高位,數(shù)據(jù)排列:從上到下從左到右 //
/////////////////////////////////////////////////////////////////////////
code struct typFNT_GB16 GB_16[]= // 數(shù)據(jù)表
{
"歡", 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,所以國家標(biāo)準(zhǔn)(GBK)制定的索引為一個字節(jié)(16位),可索引字體數(shù)達(dá)65536個,因此索引參數(shù)為ucharc[2]),對應(yīng)的底層驅(qū)動函數(shù):
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]))
{
//顯示對于索引的字庫數(shù)據(jù)
//如:display_graphic_16x16(x,y,&GB_16[k].Msk[0]);
}
}
}
到此,我們可以通過這兩個函數(shù)顯示單個字符和中文了,但是一般應(yīng)用的顯示為字符串,因此我們可以通過字符串函數(shù)來顯示,核心是通過判斷參數(shù)char*s是否為8位還是16位來判斷調(diào)入的參數(shù)是否為字符還是中文,函數(shù)如下:
//顯示字符串
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字節(jié),指針加2
l+=16;//顯示16x16所以位置加16
}
}
}
至此,我們可以通過調(diào)用字符串顯示函數(shù)來實現(xiàn)中英文字符串的顯示,
底層完善后,調(diào)用非常直觀和簡便。如:
LCD_PutString(2, 0,"歡迎使用空調(diào)系統(tǒng)");//顯示字符串
另外,筆者認(rèn)為光一個字符串顯示函數(shù)還不能滿足大部分日常所需,還需要專門設(shè)計一個數(shù)字顯示的函數(shù),方便顯示各類變動的參數(shù),比如電壓表(ADC)跳動的數(shù)據(jù)等。實現(xiàn)如下
//m^n函數(shù),用于LCD_PutNum()函數(shù)的計算
long mypow(uchar m,uchar n)
{
long result=1;
while(n--)result*=m;
return result;
}
//函數(shù):LCD_PutNum()
//描述:在顯示屏中顯示一個數(shù)字值,默認(rèn)為覆蓋模式
//參數(shù):num:數(shù)值(0~4294967295);
// uint8_tlen:需要顯示數(shù)值的長度,如果長度與小于實際數(shù)值的長度,則會自動裁剪
//返回: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, "歡迎使用空調(diào)系統(tǒng)");//顯示字符串
while(1)
{
LCD_PutNum(2, 4,a,6);//顯示a的值
}
}
此時,你會發(fā)現(xiàn)顯示器上有一個數(shù)字一直在動0-1-2……,恭喜你成功了
|