LCD作為終端顯示字符串的過程

2021-03-02 嵌入式IoT
LCD作為終端顯示字符串的過程


1.本文目的

2.資源評估

3.顯示原理

4.嵌入式上漢字處理

5.結果驗證與展示

6.總結


1.本文目的

做嵌入式圖形開發,我們往往都會利用到各種GUI進行互動設計,但是對於GUI的字符串處理與中文字庫顯示,也許並不會特別關注,因為GUI已經幫助我們封裝了一些通用的API,在調用相對應的API就可以顯示想要的圖像和字符串了。那麼這些底層原理到底是什麼呢?

正好和朋友討論,我們做嵌入式開發都是將輸出信息定位到串口,那能不能定位到I2C、SPI、網絡等各種協議上去呢?這個確實是有意思的事情,那正好手上有個樹莓派,可以通過DSI或者HDMI來顯示,那就把rt-thread的console重定位到LCD上去吧,讓樹莓派的屏幕代替我們的串口調試助手控制臺,這樣就不用接上串口看輸出信息了。

有了這個想法,於是立即付諸行動。需求很明確,開發平臺也已經確定,樹莓派4+HDMI屏(解析度1280x800)。或者接DSI的MIPI屏,我發現樹莓派的HDMI驅動原來和DSI的MIPI屏的驅動一樣,所以兩者沒有區別。為了簡化驗證的操作流程,可以選擇rtos,這裡我就用比較熟悉的rt-thread。因為rt-thread有著和Linux類似的控制終端,這樣更加方便對接。

2.資源評估

有了想法,若要想進行下去,必須評估一下手上的資源是否齊全。下面列出必要的資源

1.樹莓派4

選擇樹莓派4作為驗證平臺,是我因為現在手上環境搭建已經很方便了。嵌入式開發的痛點和難點就是在環境搭建上,一個好的的開發環境可以達到事半功倍的效果。環境搭建值得好好整理,對於驗證各種功能,實現各種特性的驗證都十分的好用。

2.hdmi屏

由於已經完成樹莓派4的hdmi屏驅動的研究工作,並且hdmi驅動和最後抽象出來的就是FrameBuffer。操作起來不用管底層的實現,只需要向這個Framebuffer的地址處寫數據,會自動將這個數據顯示到LCD的屏上,十分的方便。並不用關心x,y坐標,像素等等。

3.字庫

這裡先通過英文字庫進行演示,後面再談中文字庫。目前抽取的是開源的GUI中的font_dejavu_40字庫進行研究。後面的40表示每個字符高度為40個像素,因為屏的解析度為1280x800。如果每個字符的高度太小則看起來文字非常的小,在大屏上看起來十分不友好,所以這裡選擇40個高度的字體,而寬度不定是因為字符的寬度是不是確定的,每個字符有著自己的寬度比如L和l兩個數字的寬度就不一樣。

有了上述資源,就可以進行後面的探究了,下面來梳理一下顯示原理。

3.顯示原理

計算機圖形本質上就是像素點的集合,更加具體的就是紅黃藍三原色的組合。


三原色的排布組成了一個像素點。實際LCD放大後像素點看起來如下圖所示。


而這些像素的亮度決定了最後顯示在屏幕上的效果。像素深度(bits per pixel,簡稱bpp) 描述了每個像素的位數,比如32位則是RGBA8888,24位常見的RGB565和16位常見的565等等。這些都是一個像素所能夠表示的信息。

而多個像素可以表示一個圖像信息。像素是圖像操作的最小單位,所以下面暫時不要考慮顏色信息。

來看一個字庫中一個字符的信息

0x00, 0x00,  //....
0x00, 0x00,  //....
0x00, 0x00,  //....
0x00, 0x00,  //....
0x00, 0x00,  //....
0x00, 0x00,  //....
0x1f, 0x80,  //..+%@@@@@
0xff, 0x80,  //@@@@@@@@@
0xff, 0x80,  //@@@@@@@@@
0xe3, 0x80,  //@%%+..@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x03, 0x80,  //.@@@
0x7f, 0xfc,  //.@@@@@@@@@@@@@
0x7f, 0xfc,  //.@@@@@@@@@@@@@
0x7f, 0xfc,  //.@@@@@@@@@@@@@
0x00, 0x00,  //....
0x00, 0x00,  //....
0x00, 0x00,  //....
0x00, 0x00,  //....
0x00, 0x00,  //....
0x00, 0x00,  //....
0x00, 0x00,  //....
0x00, 0x00,  //....
0x00, 0x00,  //....

