LCD无字库--单片机字库存储
本文轉自:http://www.rationmcu.com/elecjc/356.html
學完這篇文章,你將會使你的單片機顯示系統中加入中文顯示的功能。
1.導言
和單片機搭配的顯示器,有12864、TFT、OLED等。在有些系統中,我們需要顯示漢字,可以購買漢字芯片,或者購買帶漢字顯示的顯示器,當然,也可以自己做字庫。
這里我們介紹一種自己做字庫的方法,成本2元人民幣左右。
2.漢字顯示原理
看原理需要知道什么是像素:像素是液晶屏的最小單位,看你的手機屏幕或者電腦屏幕,他們實際上是由一個一個的正方形組成的,如果你的電腦或手機屏幕分辨率太高,不容易看到,需要借助放大鏡,分辨率低的話,仔細一看就看見了,都是由一個一個的正方形組成的,這里面的一個正方形,就是1個像素。例如,12864屏幕就是128像素*64像素的屏幕,即橫著有12864個正方形,豎著有64個正方形。
上圖是12864屏幕的一角,請你仔細看看,是不是一個一個的正方形組成?
比128*64大的分辨率是320*240,還有800*600,1024*768,1280*720等,總之,分辨率越大,人的肉眼就越但不見它是由一個一個小正方形組成的。所以現在的手機屏幕是越來越高,當你用慣一個分辨率極高的手機,再去用你原來分辨率極低的手機,你就會發現原來的那個手機真是很模糊!
講完了像素的概念,下面開始講漢字顯示的原理:
現在流行的漢字字庫有兩種,一種是GB2312、一種是GBK。這是兩種不同的編碼約定。
- GB2312有六千多個漢字,是一些常用的漢字
- GBK有2萬多個漢字,包含所有的GB2312漢字,包含整個中國的漢字
假如我們想在液晶顯示器上顯示一個16*16像素大小的漢字“瑞”,怎么辦呢?先看一下“瑞”字在液晶顯示器上被放大的效果:
上面的這個瑞即是16*16像素大小的字體,你可以數一下上面的像素點。你可以看一下,在上面“亮”的地方用“寫點函數”寫成和其它點不同的顏色,不就可以了嗎!按照這個思想,我們就需要采用一種有效的辦法了。從上面圖像的右上角開始掃描,每行有16個點,即可以用兩個字節來表示,“暗”的地方用0表示,亮的地方用1表示,那么第一行就可以寫成十六進制的00 20,以此類推,可以得出第二行,第三行的字節碼,如此一來,一個漢字就需要32個字節來表示。搞好了漢字的這些碼,在程序中給TFT開個16*16大小的區域,然后開始掃描這些字節,遇到0,寫背景色,遇到1,寫定義的顏色。漢字顯示就是如此了。
3.為什么顯示英文一般不用字庫芯片?
英文的單詞都是由26個字母構成了,加上大小寫的區別和一些字符,也不過才95個。假如要顯示8*16像素大小的字符,每一個字符需要16個字節的字庫空間,95個字符即是95*16=570個字節。即占用570個字節的RAM。對于LPC1114的8K字節RAM來說,搓搓有余了。
4.為什么顯示中文需要字庫芯片?
顯示中文的話,必須需要每一個字的字模,16*16像素大小的中文,每一個中文都要32個字節。GBK收錄了中文兩萬多個,如果要都能顯示,需要700多K字節的空間。
所以,我們選擇了把這些字庫放在外部存儲器當中,我們選擇了2M的FLASH存儲芯片W25Q16做為存儲媒介。放個700多K的字庫足夠了,如果你愿意,同時放兩種字體的字庫都沒問題。
5.如何把GBK字庫做成字模?(此部分做字模參考阿莫論壇一帖子,非瑞生原創,特此感謝分享者)
5.1需要準備的文件和軟件
- 取模軟件
- GBK字庫
- 二進制文件生成工具
點此下載:GBK字庫制作軟件和文件
5.2開始制作
在工具欄處點“打開”按鈕,打開gbk_ziku.txt文件,然后根據自己的需要,設置想要的取模方式,然后點工具欄上的“輸出”按鈕?并等待其完成,完成后會在取模軟件所在路徑生成了一個temp.txt文件,修改這個文件名,比如現在我是按照“宋體、點陣數為16、字重為4、取模為為16*16、對齊設置為左上、方向設置為橫向取模,高位在左”的方式來取的字模,也就是我平時TFT常用的一種字模,改文件名為st16x16.txt?。
為了生成的方便,我們在D盤根目錄下新建一個文件夾,名稱就叫ziku吧,然后,把ziku.exe?和?st16x16.txt復制一份到這個文件夾里。
打開自己計算機的命令窗口:“開始”->“運行”->“cmd”,如下圖所示:
然后用cd命令進入到我們剛剛建的ziku文件夾下,輸入命令如下圖所示:
輸入命令,生成字庫文件,如下圖所示:
回車,然后程序會在ziku文件夾下生成一個名稱固定為ziku.bin的字庫文件
為了區分,把這個字庫文件修改名稱為st16x16.bin?。
到此,字庫已經制作完成。
6.如何把做好的GBK字庫字模存儲到W25Q16中?
硬件:電腦串口—單片機—W25Q16
程序:單片機與電腦采用串口連接,單片機與W25Q16采用SPI方式連接。所以,我們只需要給單片機寫一個接收串口數據再把數據通過SPI口傳輸到W25Q16中的程序即可。
7.單片機如何讀取W25Q16中的字模并顯示在液晶屏上?
假設我們的GBK字模是從W25Q16地址中的0x100開始存儲的,那么,從0x100地址開始,單片機讀取32個字節,就是GBK字庫的第一個字“丂”的字模,再讀32個字節,就是GBK字庫第二個字“丄”的字模。(有人會問,你是怎么知道GBK字庫第幾個字是什么的?答:你把上文中5.1節提到的文件下載后,打開GBK字庫,就看見了。)根據上文中第2步講的原理,字模中,遇到0就給LCD的1個像素畫一個顏色,遇到1就給LCD的下一個像素畫不同的顏色,把32個字節都捋一遍,一個漢字就顯示在LCD上了。
如果我們想要顯示漢字“瑞”,我們該從W25Q16中的哪個字節開始提取它的字模呢?這時候,就需要知道字符存儲編碼的原理了。
字符編碼原理:英文字母帶各種符號等共有95個,都有自己的ascii碼,一個字母或者符號就是一個ascii碼。漢字以及漢字的符號是需要2個字節來存儲,在keil等主流編譯器中,一般都是以GBK編碼方式存儲。
GBK編碼:每個GBK碼由2個字節組成,第一個字節為0X81~0XFE,第二個字節分為兩部分,一是0X40~0X7E,二是0X80~0XFE。例如漢字“瑞”的GBK編碼為C8 F0,第一字節C8,位于0X81~0XFE之間,第二字節F0,位于0X40~0XFE之間。第一個字節代表的意義稱為區,那么GBK里面總共有126個區(0XFE-0X81+1=126);第二個字節代表的意義就是每個區內有多少個漢字,算了一下,一共有190個(0XFE-0X80+0X7E-0X40+2=190)。那么,GBK一共存儲了126X190=23940個漢字。
我們仔細看GBK編碼第二個字節兩部分,0X40~0X7E 0X80~0XFE,也就是說它是從0X40~到0XFF,中間的0x7F和最后的0xFF沒有用到。但是為了能夠線性查找,我們暫且認為這兩個字節也存在,就是我們強制把每個區190個漢字當做每個區192個漢字,不過0X7F和0XFF上沒有漢字。
定義GBKH代表第一個字節,GBKL代表第二個字節,字庫的偏移量offset,放入W25Q16的字庫從0x100地址開始存儲,那么獲取某個漢字的字模的函數就可以寫成:
void Get_GBK_DZK(uint8_t *code, uint8_t *dz_data) {uint8_t GBKH,GBKL;????? ??? ??? ?? uint32_t offset; ?? ??? GBKH=*code;GBKL=*(code+1);?? ? if(GBKH>0XFE||GBKH<0X81)return;GBKH-=0x81;GBKL-=0x40;offset=((uint32_t)192*GBKH+GBKL)*32;W25Q16_Read(dz_data,offset+0x100,32); ?? ??? ? ?return; }函數中,參數*code帶入漢字的兩字節編碼,*dz_data是一個32個字節的數據,帶入函數中,就可以得到任何一個漢字的字模了。例如:
??? uint8_t buf[32];Get_GBK_DZK("瑞", buf);總結
以上是生活随笔為你收集整理的LCD无字库--单片机字库存储的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STM32 FSMC 外部使用SRAM
- 下一篇: 采用串口DMA双缓冲方法,快速更新外部F