17.1液晶顯示原理
TFT-LCD(Thin Film Transistor Liquid Crystal Display)即薄膜晶體管液晶顯示器,是微電子技術與液晶顯示器技術巧妙結合的的一種技術。
CRT顯示器的工作原理是通電后燈絲發熱,陰極被激發后發射出電子流,電子流受到高電壓的金屬層的加速,經過透鏡聚焦形成極細的電子束打在熒光屏上,使熒光粉發光顯示圖像。LCD顯示器需要來自背后的光源,當光束通過這層液晶時,液晶會呈不規則扭轉形狀(形狀由TFT上的信號與電壓改變實現),所以液晶更像是一個個閘門,選擇光線穿透與否,這樣就可以在屏幕上看到深淺不一,錯落有致的圖像。目前主流的LCD顯示器都是TFT-LCD,是由原有液晶技術發展而來。TFT液晶為每個像素都設有一個半導體開關,以此做到完全的單獨控制一個像素點,液晶材料被夾在TFT陣列和彩色濾光片之間,通過改變刺激液晶的電壓值就可以控制最后出現的光線強度和色彩,如圖7-1所示。
圖7-1 液晶顯示屏結構圖
Kingst-32F1開發板配套的TFT-LCD是3.2寸大小,分辨率為240*320,即一共有240×320=76800個像素點,每個像素都設有一個半導體開關,像素之間是相對獨立的,這么多像素如何控制呢?聯想一下51單片機驅動LED點陣時,為了減少IO口的使用,采用三八譯碼器驅動點陣模塊。同理,TFT-LCD也可以用專門的驅動器來驅動,教材所用的TFT-LCD采用ILI9341驅動芯片。該控制芯片是封裝在TFT-LCD內部,只留有外部引腳接口。對於用戶來說,只要掌握如何向ILI9341控制器發送指令和讀寫數據,並不需要再設計額外的驅動電路,該液晶的具體參數如表7-1所示。
7.1.1ILI9341硬件接口和像素格式
ILI9341驅動芯片主要由接口電路、顯存(GRAM)、LCD驅動電路、背光控制、電源等部分組成,主要結構如圖7-2所示。
由於STM32的I/O口資源豐富,為了提高數據的讀寫效率,采用16位的8080並行接口,可以比8位的8080並行接口的傳輸速率高出一倍(數據線多出一倍),由於是並行接口,比SPI串行接口的傳輸速率更快,並且通訊時序簡單,因此這里將TFT-LCD的IM2~IM0引腳接地。
7.1.4 ILI9341 GRAM指令和像素格式
GRAM(Graphics RAM)——顯存,也稱作幀存儲器,是ILI9341用來存儲顯示數據的圖像RAM。GRAM中一個像素點的顏色數據用18bit表示,GRAM的大小為240*320*18/8=172800字節,所有像素數據都存儲在GRAM中。當TFT-LCD開顯示時,LCD源極驅動會根據GRAM中存儲的數據對液晶像素進行刷新,從而實現圖像顯示。如果改變GRAM中單個像素點的數據,刷新顯示時,TFT-LCD對應的像素狀態也會改變。如何才能准確的向每個像素對應的數據位寫入顯示數據呢?ILI9341控制器內部設計了一個“控制寄存器”,用戶只需要按照要求發送相應的控制指令,“控制寄存器”收到控制指令后,通過“地址計數器”在對應的像素位置寫入像素數據,最終通過LCD源極驅動LCD刷新顯示,ILI9341控制器內部結構如圖7-8所示。
ILI9341控制器共有76條控制指令,每條指令的控制功能在手冊中都有詳細描述,本書只針對常用指令做重點說明。
1、讀取驅動器ID:用於讀取TFT-LCD的驅動器的的ID,板載液晶的驅動器是ILI9341,ID固定為0x9341。在讀取的過程中,首先通過寫命令函數發送指令0xD3,然后連續讀取4次數據。其中第1次是無效數據,第二次是版本號,也是無效數據,第三次和第四次的高8位也是無效數據,只有第三次和第四次的低8位才是有效的ID數據,讀取ID成功,表明單片機和驅動器通信正常,讀ID指令如圖7-9所示。
2、設置顯示窗口:當用戶將一部分要顯示的內容填充到液晶顯示屏的某一個區域,這個區域的列范圍用0x2A這條指令設置,行范圍用0x2B這條指令設置。首先通過寫命令函數發送指令0x2A,緊跟着列起始地址的高字節、列起始地址的低字節、列結束地址的高字節、列結束地址的低字節;然后通過寫命令函數發送指令0x2B,緊跟着行起始地址的高字節、行起始地址的低字節、行結束地址的高字節、行結束地址的低字節。注意:結束地址只能大於等於起始地址,不能小於起始地址。
通過限定這4個角的坐標,就可以從液晶中選取其中一個區域作為顯示窗口。指令和地址都只有低8位數據有效,發送過程如圖7-10和圖7-11所示。
3、寫存儲器指令:設置好顯示窗口后,在寫入數據之前,需要先寫入0x2C指令。無論當前行寄存器和列寄存器的地址是多少,寫入0x2C后,行寄存器和列寄存器會自動復位,復位值就是通過0x2A和0x2B寫入的列起始地址和行起始地址,此時如果發送數據,數據會寫入幀存儲器對應地址中,數據寫入具體流程如圖7-12所示。
4、幀存儲器掃描方向控制指令:設置顯示窗口后,發送0x2C指令開始向內存中寫數據,數據是從設置窗口的起始地址開始寫入,先寫行,行地址自增直至該行的終止地址,然后列地址加1,數據再從下一行的起始地址開始寫入,如此循環直至將整個顯示窗口的數據寫入到幀存儲器中。幀存儲器讀/寫掃描方向如圖7-13所示,圖中B表示起始位置,E表示終止位置。
數據按照上面介紹的順序寫入,但是液晶屏刷新顯示時,並不一定按照寫入的順序刷新數據,而是可以通過“存儲器訪問控制”指令0x36設置幀存儲器的掃描方向(即行列方向)。設置幀存儲器掃描方向時,先發送指令0x36,緊跟着發送設置參數,參數由18位組成,只有2~7位有效。其中D7:MY-設置行地址方向;D6:MX-設置列地址方向;D5:MV-設置行列地址交換;D4:ML-設置垂直刷新方向;D3:BGR-設置刷新像素格式為BGR或RGB;D2:MH-設置水平刷新方向,存儲器訪問控制指令如圖7-14所示。
其中MY、MX、MV這三位用來設置掃描方向,也是重點介紹的地方,MX和MY分別設置行列掃描方向,MV設置行列交換,它們可以組合成23=8種掃描模式,如圖7-15所示。
注意:無論MY、MX、MV設置的存儲器掃描方向如何,數據總是以相同的順序寫入幀存儲器。設置掃描方向后,還需要通過0x2A、0x2B指令重新設置顯示窗口大小。
其中模式0和3為豎屏顯示,模式5和6為橫屏顯示,這四種模式的掃描方向和稍后所講的文字取模方向相同,旋轉液晶屏即可達到閱讀效果,其他模式直接顯示時呈現亂碼,需要根據掃描方向重新取模。
ML和MH主要設置幀存儲器到LCD顯示面板的數據刷新方向,就像過年貼春聯,可以選擇從上向下貼,或者從下向上貼,無論哪種方式,最后的顯示效果是不變的,默認ML和MH都為0。
5、像素格式:
TFT-LCD的每個像素點由紅(R)、綠(G)、藍(B)三原色組成,幀存儲器為每個像素分配了18bit的存儲空間,三原色各用6個數據位表示,也就是常說的RGB666格式,該模式色彩度最大,它們按不同比例的混合可以組成218種顏色,俗稱262K色。同時ILI9341還支持16位、9位數據格式。
GRAM選擇16位數據格式,16位數據格式下按照R:G:B =5:6:5格式存儲,俗稱RGB565格式,由於GRAM為每個像素預留的存儲空間是18bit,為了保證寫入的16bit像素數據能夠正常匹配GRAM中18bit像素存儲空間,控制器會自動將RGB565格式轉換成RGB666格式,轉換后數據存儲形式如圖7-16所示,空白位置表示沒有數據。由於缺少了兩位數據,此時TFT-LCD最大支持216種色彩度,也就是65K色
像素數據在幀存儲器按照圖7-18的格式存儲,即R位於高位,B位於低位。但是像素數據刷新到LCD顯示屏上時,可以通過“存儲器訪問控制(0x36)”指令中的 BGR位選擇像素數據寫入到顯示屏的方向,當BGR位為 0時,數據按照RGB(即R在高位,B在低位)的順序寫入;當BGR位為1時,數據沿BGR(即B在高位,R在低位)的順序寫入到液晶面板中。默認BGR位為1,該模式下寫入的顏色與顯示效果相同,像素刷新示意圖如圖7-17所示。
6、讀存儲器指令;讀存儲器指令為0x2E,與上面介紹的寫存儲器指令0x2C類似,首先發送0x2A和0x2B設置行列起始和終止地址,然后發送0x2E,行列地址自動復位。通過讀數據函數可以讀取幀存儲器存儲的像素數據,第一次讀取的數據無效,之后每一次讀取16bit數據,由於幀存儲器中每個像素占18位,因此一個像素點的數據需要分兩次讀取,第一次讀取RG的值,第二次讀取B值。讀數據時行列地址會自增,直至讀完整個顯示窗口,讀存儲器指令如圖7-18所示。
7、ILI9341初始化
由於ILI9341液晶屏初始化需要設置的參數比較多,在此就不再一一講解,僅提供初始化代碼。如果想深入研究,可以按照上面介紹指令的方式,到ILI9341參考手冊中查找相關指令和對應參數位的作用。
27.2ILI9341 TFT-LCD 顯示操作
7.2.1 畫點
畫點就是向單個像素點填充顏色,畫點主要分為三部分:
第一步、通過窗口設置函數設置像素點的坐標,由於設置的是一個像素點,所以窗口設置函數的起始和終止坐標相同;
第二步、發送寫存儲器指令0x2C;
第三步、寫入像素數據。為了提高速率,通過寫指令和數據函數一並將指令和數據寫入。
7.2.2 讀點
讀點就是讀取幀存儲器中相應像素點的數據。讀點也分為三部分:
第一步、通過窗口設置函數確定像素點的坐標;
第二步、發送讀存儲器指令0x2E;
第三步、讀取像素數據。
由於幀存儲中像素數據為18bit,寫入幀存儲器中的像素數據是RGB565格式,幀存儲器中存儲的數據是RGB666格式。16位並口模式下讀取一個像素點數據需要讀兩次,數據按照高位在前,低位在后順序輸出。第一次讀取的數據無效,之后讀取的才是真正的像素數據;第二次讀取的是RG值,其中高8位為R值,有效位為[15:11]位,低8位為G值,有效位為[7:2]位,第三次讀取的B值位於高8位,有效位為[15:11]位,像素數據讀取完畢后還需要轉換為RGB565格式。需要注意的是讀數據時需要設置數據總線為輸入模式,讀取完畢后再重新設置為輸出模式。
7.2.4 填充和清屏
填充是對某一區域填充特定顏色。首先通過“顯示窗口設置函數”設置被填充區域范圍,然后發送0x2C寫存儲器指令,最后通過寫數據函數寫入像素數據。該函數如下所示:其中xStart、yStart、xEnd、yEnd表示填充區域起始和終止坐標,Color表示填充的顏色。
void LcdFill(u16 xStart, u16 yStart, u16 xEnd, u16 yEnd, u16 Color)
清屏函數實際是一個填充函數,只不過清屏函數的顯示窗口大小設置為全屏。該函數如下所示,Color表示全屏填充的顏色。
void LcdClear(u16 Color)
參考了網友的文章:https://mp.weixin.qq.com/s/JME3VArPETgPjD0n_cHKNQ