上述就是字符1在字符中的存放信息,每個字節按位展開,.表示0,@表示1。則右邊的注釋展示了該串字符的信息。如果我們將上述信息告訴給cpu,然後CPU處理這些信息放到LCD上顯示則可以顯示字符串1。

如果把上面的數組用程序解析交給LCD該如何設計。

1.拷貝上述數組到程序裡,作為只有一個字符的字庫數組array

2.申請一塊和framebuff一樣大的內存palette,作為圖像輸入的畫板

3.讀取array第一和第二個元素,將第一個元素按高位解析,如果是0向palette填充黑色像素點,1向palette填充白色像素點。


字庫中的每一位對應LCD的一個像素,如果對於RGB565來說,則表示2個字節。那我們可以做這樣的理解。字庫中1的寬度是32個像素,高度是40個像素。

於是可以做標準字庫的解析了。一個標準字庫是包含多個這樣的字符串結構的,所以字符串需要一張表記錄這些信息,根據asiic碼錶排序,字庫的存放順序也可如此,然後一個索引表記錄著每個字符串的寬度,數組所在的起始地址信息,有了這些信息,就可以依次做解析然後轉換成像素進行顯示了。

4.嵌入式上漢字處理

嵌入式上受到資源限制,漢字字庫一直都不好解決,不能為了顯示漢字把2500~7000個漢字都收錄進去,這樣需要的內存資源和flash資源十分龐大。為了解決這個問題,一般都是自定義字庫,就是首先列出該項目中實際會用到的所有漢字,然後利用特定的軟體生成對應的像素字符數組,生成的同時,也會對應這一張map表,方便查找具體漢字的位置。

在處理英文的時候,由於所需的字符很少,可以通過ASCII碼進行索引,漢字則可以自定義索引規則,這些都是需要自己設計處理的。但是原理是一樣的。

5.結果驗證與展示

經過上述的操作,已經完成了lcd console的任務,可以給自己交差了。


其實現的代碼也已經放到百度網盤上可以供參考。

連結:https://pan.baidu.com/s/17A37ISKT0tW3WWq2oXJASw 
提取碼:dgr6

上述代碼僅供參考,優化部分還需完善。

6.總結

需要注意的是,對於不同的LCD,需要自己找到合適的大小的字體,這樣才能看起來清楚。另外在實現的細節上需要注意的是最好不要在framebuffer上直接繪圖,可以放到一個與framebuffer大小一樣的數組中,叫做palette,也就是畫板。當繪製一幀畫面完成後,再刷新到framebuffer中,這是因為framebuffer是非cache的,操作起來會影響刷屏的幀率,看起來幀率會很低。

對於英文字庫的顯示、中文漢字的處理,有很多東西需要去拓展。其中漢字的抗鋸齒問題就很值得研究學習,漢字模糊,漢字的銳化等等,萬變不離其宗,其核心都是對像素的處理。LCD繪圖,理解像素處理流程,所有的上層應用實現都非常好理解。

