
簡介PCtoLCD2002完美版是一款面向圖形設(shè)計、攝影后期及視覺效果制作者的顯示器色彩校準(zhǔn)工具重點解決因屏幕色彩偏差導(dǎo)致的設(shè)計稿偏色、作品輸出不一致等問題。軟件支持色彩管理、亮度/對比度/色溫調(diào)節(jié)、sRGB/Adobe RGB等多種色彩空間轉(zhuǎn)換并兼容LCD、CRT、LED等顯示設(shè)備操作界面直觀適合不同水平的用戶快速完成校準(zhǔn)流程。資源包共19個文件壓縮后僅1.15MB主要包含Windows可執(zhí)行程序、txt使用說明與配置文檔、ini配置文件、bpl運行庫、h頭文件及ptl色彩預(yù)設(shè)文件結(jié)構(gòu)精簡便于解壓即用。已有155人學(xué)習(xí)下載用戶可通過附帶的說明文檔和預(yù)設(shè)快速上手根據(jù)自身顯示器型號調(diào)整參數(shù)從而獲得穩(wěn)定的色彩輸出提升設(shè)計、修圖與視頻調(diào)色工作的準(zhǔn)確度和效率。 搞過單片機(jī)顯示的人電腦里多半都躺著那么一兩個老掉牙但離不開的小工具。我自己用最久的就是PCtoLCD2002而且特意留了個“完美版”。別的取模軟件也不是沒試過轉(zhuǎn)了一圈還是回來了。別看不更新了它在給LCD、OLED點屏?xí)r處理漢字字模這一塊依然是效率最高的工具之一沒有那種花里胡哨的界面和云功能打開就能干活老牌工具那種“干完活就走”的氣質(zhì)真的很難替代。這篇文章就圍繞PCtoLCD2002完美版把取模這件事從頭到尾捋一遍。會講到它接解決什么問題、界面里那些選項到底怎么選、從輸入漢字到燒進(jìn)固件的完整流程以及我自己實際項目中踩過的幾個典型坑。無論你是剛開始玩OLED、LCD的入門選手還是已經(jīng)在做正式產(chǎn)品的嵌入式工程師只要屏幕上要顯示漢字這篇都能幫你少走不少彎路。1. 這個軟件到底是做什么的解決嵌入式顯示里的哪塊痛點1.1 從字形到點陣取模的本質(zhì)先聊點底層的。以STM32為代表的主流MCU本身是不帶中文字庫的。怎么理解這件事電腦上顯示一個“中”字是操作系統(tǒng)調(diào)用字體引擎把TrueType曲線輪廓渲染成屏幕上的像素。MCU沒有這個算力也沒有這么復(fù)雜的資源所以我們得換個思路提前把字“畫”好存成一個個數(shù)字?jǐn)?shù)組運行時直接把數(shù)組數(shù)據(jù)搬進(jìn)顯存就行?!爱嫛边@個動作在嵌入式里就是“取?!?。以16x16點陣為例一個漢字被分成16行、每行16個點。這個點是黑還是白對應(yīng)二進(jìn)制里的1還是0把16個點拼成兩個8位字節(jié)2字節(jié)16行就是32字節(jié)。PCtoLCD2002完美版干的事情就是把你在界面里輸入的文字按照你選擇的字體、大小、取模方向自動換算成這一串十六進(jìn)制字節(jié)。沒有它你得自己對著點陣圖一格一格數(shù)那效率和體驗太痛苦了。1.2 為什么“完美版”值得單獨拿出來說原版PCtoLCD2002年代久遠(yuǎn)放在現(xiàn)在用有幾個不方便的地方一是字體選擇上對新版Windows里一堆中文字體的兼容性一般二是輸出格式不夠靈活生成的數(shù)據(jù)經(jīng)常要手動改格式才能貼進(jìn)工程三是批量操作弱做一套幾百個漢字的菜單字庫時要一個一個字地來?!巴昝腊妗敝员淮蠹铱诳谙鄠魑易约旱呐袛嗍撬堰@類痛點基本都補上了。最直觀的改善是字體列表讀取得更完整系統(tǒng)里裝了黑體、雅黑都能正常識別不會出現(xiàn)原來的“字體列表空白”問題。輸出格式上也能自定義模板生成代碼直接就是符合你工程習(xí)慣的樣式。最關(guān)鍵的是批量生成和自動命名這塊整理字庫的效率提升了不是一星半點。所以我一直建議周圍朋友別再用那種功能殘缺的綠色精簡版找這個完美版存一份能省很多事。2. 核心功能拆解把界面上的每個選項吃透2.1 陰碼/陽碼、逐行/逐列這些選項的物理意義很多人打開這個軟件后直接就被左側(cè)那一排選項勸退了。其實每個選項背后都非常好理解關(guān)鍵要放到“屏幕怎么點亮”這個物理場景里想。先說“陰碼”和“陽碼”。這倆本質(zhì)上是點陣數(shù)據(jù)的“極性”不同。如果屏幕是黑底白字那么字的筆畫位置要點亮也就是1空白處不亮是0這種就是陽碼。反過來白底黑字的場景用陰碼更直接筆畫位置是0背景是1。這里沒有絕對的對錯關(guān)鍵看你的顯示驅(qū)動怎么用數(shù)據(jù)。我之前遇到過一個案例OLED驅(qū)動庫里的畫點函數(shù)是“寫1點亮”結(jié)果用了陰碼的數(shù)據(jù)字就像底片一樣反白了。排查半天最后就是把陰碼改成陽碼一次性解決。再說“逐行式”和“逐列式”這決定的是數(shù)據(jù)排列順序。逐行式就是按從左到右、由上而下的順序一行一行取點逐列式則是按從上到下、從左往右一列一列取點。用生活一點的類比逐行式像你閱讀英文書從左到右讀完一行再換下一行逐列式像你看那種豎向排版的古書從上往下看完一列再看下一列。屏幕驅(qū)動芯片比如SSD1306、ST7789在顯存里裝填數(shù)據(jù)時是按照它自己的掃描順序來刷行的。你的取模順序必須和驅(qū)動的掃描順序一致否則顯示出來的字就是亂的——可能筆畫錯位甚至像打碎的鏡子。順帶一提界面上還有個“逆向”選項比如“逐行式逆向”。這個也好理解就是倒著來從右下角往左上角取。什么時候用當(dāng)你旋轉(zhuǎn)了屏幕方向或者驅(qū)動本身的數(shù)據(jù)讀法是反向的時候這個選項能快速糾正方向不用重新取模。我自己習(xí)慣是先在紙上畫幾個關(guān)鍵字的點陣草圖再對照選項組合邏輯一下就清晰了。2.2 自定義輸出格式生成可以直接用的數(shù)組PCtoLCD2002完美版最讓我喜歡的地方是“自定義格式”這個功能。說白了它允許你告訴軟件“數(shù)據(jù)前綴用什么、后綴加什么、每行幾個字節(jié)、大端還是小端?!眲e小看這幾個設(shè)置直接決定了生成出來的代碼能不能“零修改”粘進(jìn)你的工程。舉個例子。你的代碼風(fēng)格是這樣的const unsigned char font_hz[16][32] { {0x00, 0x00, 0x7F, 0xFC, 0x7F, 0xFC, 0x01, 0x80}, // ... };如果你把輸出格式設(shè)置成對應(yīng)的模板那么在軟件里輸入一個字點擊生成復(fù)制出來就是這個樣子連大括號和數(shù)組名都是現(xiàn)成的。我自己的習(xí)慣是先把輸出格式預(yù)置為const unsigned char code { hex }這樣不同字模文件之間復(fù)制粘貼格式永遠(yuǎn)統(tǒng)一后期維護(hù)不用再肉眼對括號。還要注意一個“每行顯示數(shù)據(jù)個數(shù)”的參數(shù)。這個參數(shù)影響可讀性但不影響正確性。我的建議是設(shè)成8或者16也就是一行放8個十六進(jìn)制字節(jié)這樣數(shù)組看起來整齊和硬件調(diào)試時看內(nèi)存里的數(shù)據(jù)也能對應(yīng)上。2.3 字體與點陣尺寸的經(jīng)典搭配用PCtoLCD2002時很多人會有個疑問“我選16號字體是不是就是16x16點陣”這個問題是常見的誤區(qū)。字體里的“16號”是一個字體設(shè)計單位跟最終導(dǎo)出的點陣尺寸不是嚴(yán)格對應(yīng)的。16x16點陣的含義是用16行、每行16個點來描繪這個字符。真正決定導(dǎo)出的點陣有多大是軟件里的“字符寬度”和“字符高度”。對于標(biāo)準(zhǔn)漢字最經(jīng)典的搭配就是16x16和24x24奇數(shù)尺寸如12x12、32x32也常用但要額外注意12x12的漢字通常是從16x16里抽出來的簡化點陣顯示效果會有點“毛邊”適合小屏場景但別用在正式產(chǎn)品的主界面上。至于ASCII字符和數(shù)字一般用8x16或者8x8高度和漢字對齊否則混排時“1”和“一”會在垂直位置上一個偏高一個偏低看起來特別別扭。我個人的選擇邏輯很簡單追求清晰就用24x24以上屏小或者要顯示大量內(nèi)容就用12x12、16x16。然后記得把PCtoLCD2002里的“字符寬度”和“字符高度”設(shè)成一致比如都是16生成出來的數(shù)據(jù)才是標(biāo)準(zhǔn)的“方形”點陣。如果不一致比如寬16、高32那就是一個豎著的長方形用來做藝術(shù)字或特殊排版沒毛病但常規(guī)顯示不建議。3. 完整實操流程從輸入文字到固件顯示3.1 制作字庫前的準(zhǔn)備工作實操之前建議先確認(rèn)三件事能省下后續(xù)所有返工的時間。第一件是屏幕的分辨率和驅(qū)動IC型號搞清楚驅(qū)動是怎么掃描的這決定了取模方式選“逐行式”還是“逐列式”。第二件是MCU的Flash剩余空間16x16漢字一個字32字節(jié)如果你要在128x64的OLED上放一個8x432個漢字的菜單字庫那光字模數(shù)據(jù)就要1KB左右雖然不大但如果你用的是Flash只有8KB的老51單片機(jī)還是要掂量一下。第三件是確定顯示編碼一般UTF-8工程里直接用Unicode碼轉(zhuǎn)碼或者直接用GB2312碼這個后面會提。打開PCtoLCD2002完美版后默認(rèn)界面是網(wǎng)格預(yù)覽區(qū)加上右側(cè)參數(shù)面板。先別急著輸入文字我習(xí)慣先把所有參數(shù)一次配好再開始批量取模這樣后期連貫性有保障。3.2 參數(shù)配置的推薦組合下面貼一套我自己在STM32OLEDSSD1306128x64上驗證過無數(shù)次的推薦配置組合大家可以直接參考拷貝。參數(shù)項推薦值說明字符寬度/高度16 / 16標(biāo)準(zhǔn)漢字點陣也適配ASCII字符取8x16取模方式逐行式SSD1306頁尋址模式下的常用方式每行顯示數(shù)據(jù)8或16影響可讀性不影響數(shù)據(jù)本身陰碼/陽碼陽碼配合“點1亮”的畫點函數(shù)輸出格式自定義模板默認(rèn)模板也行但要看清分隔符字體類型黑體/宋體需求清晰度決定建議黑體取模走向順向如果顯示方向旋轉(zhuǎn)再用逆向拿16x16來算一筆賬16行 * 16點 256個點每8個點組成1字節(jié)所以共32字節(jié)數(shù)據(jù)總量是固定的。如果最后導(dǎo)出的數(shù)組長度不是32字節(jié)的整數(shù)倍那一定是參數(shù)配錯了這個很值得在調(diào)試時作為第一判斷點。參數(shù)配好之后在文本框里輸入“你好世界”點擊“生成字?!庇覀?cè)預(yù)覽區(qū)會實時把這四個字的點陣給畫出來。這時候要做一件事核對預(yù)覽圖。我在預(yù)覽圖里不是看字好不好看而是重點看有沒有明顯的斷筆、錯位尤其是像素密度比較高的字號。每個字都確認(rèn)無誤后再點“保存字?!被驈?fù)制出去。3.3 批量生成字庫文件從單字到完整菜單前面說的單字取模適合調(diào)試階段正式做產(chǎn)品時需求往往是一個菜單里幾十個漢字。PCtoLCD2002完美版支持在輸入框里一次粘貼多個漢字然后點擊“生成字?!彼鼤错樞蜉敵觥5@里有個非常容易踩的坑它通常會為每個字單獨生成一個數(shù)組段也可能把所有字連續(xù)生成一段長數(shù)組取決于你在“輸出格式”里的設(shè)置。我自己的做法是批量粘貼要用的所有漢字一次生成然后復(fù)制到Excel里按固定列寬把它們拆分成一行一個數(shù)組。再配合腳本批量加固定前綴。比如先用Python或其他工具把文本按“每32字節(jié)一個數(shù)組”切分再統(tǒng)一包一層const unsigned char code_font_01[] { ... }; const unsigned char code_font_02[] { ... };這樣維護(hù)起來特別清晰。如果你不習(xí)慣寫腳本那至少可以在軟件里一個字一個字地生成每個字單獨保存成一個.h片段。雖然慢一點但保險不會把數(shù)組順序搞錯。3.4 把字模數(shù)據(jù)接入工程并驗證顯示數(shù)據(jù)生成好了接下來就是工程側(cè)的事。常見的做法是在Keil或STM32CubeIDE工程里新建一個font.h把生成的字模數(shù)組貼進(jìn)去然后在主程序里按坐標(biāo)和數(shù)組索引調(diào)用。參考一下實際的調(diào)用邏輯。假設(shè)你已經(jīng)把“你好世界”四個字放在一個二維數(shù)組里const unsigned char hz_index[4][32] { {0x00, 0x00, 0x7F, 0xFC, 0x7F, 0xFC, ...}, // ...后面繼續(xù) }; void display_hanzi(uint8_t x, uint8_t page, uint8_t index) { for (uint8_t i 0; i 16; i) { for (uint8_t j 0; j 2; j) { draw_byte(x j * 8, page i, hz_index[index][i * 2 j]); } } }上面這種是典型的頁尋址逐行顯示。我實際用的多半是SSD1306的寫顯存方式把整個顯存建好再一次性刷到屏幕。這樣免去一字節(jié)一字節(jié)發(fā)送的閃爍感速度也快得多。具體實現(xiàn)就是先按字節(jié)填顯存填充時根據(jù)當(dāng)前坐標(biāo)算出顯存偏移把hz_index[index][i]寫進(jìn)去刷屏后字就出來了。實際燒錄驗證的時候我建議先用一個字的數(shù)據(jù)測通整個鏈路確認(rèn)方向和極性都對再批量上其余的字。這樣定位問題非常快不然幾十個漢字一起刷上去顯示花了你都不知道是哪個字的數(shù)據(jù)錯了。4. 高頻坑點與排查技巧實錄4.1 字顯示成反白、鏡像是哪里出了問題這個場景我碰到過不止一次。最常見的原因就是陽碼陰碼搞反了。你說我明明選對了怎么還是反白還有一個隱藏原因——有些OLED驅(qū)動庫在初始化的時候會設(shè)置“反色顯示”或“顯示翻轉(zhuǎn)”的寄存器位。比如SSD1306的0xA7命令就是反色顯示。數(shù)據(jù)本身是陽碼但寄存器把顯存反了一下屏幕上就變成白底黑字了。排查方法很簡單先在初始化代碼里找有沒有0xA6 / 0xA7、0xC8 / 0xC0這類翻轉(zhuǎn)命令把這些作為第一嫌疑對象。如果確認(rèn)寄存器沒有問題再去改字模的陰碼陽碼。順序很重要一定要先查硬件/驅(qū)動層再動數(shù)據(jù)層不然盲改半天數(shù)據(jù)最后發(fā)現(xiàn)只是初始化里一個參數(shù)的問題。鏡像的問題則多半出在“取模方向”上。比如你用的寬屏驅(qū)動數(shù)據(jù)掃描是從右往左的這時候就需要在取模方式里選“逆向”。還有一個在寬屏TFT上特別常見的情況用“逐列式”取了模但驅(qū)動寫顯存用的卻是“逐行式”的地址自增方向這時候你需要把驅(qū)動的寫坐標(biāo)設(shè)置改一下或者干脆讓取模方向配合驅(qū)動。我的建議始終是以驅(qū)動的數(shù)據(jù)手冊為準(zhǔn)把取模方向調(diào)成和驅(qū)動掃描方向一致不要反向去改驅(qū)動代碼。4.2 字模數(shù)據(jù)長度對不上屏上出現(xiàn)奇怪錯位16x16漢字對應(yīng)32字節(jié)24x24對應(yīng)72字節(jié)8x16的ASCII對應(yīng)16字節(jié)。當(dāng)你發(fā)現(xiàn)顯示錯位、缺筆畫、或多了一排亂七八糟的點十有八九是數(shù)組長度和注釋里的尺寸對不上。特別是在使用“批處理”或“腳本”方式合并字模時如果一個字的數(shù)組多復(fù)制了兩個字節(jié)后面所有字的顯示位置就整體偏移了。我自己踩過的坑是從網(wǎng)上復(fù)制了一份“12x12漢字字庫”文件里標(biāo)注的是12x12實際數(shù)據(jù)卻是由16x16裁剪來的長度是32字節(jié)而不是18字節(jié)導(dǎo)致調(diào)取時索引全亂。所以拿到任何字模文件第一件事就是對長度。怎么對直接看十六進(jìn)制數(shù)組元素個數(shù)或者放到PCtoLCD2002的“讀字?!惫δ芾镏匦录虞d一遍軟體會自動識別尺寸如果識別出來和標(biāo)稱不一致說明文件來源本身就不可靠趁早換。4.3 不同屏幕驅(qū)動IC之間的兼容性差異同一個字模數(shù)據(jù)在SSD1306的OLED上顯示正常換到ST7789的TFT上就容易亂這不是玄學(xué)是兩者的顯示緩沖掃描順序不一樣。SSD1306內(nèi)部顯存按8頁、每頁128字節(jié)組織本質(zhì)是把屏幕分成8條橫帶區(qū)域ST7789則是通過GRAM地址自增方式線性掃描坐標(biāo)數(shù)據(jù)直接對應(yīng)顯示點坐標(biāo)。遇到換屏的情況不要馬上回PCtoLCD2002里把所有數(shù)據(jù)重新生成一遍。先捋清楚新屏驅(qū)動是怎么刷顯存的如果是逐點坐標(biāo)方式那就優(yōu)先選“逐行式”如果支持局部窗口填充那“逐列式”也可能沒問題。我現(xiàn)在的習(xí)慣是手里常備兩份字模緩存一份逐行式、一份逐列式調(diào)試時直接切不用反復(fù)打開軟件省很多時間。4.4 中英文混合顯示時字體基線對不齊這個坑在真實產(chǎn)品界面里太常見了。漢字和數(shù)字、字母混排時中文用16x16點陣數(shù)字也用了16x16點陣顯示出來肉眼看起來數(shù)字就會偏下或偏上整體不在一條中線上。原因是漢字有比較復(fù)雜的天-地結(jié)構(gòu)而數(shù)字和字母通常集中在基線以上同尺寸點陣下它們的重心位置不一樣。要解決就得在字模層面人為校正。我常用的做法是中文用16x16點陣ASCII字符用8x16點陣然后寫顯示坐標(biāo)時把ASCII字符的Y坐標(biāo)額外加2到3像素讓它視覺上和漢字對齊。如果你覺得每次調(diào)坐標(biāo)麻煩還有一個更省事的方案取模時統(tǒng)一用“字體-仿宋”這類字形偏居中的字體把字符重心盡量往中間壓混合排版時會自然很多。5. 我的一些使用習(xí)慣和擴(kuò)展建議PCtoLCD2002用了這么多年說幾個我自己的習(xí)慣可能對你有參考價值。一是給字模文件命名時帶上尺寸和取模方式比如font_hz_16x16_ls、font_ascii_8x16_ls哪怕時間久了看到文件名也知道當(dāng)時的數(shù)據(jù)格式。二是把所有生成過的字模統(tǒng)一放到同一個目錄用日期做版本號這樣每次改版本后能清楚知道哪批字庫在哪個固件里。三是不管時間多緊生成完字模一定要在軟件預(yù)覽區(qū)里逐個看一眼確認(rèn)沒有多余的點、沒有斷筆畫再繼續(xù)下一步。再分享一個小技巧如果你需要類似“開機(jī)動畫文字動態(tài)效果”的處理其實不用額外取模直接對已經(jīng)生成的字模數(shù)組做位運算就行。比如想實現(xiàn)單個漢字從左往右逐步點亮的效果就可以在每次刷新時對數(shù)組里的每一字節(jié)按順序把高位的位逐步置1或清零每次刷新都多顯示一列點。這個效果用PCtoLCD2002生成的逐行式數(shù)據(jù)特別容易實現(xiàn)因為逐行式的字節(jié)排列和屏幕上的列位置有天然的對應(yīng)關(guān)系。關(guān)于擴(kuò)展方向PCtoLCD2002雖然老但并不妨礙你把它輸出和現(xiàn)代工具鏈結(jié)合。我自己最近就在做一個項目需要把一批自定義圖標(biāo)也做成數(shù)組我是先用占位符文字生成一段數(shù)據(jù)然后手工替換成圖標(biāo)的點陣數(shù)據(jù)再用Excel公式批量生成注釋。整個流程看似原始但勝在穩(wěn)定而且從調(diào)試到量產(chǎn)都沒出過差錯。工具的價值不在新舊在于你用它的思路是否足夠扎實。希望這篇文章能幫你在用PCtoLCD2002完美的路上少踩幾個坑。本文還有配套的精品資源點擊獲取