基于Nios在液晶屏和觸摸屏顯示實驗
1. 實驗內容
通過本實驗了解觸摸屏的觸摸原理和顯示原理,能夠在液晶屏上開發應用。
本實驗要求:
1. 將存儲在Flash中的一幅圖像顯示在液晶屏上。
2. 將用戶在觸摸屏上觸摸的坐標顯示在8段數碼管上。
2. 實驗原理
2.1 液晶屏的基本原理
液晶顯示是目前最常用的顯示方式,無論是簡單的黑白顯示還是高清晰度的數字電視,大量使用了液晶顯示。液晶屏的基本物理原理是:液晶分子在不通電時排列混亂,阻止光線通過;當液晶上加一定電壓時,分子便會重新垂直排列,使光線能直射出去,從而可以在液晶陣列上顯示不同的圖形。
本實驗使用的液晶屏分辨率為400×240,其控制芯片為ILI9326。對于液晶屏顯示的操作主要體現在對控制芯片ILI9326的操作上。
對ILI9326進行的操作可以分為讀、寫兩種操作,本實驗中主要用到寫操作,在此簡要介紹FPGA如何向ILI9326進行寫操作。具體到寫操作又可以分為兩種操作模式:第一是對芯片ILI9326中寄存器的設置操作,第二是對ILI9326中存儲像素值的GRAM的操作。本實驗使用的液晶屏分辨率為400×240,一共有96000個像素點,而每一個像素點對應于一位16位寬的GRAM,也就是說通過控制ILI9326內部的GRAM即可以控制液晶屏的顯示內容。
對ILI9326中控制寄存器的設置操作時序為:首先輸出寄存器的編號,然后輸出要向該寄存器寫入的數據,其時序如圖 20-1所示。在nWR的上升沿和RS信號為低時FPGA向從設備ILI9326送出寄存器的編號,而在下一個nWR的上升沿和RS信號為高時FPGA輸出要寫入數據。
圖20-1 設置控制寄存器時
對ILI9326中GRAM的寫操作時序為:首先在nWR的上升沿和RS為低電平的時FPGA向ILI9326發送0202h,然后在nWR的上升沿和RS為高電平期間FPGA逐次向ILI9326發送需要顯示的圖像像素數據(圖 20 2)。在每寫完一個圖像像素數據后,ILI9326內部的計數器會自動加一,使下一個寫入的數據對于下一個像素,以此類推達到控制液晶屏顯示內容的目的。
圖20-2 寫入需要顯示的圖像信號
2.2 觸摸屏的基本原理
觸摸屏(Touch panel)是可以接收觸頭等輸入訊號的感應式顯示裝置,當觸頭接觸了屏幕時,屏幕上的觸覺反饋系統就可以感應到觸頭接觸的位置。
從技術原理上,觸摸屏可以分為五類:矢量壓力傳感技術觸摸屏、電阻技術觸摸屏、電容技術觸摸屏、紅外線技術觸摸屏、表面聲波技術觸摸屏。其中矢量壓力傳感技術觸摸屏已退出歷史舞臺;紅外線技術觸摸屏價格低廉,但其外框易碎,容易產生光干擾,曲面情況下失真;電容技術觸摸屏設計構思合理,但其圖像失真問題很難得到根本解決;電阻技術觸摸屏的定位準確,但其價格頗高,且怕刮易損;表面聲波觸摸屏解決了以往觸摸屏的各種缺陷,清晰不容易被損壞,適于各種場合,缺點是屏幕表面如果有水滴和塵土會使觸摸屏變的遲鈍,甚至不工作。按照觸摸屏的工作原理和傳輸信息的介質,我們把觸摸屏分為四種,它們分別為電阻式、電容感應式、紅外線式以及表面聲波式。每一類觸摸屏都有其各自的優缺點,要了解那種觸摸屏適用的場合,關鍵就在于要理解每一類觸摸屏技術的工作原理和特點。下面對實際中應用較多的電容和電阻式觸摸屏進行簡要介紹一下。
電容技術觸摸屏是利用人體的電流感應進行工作的。電容式觸摸屏是是一塊四層復合玻璃屏,玻璃屏的內表面和夾層各涂有一層ITO(氧化銦),最外層是一薄層矽土玻璃保護層,夾層ITO涂層作為工作面,四個角上引出四個電極,內層ITO為屏蔽層以保證良好的工作環境。 當手指觸摸在金屬層上時,由于人體電場,用戶和觸摸屏表面形成以一個耦合電容,對于高頻電流,電容是直接導體,于是手指從接觸點吸走一個很小的電流。這個電流分從觸摸屏的四角上的電極中流出,并且流經這四個電極的電流與手指到四角的距離成正比,控制器通過對這四個電流比例的精確計算,得出觸摸點的位置。
這種觸摸屏利用壓力感應進行控制。電阻觸摸屏的主要部分是一塊與顯示器表面非常配合的電阻薄膜屏,這是一種多層的復合薄膜,它以一層玻璃或硬塑料平板作為基層,表面涂有一層透明氧化金屬(透明的導電電阻)導電層,上面再蓋有一層外表面硬化處理、光滑防擦的塑料層、它的內表面也涂有一層涂層、在他們之間有許多細小的(小于1/1000英寸)的透明隔離點把兩層導電層隔開絕緣。 當手指觸摸屏幕時,兩層導電層在觸摸點位置就有了接觸,電阻發生變化,在X和Y兩個方向上產生信號,然后送觸摸屏控制器??刂破鱾蓽y到這一接觸并計算出(X,Y)的位置。
而本實驗中使用的TSC2046是一種典型的電阻式觸摸屏,其采用的是逐次逼近型模數轉換器(SAR ADC),包含了采樣/保持、模數轉換、串口數據 輸出等功能。同時芯片集成有一個2.5V的內部參考電壓源、溫度檢測電路,工作時使用外部時鐘。TSC2046可以單電源供電,電源電壓范圍為 2.7V~5.5V。參考電壓值直接決定ADC 的輸入范圍,參考電壓可以使用內部參考電壓,也可以從外部直接輸入1V~VCC 范圍內的參考電壓(要求外部參考電壓源輸出阻抗低)。X、Y、Z、VBAT、Temp和 AUX模擬信號經過片內的控制寄存器選擇后進入ADC,ADC可以配置為單端或差分模式。選擇VBAT、Temp和AUX時應該配置為單端模式;作為觸摸屏應用時,應該配置為差分模式,這可有效消除由于驅動開關的寄生電阻及外部的干擾帶來的測量誤差,提高轉換精度。
其基本控制方式為:
首先通過SSI串行接口向TSC2046發送8位控制字(DIN),設置需要數模轉換的信號(X、Y、Z、VBAT、Temp和 AUX等)和精度等,延時一個時鐘周期后可以通過SSI接口讀取相應的模擬信號數字化后的數數值,具體時序如圖20-3所示。
發送給TSC2046的8位控制字的設置方式可以根據具體情況進行選擇。通過8位控制字可以選擇ADC的分辨率,即選擇是8位分辨率還是12位分辨率。當設置為12位分辨率時得SSI數字接口如圖20-3所示,而8位分辨率的傳輸時序基本類似。
圖20-3 SSI數字接口時序
3. 程序設計
3.1 總體架構
整個程序有5個模塊構成,如圖 20 4所示: 1. TFT是頂層模塊,實例化各子模塊并連接各子模塊。 2. ping模塊主要負責液晶屏的控制與顯示。 3. touch模塊負責控制和讀取觸摸屏上面的坐標值。 4. data2disp模塊負責輸入鍵值的譯碼,因為要分別對X坐標和Y坐標進行譯碼,而每一個坐標均需要2個七段數碼管,所以程序中使用了4個data_2_disp模塊。 5. U1模塊是PLL模塊,產生屏幕顯示所需要的10MHz和5MHz的時鐘。
圖20-4 程序總體架構
3.2 液晶顯示模塊ping (ping.v)
Ping模塊的基本思路為:首先對顯示控制芯片ILI9326進行初始設置,然后將存儲在Flash內的圖像數據寫入ILI9326中,將圖像顯示在液晶屏上。
該程序的接口主要分為兩個部分,一部分是液晶屏接口部分,另一部分是Flash接口部分。 Ping模塊的接口如下:
iRst //全局異步復位iClk50 //全局時鐘 50Mhz//液晶屏接口oRst //液晶屏異步復位oCs_TFT //液晶屏片選信號,低電平有效,只有在片選信號有效時,//才能對液晶屏進行操作oRs //在對液晶屏控制芯片進行配置期間,該信號用于區分數據線上是寄//存器編號還是要向該寄存器寫入的數據oWr //操作液晶屏控制芯片的時鐘信號,上升沿有效oData //16位寬的數據線 //Flash接口FL_DQ //Flash 數據接口FL_CE_N //Flash片選信號FL_ADDR //Flash地址信號FL_OE_N //Flash輸出使能FL_WE_N //Flash輸入使能FL_RST_N //Flash復位FL_RY_BY //Flash忙指示信號
Ping模塊中的主要狀態機為State,state的狀態轉移圖如圖 20 5所示。
圖20-5 ping模塊內的State狀態機
狀態機的跳轉主要由計數器counter來進行控制。在counter的不同數值對應不同時間整個程序進入不同狀態,具體跳轉條件見程序。
程序一共有3個狀態:WAIT、CONFIG和WRITEDATA:
WAIT狀態:有兩個可能程序處于WAIT狀態時間,第一是上電后需要延時,因為液晶屏點亮等操作需要對電容等充電,在上電后程序出WAIT狀態等待系統充電穩定。第二就是在配置ILI9326周期內,如果某些配置后同樣需要ILI9326穩定一段時間后才能接著向下配置,此時程序也需要進入WAIT狀態。
CONFIG狀態:當程序處于CONFIG狀態,程序從保存配置文件的內部ROM中讀取配置數據,對ILI9326進行配置。配置內容參看文件displayData.hex。
WRITEDATA狀態:主要是在配置完成后,從FLASH內讀取待顯示的數據寫入ILI9326的GRAM內,控制液晶屏的顯示內容。完成顯示數據的讀寫后,程序進入WAIT,直至手動復位。具體程序如下所示:
always@(posedge clk_sys) beginif(counter<=start_size + 1000) begin
State <= WAIT; //在start_size + 1000個時鐘周期內,為上電延時
color <= 1'b0;
end
else if(
((start_size + 1000<counter)&(counter<=start_size + 1008))
|
((start_size + 1108<counter)&(counter<=start_size + 1150))
|
((start_size + 2150<counter)&(counter<=start_size + 2182))
|
((start_size + 3182<counter)&(counter<=start_size + 3184))
|
((start_size + 4184<counter)&(counter<=start_size + 4189))
) //Write_Register(0x00, 0x00000);
beginState <= CONFIG; //在start_size + 1000到start_size + 4190時鐘周//期內狀態在不停在WAIT和CONFIG之間跳轉
//而在處于CONFIG狀態時間,程序對液晶屏進//行配置color <= 1'b0;
end
else if(
((start_size + 1008<counter)&(counter<=start_size + 1208))
|
((start_size + 1150<counter)&(counter<=start_size + 2150))
|
((start_size + 2182<counter)&(counter<=start_size + 3182))
|
((start_size + 3184<counter)&(counter<=start_size + 3184))
) //delayms(20);//{time, 0010, ms);
beginState <= WAIT; //在start_size + 1000到start_size + 4190時鐘周//期內狀態在不停在WAIT和CONFIG之間跳轉
//而在處于WAIT狀態時間,程序在等待液晶屏//的延時動作。
color <= 1'b0;
end
else if( (counter > start_size + 4190) & (counter<All_Size)) beginState <= WRITEDATA;//在此期間程序從FLASH內讀取數據,//GRAM內寫入數據color <= 1'b1;
end
else begin
State <= WAIT;//進入最后的休眠狀態。
color <= 1'b0;
endend
end
end
當處于CONFIG狀態時,程序從內部ROM(registerData)存儲器中讀取出配置文件,該ROM地址生成程序如下所示:always@(negedge clk_sys or negedge oRst)begin
if(!oRst)
address <= 7'b0;
else if(State == CONFIG)//處于CONFIG狀態,ROM地址自動增加
address <= address + 1'b1;
else
address <= address; end
Flash接口時序控制程序如下所示:assign FL_WE_N = 1'b1; //實驗僅僅需要讀取Flash,所以該信號一直拉高assign FL_RST_N = iRst; //Flash復位信號assign FL_CE_N = 1'b0; //片選信號總是有些assign FL_OE_N = 1'b0; //讀輸出總是有效
而當程序處于WRITEDATA狀態,也就是讀取存儲在FLASH內部的圖像數據向TFT屏寫入的狀態時,其FLASH地址需要不斷增加,程序如下所示:always@(negedge flashclk or negedge oRst) begin //生成Flash地址信號
if(!oRst) begin
FL_ADDR <= 25'b0;
end
else begin if(color_d == 1'b1) // color_d 為color的一個時鐘延時,而color在WRITEDATA//狀態被拉低,也就是程序處于WRITEDATA狀態時//Flash地址自動增加begin FL_ADDR <= FL_ADDR + 1'b1;
end
else
FL_ADDR <= FL_ADDR;
endend reg [7:0] FL_DQ_d;always@(negedge flashclk or negedge oRst) begin //讀取Flash信號
if(!oRst) begin
FL_DQ_d <= 8'b0;
end
else
FL_DQ_d <= FL_DQ;end
程序中有一點時序需要注意,那就是GRAM位寬為16位,而Flash的位寬為8位,所以讀取Flash的時鐘需要是寫入GRAM的時鐘速率的兩倍。將讀取出來的兩個8位Flash數據合并寫入GRAM內。
其對應的時鐘信號生成程序如下所示:
//分頻以產生系統時鐘wire clk_sys;//5MHz wire flashclk;//10MHz
Pll U1(.inclk0(iClk50),
.c0(flashclk),
.c1(clk_sys));
3.3 觸摸屏touch模塊(touch.v)
觸摸屏touch模塊檢測觸點坐標的基本原理是:等待觸摸屏送出IRQ終端信號,在檢測到終端信號后,向觸摸屏控制芯片TSC2046寫入控制字,在寫入控制字后通過SSI接口讀取相應觸點的x、y坐標位置,并將坐標位置顯示在7段數碼管上。
觸摸屏主要有六個信號:CS、DCLK、DIN、BUSY、DOUT和IRQ,在檢測到中斷IRQ后,通過DOUT輸出控制字,然后通過DIN接收坐標位置;CS為片選信號,DCLK為訪問時鐘;在輸出控制字后,觸摸屏置BUSY為高一個時鐘周期,表示觸摸屏正忙。 觸摸屏模塊touch的數據流如圖20-6所示。
圖20-6 觸摸屏程序框圖
Ping模塊的接口分兩部分:一部分是與觸摸屏控制芯片的接口,一部分是與顯示坐標數據的8段數碼管接口。與觸摸屏的接口如下:
input IRQ; //觸摸屏產生的中斷信號,有觸摸時IRQ為低。input iBusy; //觸摸屏工作中指示信號,為高時表示觸摸屏忙。input Din; //從觸摸屏輸入到FPGA的坐標位置數據。output Dclk; //接口時鐘。output Dout; //FPGA向觸摸屏發送的控制信號。output oCs; //觸摸屏片選信號。與顯示坐標數據的7段數碼管有關的引腳如下:
output [7:0]HEX_sel; //七段數碼管片選信號線。output [7:0]HEX_seg; //數碼管顯示的數據。
Touch模塊主要受狀態機State控制,其狀態轉移圖如圖 20-7所示。
圖20-7 觸摸屏程序狀態機
State有XCONFIG、XDATA、YCONFIG和YDATA4個狀態:
X_CONFIG狀態:對TSC2046進行設置,以測試X方向的坐標。
X_DATA狀態:讀取TSC2046送來的X方向坐標值。
Y_CONFIG狀態:對TSC2046進行設置,以測試Y方向的坐標。
Y_DATA狀態:讀取TSC2046送來的Y方向坐標值。
狀態機的狀態轉移由計數器counter來進行控制。在初始時,State處于Y_DATA,而當IRQ被拉低期間,counter每個時鐘自動增加,從而驅動狀態機發生跳轉以讀取x、y坐標,并將坐標顯示在八段數碼管上。當觸摸屏受到觸發時IRQ信號被拉低,一般情況下拉低的周期足夠完成狀態機的跳轉(因為FPGA運轉很快,而人的操作則相對緩慢),完成坐標位置的讀寫。具體程序如下:
reg [2:0] state;
reg [11:0] counter;
always@(negedge Dclk or negedge iRst) begin
if(!iRst)
counter <= 12'b0;
else beginif(IRQ==1'b1)
counter <= 12'b0;
else //在IRQ為低時,表示有觸摸,counter開始工作。
counter <= counter + 1'b1;
end
end always@(posedge Dclk or negedge iRst) begin
if(!iRst) begin
state <= Y_DATA;
end
else begin
if((counter>=3000) && (counter < 3008))
state <= X_CONFIG; //發送命令:讀取x坐標值
else if((counter >=3008) && (counter <3024))
state <= X_DATA; //讀取x坐標值
else if((counter >=3024) && (counter <3032))
state <= Y_CONFIG; //發送命令:讀取y坐標值
else
state <= Y_DATA; //讀取y坐標值
endend
需要說明的是,因為該接口時鐘為百K量級,所以觸摸屏程序的時鐘是通過內部觸發器產生,沒有統一到整個系統時鐘域內。
4. 運行結果
從SignalTap中觀測觸摸屏程序中讀取坐標值的信號如圖 20 8所示,其中在XCONFIG、XDATA、YCONFIG、和YDATA 有效期間,Din和Dout在Dclk時鐘控制下對TSC2046進行配置和讀取。其中在XCONFIG有效期間程序向TSC2046發送的數據為8'b00011011,而在YCONFIG有效時程序向TSC2046發送的數據為8' b00011001。
圖20-8 運行結果
5. 演示程序文件說明
文件名 | 功能 |
TFT.v | 頂層模塊。 |
ping.v | 液晶屏控制模塊。 |
touch.v | 控制和讀取觸摸屏上面的坐標值。 |
data_2_display.v | 顯示觸點坐標。 |
displayData.hex | 該文件存儲液晶屏芯片ILI9326的配置數據, 16位寬,奇數地址存儲ILI9326的寄存器地址,偶數地址存儲待向該地址寫入配置數據。 |
6. 演示程序使用
演示設備:核心板、擴展板。
演示方法:首先需要用Nios將圖像“tft屏顯示圖像.bmp”燒到Flash中,起始地址為0x0。然后把程序下載到開發板上之后,液晶屏上將顯示燒入的圖像。如果FLASH內沒有燒入圖像,液晶屏上將液晶花屏。用手指觸摸液晶屏,可以看到在8段數碼上顯示當前觸點的坐標值。
評論