相關焦點

  • 全方位解析LCD1602特性及單片機顯示應用
    現舉例如下:  sbit EN=P3^4;  sbit RS=P3^5;  sbit RW=P3^6;  2.顯示初始化,在這一步進行初始化及設置顯示模式等操作,包括以下步驟:  設置顯示方式  延時  清理顯示緩存  設置顯示模式  通常推薦的初始化過程如下
  • PIC單片機驅動LCD1602液晶顯示字符串程序
    web地址char web[ ] = {"***.*********.***"};//顯示公司電話號碼char tel[ ] = {" 110 " };void init(); //申明I/O口初始化函數void lcd_init(); //申明LCD初始化函數void write(char x); //申明顯示1位元組數據函數void
  • 「正點原子Linux連載」第五十九章Linux LCD驅動實驗
    換言之就是,LCD的驅動就是構建fb_info,並且向系統註冊fb_info的過程。設置好以後保存退出,重新編譯Linux內核,編譯完成以後使用新編譯出來的imx6ull-alientek-emmc.dtb和zImage鏡像啟動系統,如果LCD驅動工作正常的話就會在LCD屏幕左上角出現一個彩色的小企鵝logo,屏幕背景色為黑色,如圖59.4.1.2所示:圖59.4.1.2 Linux啟動logo顯示59.4.2 設置LCD作為終端控制臺我們一直使用
  • 基於51單片機的漢字LCD智能顯示模塊設計
    而lcd智能型顯示模塊則是一種低功耗、低損耗、低價值的顯示器件,它不但可以顯示各式各樣的字符、漢字和圖形,同時具有可編程能力,且與單片機接口方便,基於以上優點,lcd智能顯示模塊獲得了廣泛的應用。 系統組成本文引用地址:http://www.eepw.com.cn/article/21534.htm 本系統主要由三部分組成,分別為單片機,lcd模塊和flash字庫,圖1所示是該系統的硬體原理框圖,由於顯示所需要佔用的資源過多(本設計採用的是16×16點陣,每個漢字存儲需要32個字節),而單片機內部ram資源及其有限,所以系統設計時有必要擴展—
  • 【轉】西門子HMI和PLC中文字符串的顯示與輸入
    =============================================自動化項目中,HMI部分會經常涉及到使用字符串顯示漢語部分。本文主要講述西門子常用的觸控螢幕和經典Wincc如何顯示漢語字符。觸控螢幕和PLC能正確顯示漢語的條件:PLC和HMI都必須支持同一種漢語編碼方式。        要了解漢語顯示,要了解漢語的編碼模式。
  • LCD與LED的區別在哪裡,LED和LCD哪個好
    lcd與led的區別 雖然LED顯示屏已經逐漸成為市場上的主流液晶屏,但多數人對LCD顯示屏和LED顯示屏的了解還不是很清晰,在選購液晶屏時經常會覺得受到了廠商的誤導,本文將對什麼是lcd,led是什麼,lcd液晶屏和led液晶屏有什麼區別,各自優劣勢在哪,
  • 液晶顯示模組防靜電三大妙招
    前面我們海飛智顯小編和大家講了靜電對液晶屏幕lcd會造成哪些影響,靜電對電子產品的危害真是不小,一家專業的tftlcd顯示屏廠商一般都可以在生產過程中進行規避。在生產的過程中不產生靜電,避免靜電對tftlcd顯示屏,把危險扼殺在搖籃裡,才是最明智之舉,揭曉來小編就要分享乾貨了,關於lcd顯示屏廠商在生產過程中如何有效防止靜電。
  • lcd1602中文資料分享:lcd1602接線圖_lcd1602與單片機連接圖
    lcd1602液晶屏在很懂工業產品上都有應用,LCD1602能夠能夠同時顯示32個字符,價格便宜,編程簡單而且穩定可靠。lcd1602液晶屏是一種圖形點陣顯示器,顯示原理簡單易懂,都是液晶屏內部的液晶材料變化而顯示不同的字符,因為液晶是具有流動特性的物質,所以只需外加很微小的力量即可使液晶分子運動,以最常見普遍的向列型液晶為例,液晶分子可輕易的借著電場作用使得液晶分子轉向,由於液晶的光軸與其分子軸相當一致,故可藉此產生光學效果,而當加於液晶的電場移除消失時,液晶將借著其本身的彈性及黏性,液晶分子將十分迅速的回撤消來未加電場前的狀態
  • lcd12864中文資料匯總(12864引腳說明及功能_特性參數及驅動程序...
    lcd12864簡介   帶中文字庫的128X64是一種具有4位/8位並行、2線或3線串行多種接口方式,內部含有國標一級、二級簡體中文字庫的點陣圖形液晶顯示模塊;其顯示解析度為128×64,內置8192個16*16點漢字,和128個16*8點ASCII字符集。
  • 【Proteus】單片機配合矩陣鍵盤LCD1602製作簡易計算器
    在LCD1602的初始化程序中需要配置LCD1602的一些配置指令,就是那些顯示屏的配置指令,是否顯示光標,地址是否自加等等配置,按照自己的需求進行配置即可,之後將光標移到最開始的位置,方便之後的操作。
  • 單片機設計LCD數字鐘(萬年曆)
    //P2.4sbit RW=P2^5; //P2.5sbit E=P2^6; //P2.6sbit set=P3^4; //設置鍵sbit enter=P3^5; //確認鍵sbit add1=P3^6; //加1鍵sbit sub1=P3^7; //減1鍵bit k=0,f=0;//k為0表示運行狀態,k為1表示設置狀態;f為0表示第一行顯示
  • 51單片機開發之LCD1602顯示屏
    它是由若干個5x7或者5x11的點陣字符位組成,每個點陣字符位都可以用顯示一個字符,每位之間有一個點距的間隔,每行之間也有間隔,起到了字符間距和行間距的作用,正因為如此,所以它不能很好的顯示圖片。(4)指令4:顯示開關控制。其中,D用於控制整體顯示的開與關,高電平表示開顯示,低電平表示關顯示;C用於控制光標的開與關,高電平表示有光標,低電平表示無光標;B用於控制光標是否閃爍,高電平閃爍,低電平不閃爍。(5)指令5:光標或字符移位控制。其中,S/C表示在高電平時移動顯示的文字,低電平時移動光標。(6)指令6:功能設置命令。
  • LCD屏幕和AMOLED屏幕的區別,告訴你iPhone11為什麼使用LCD屏幕
    LCD屏幕通過背光光源控制前置液晶面板,進行顯示。AMOLED屏幕是以AMOLED材料為主的屏幕,AMOLED則是使用有源矩陣技術的有機發光二極體面板。在屏幕顯示原理上,lcd屏幕是背光光源的方式,顯示圖像;AMOLED屏幕則是直接自己發光,顯示圖像。
  • ESkill LCD2004液晶模塊ARDUINO連接應用
    編譯後LCD2004A液晶模塊顯示結果如圖:lcd.createChar(0, bell);lcd.createChar(1, note);lcd.createChar(2, clock);lcd.createChar(3, heart);lcd.createChar(4, duck);lcd.createChar(5, check);lcd.createChar
  • 寧盾物聯網終端準入之啞終端IP及MAC地址防偽造解決方案
    加強啞終端身份識別,杜絕非法偽造IP/MAC地址使用網絡終端身份又可稱為終端指紋,就像人類將身份證、護照、指紋、面部作為識別通行證一樣,啞終端MAC地址、IP位址、終端類型、作業系統、版本、品牌、型號等均可作為終端指紋及身份標識。
  • Arduino 課程 第 9 課 LCD1602 I2C 液晶實驗
    LiquidCrystal_I2C lcd(0x27,16,2);初始化對象中有三個參數,分別對應 地址、列、行。地址取決於轉接板上A0 A1 A2 的連接。懸空即拔掉跳線帽。短路即插上跳線帽。#include <Wire.h>#include <LiquidCrystal_I2C.h>LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display// 創建液晶屏對象// 參數1 液晶屏地址// 參數2
  • STM32十一天燒寫中文字庫在LCD上顯示
    led.h"#include"key.h"#include"delay.h"#include"uart1.h"#include//因為用到printf函數#include"spi2.h"#include"w25q64.h"#include"iic.h"#include"at24c02.h"#include"lcd.h"voidDelay
  • 如何提取指定開頭和結尾的字符串並以三種形式顯示結果
    如何提取指定開頭和結尾的字符串並以三種形式顯示結果?一、 題目如下圖所示,"要求:提取開頭為華南和華東和東北,結尾為一部、三部和五部的部門,並按如下三種方式分別顯示結果:1. 與目標單元格同行對應顯示。2. 獨立集中顯示。
  • C++字符串操作
    庫函數中提供了大量的API函數用於讀寫字符串、拷貝字符串、比較字符串、合併字符串、查找字符串等。  #include<stdio.h> #define MSG "I am a symbolic string constant."