|
本帖最后由 人民幣的幻想 于 2015-4-16 09:25 最近幾天在DIY MP3播放器這個(gè)東西,說(shuō)來(lái)其實(shí)很簡(jiǎn)單,去年就做好了。只不過(guò)當(dāng)初是通過(guò)1602液晶顯示一些簡(jiǎn)單的東西,歌曲名字還有很多相關(guān)信息沒(méi)法顯示。言歸正傳,這回打算用OLED屏試試看,經(jīng)實(shí)踐,顯示效果幫幫噠~~。 首先先說(shuō)一下所用方案:MCU用的STM32F103RBT6,OLED用的SSD1306控制的,MCU和屏是通過(guò)硬件SPI通信的。具體底層實(shí)現(xiàn)請(qǐng)看我曾經(jīng)發(fā)過(guò)的一篇帖子。SD卡采用硬件SPI+DMA方式驅(qū)動(dòng),底層驅(qū)動(dòng)移植自振南的SD卡驅(qū)動(dòng)。 字符和數(shù)字顯示很簡(jiǎn)單,用的取模軟件直接取得,畢竟數(shù)量不多,占用體積也不大,相對(duì)128K的ROM來(lái)說(shuō)夠了。我是用的PCtoLCD2002完美版取得模,點(diǎn)陣采樣陰碼-列行式-逆向-C51格式。當(dāng)然還可以自己選擇自己喜歡字體大小和格式,就不再多說(shuō)了。顯示原理是這樣的:假設(shè)以8*8大小某字符為例,占用8*8=64個(gè)bits,占用64/8=8Bytes,其他格式請(qǐng)自己推算,列行式即先掃一列在掃下一列,掃完這一行再掃下一行(假設(shè)有的話)。至于為什么選擇陰碼,我用的OLED屏手冊(cè)上有這樣一句話 Display Mode: Passive Matrix,即共陰點(diǎn)陣。大家應(yīng)該都用過(guò)數(shù)碼管,有共陰和共陽(yáng)之分,此處原理相同。逆向是低位在前高位在后,即先取低位再取高位。取模原理大致就是這樣。顯示是某些像素點(diǎn)的顯示與不顯示,我們把一個(gè)字符的8個(gè)字節(jié)依次取出,通過(guò)SPI送屏顯示,這樣,一個(gè)字符就得到顯示。 圖片顯示同字符顯示,如果想顯示到LCD屏上,就需要一些辦法了,首先用畫(huà)圖板打開(kāi)某張圖片,然后調(diào)整分辨率為水平128,垂直64。并且保存為單色位圖格式。然后用PCtoLCD軟件打開(kāi)圖片,然后生成字模就好了。以下同字符顯示。 至于漢字顯示就比較復(fù)雜,為什么復(fù)雜,拿常見(jiàn)的16*16點(diǎn)陣大小的漢字舉例,一個(gè)漢字占用256bits=32Bytes,想制作MP3,那么長(zhǎng)名文件名顯示是繞不開(kāi)的,因此漢字規(guī)模按8000算,共占用8000*32=256000Bytes=250.98KB,以單片機(jī)的存儲(chǔ)空間是放不下的,即使換用更大存儲(chǔ)空間的單片機(jī)比如1M flashROM,那么24*24點(diǎn)陣的漢字占用562.5KB空間,再加上GBKUNI互轉(zhuǎn)表,那么可供利用的ROM空間就很小了。所以把這些點(diǎn)陣放到一個(gè)空間很大又不貴的存儲(chǔ)介質(zhì)中去,不失為一個(gè)很好的辦法,基于此,我用的SD卡存放這幾個(gè)文件,分別是12字體,16字體,24字體,GBK轉(zhuǎn)UNI互轉(zhuǎn)表,UNI轉(zhuǎn)GBK互轉(zhuǎn)表。這些是顯示漢字及長(zhǎng)名所必須的文件。存儲(chǔ)的問(wèn)題解決了,那么怎么找到哪個(gè)漢字對(duì)應(yīng)哪些字節(jié)的點(diǎn)陣數(shù)據(jù)呢?這就要稍微了解一下漢字在計(jì)算機(jī)內(nèi)表示的知識(shí)了,我們知道,由于直接存放點(diǎn)陣太大,所以在計(jì)算機(jī)內(nèi)部是利用區(qū)位碼來(lái)存放漢字的,關(guān)于這個(gè)區(qū)位碼,我們國(guó)家發(fā)布了一些標(biāo)準(zhǔn),當(dāng)然,在MP3播放器中用到的是簡(jiǎn)體中文,而且可能出現(xiàn)一些不太常見(jiàn)的漢字,因此我利用GBK標(biāo)準(zhǔn)達(dá)到了顯示這些漢字的效果。每個(gè)GBK碼由2個(gè)字節(jié)組成,第一個(gè)字節(jié)為0X81~0XFE,第二個(gè)字節(jié)分為兩部分,一是0X40~0X7E,二是0X80~0XFE。其中與GB2312相同的區(qū)域,字完全相同。我們把第一個(gè)字節(jié)代表的意義稱為區(qū),那么GBK里面總共有126個(gè)區(qū)(0XFE-0X81+1),每個(gè)區(qū)內(nèi)有190個(gè)漢字(0XFE-0X80+0X7E-0X40+2),總共就有126*190=23940個(gè)漢字。我們的點(diǎn)陣庫(kù)只要按照這個(gè)編碼規(guī)則從0X8140開(kāi)始,逐一建立,每個(gè)區(qū)的點(diǎn)陣大小為每個(gè)漢字所用的字節(jié)數(shù)*190。這樣,我們就可以得到在這個(gè)字庫(kù)里面定位漢字的方法: 當(dāng)GBKL<0X7F時(shí):Hp=((GBKH-0x81)*190+GBKL-0X40)*(size); 當(dāng)GBKL>0X80時(shí):Hp=((GBKH-0x81)*190+GBKL-0X41)*(size); 其中GBKH、GBKL分別代表GBK的第一個(gè)字節(jié)和第二個(gè)字節(jié)(也就是高位和低位),size代表一個(gè)漢字點(diǎn)陣規(guī)模大小,Hp則為對(duì)應(yīng)漢字點(diǎn)陣數(shù)據(jù)在字庫(kù)里面的起始地址(假設(shè)是從0開(kāi)始存放)。這樣我們只要得到了漢字的GBK碼,就可以顯示這個(gè)漢字了。從而實(shí)現(xiàn)漢字在液晶上的顯示。 說(shuō)到底,我們知道漢字點(diǎn)陣在哪放,怎么找到某個(gè)漢字對(duì)應(yīng)偏移,那么怎么讀取數(shù)據(jù)送到屏幕來(lái)呢,接下來(lái)就需要一些文件系統(tǒng)的知識(shí)了。。。。。。(省略1w字)。當(dāng)然,也可以不用去了解,用現(xiàn)成的文件系統(tǒng)數(shù)據(jù)讀取函數(shù)直接去定位文件位置,讀取相應(yīng)大小數(shù)據(jù)就好了。這里我用的是znFAT V11.21,實(shí)踐看來(lái),用起來(lái)很不錯(cuò),移植到你的CPU平臺(tái)也很簡(jiǎn)單。這樣,就得到顯示一個(gè)漢字到OLED屏的效果了,為了顯示一個(gè)漢字,我們不得不去了解文件系統(tǒng),了解字庫(kù)中漢字表示,計(jì)算偏移量,定位數(shù)據(jù),讀取數(shù)據(jù),處理,送顯示。 這里就完成了整個(gè)漢字、字符、圖片的顯示原理及實(shí)踐,在臘月二十九終于做好了,等待回學(xué)校有網(wǎng)時(shí)發(fā)出。 ![]() 以下附上參考資料若干,有愿意一起折騰的朋友可以參考幫助改進(jìn),一起努力學(xué)習(xí)。 STM32開(kāi)發(fā)指南V1.0庫(kù)函數(shù)版本。(漢字顯示章節(jié)) SSD1306數(shù)據(jù)手冊(cè)。 嵌入式FAT32文件系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)-基于振南znFAT(上冊(cè))。
|
|
|
來(lái)自: rookie > 《技術(shù)帖》