音频电平vu显示表软件下载_正点原子开拓者 Nios II资料连载第十章MCU TFT-LCD图片显示实验...
1)實驗平臺:正點原子開拓者FPGA 開發板
2)摘自《開拓者 Nios II開發指南》關注官方微信號公眾號,獲取更多資料:正點原子
3)全套實驗源碼+手冊+視頻下載地址:http://www.openedv.com/docs/index.html
第十章MCU TFT-LCD圖片顯示實驗
TFT LCD是Thin Film Transistor Liquid Crystal Display的縮寫,即薄膜場效應晶體
管液晶顯示器,即每個液晶像素點都是由集成在像素點后面的薄膜晶體管來驅動,這樣不僅
提高了顯示屏的響應速度,同時還可以精確控制顯示色階,做到高速度、高彩色保真度、高
亮度、高對比度和高分辨率。TFT LCD能夠低電壓驅動,具有功耗低,使用壽命長等特點。其
顯示應用范圍覆蓋了從1英寸至40英寸范圍內的所有顯示器以及投影大平面,是全尺寸顯示終
端。另外TFT LCD的環保特性好,無輻射、無閃爍,是設計用戶友好型圖形界面的優良載體。
本章我們將使用Nios II驅動TFT LCD的顯示。
本章包括以下幾個部分:
10.1 簡介
10.2 實驗任務
10.3 硬件設計
10.4 軟件設計
10.5 下載驗證
簡介
ATK-4.3’TFTLCD是ALIENTEK推出的一款高性能4.3寸電容觸摸屏模塊。該模塊屏幕分辨
率為800*480,16位真彩顯示,采用Intel8080接口(MCU接口),該芯片自帶GRAM,無需外加
驅動器,因而任何單片機,都可以輕易驅動。此外ALIENTEK還推出了一款具有相同接口和分
辨率的TFTLCD——ALIENTEK第二代7寸TFTLCD——ATK-7’ TFTLCD-V2.2,ATK-7’TFTLCD V2
模塊具有屏幕分辨率高(800*480),支持16/18/24位真彩顯示、支持8/9/12/16位數據格
式、支持開窗顯示等特色。當然了,ALIENTEK也提供了3.5寸和2.8寸的TFTLCD,以滿足不同
應用的需求。
雖然這些不同尺寸的TFTLCD的LCD驅動器芯片不同(關于各尺寸的TFTLCD的詳細介紹可參
見提供的增值資料部分),如7寸的ATK-7’ TFTLCD-V2.2采用的是SSD1963、4.3寸的ATK-
4.3’TFTLCD采用的是NT35510等,但都采用Intel8080接口。Intel8080接口是一種并行接口
協議,由Intel公司提出,被廣泛應用于各類液晶顯示器。下面我們了解一下Intel8080接口
的操作時序。
為了更好的了解Intel8080接口,我們先來看一下TFTLCD模塊的接口原理圖,如下圖所
示:
圖10.1.1 TFTLCD模塊接口原理圖
各引腳的詳細描述如下表所示:
表格10.1.1 TFTLCD模塊接口引腳功能描述
在Intel8080并口模式下,LCD驅動需要用到的信號線如下:
CS:LCD片選信號。
WR:向LCD寫入數據。
RD:從LCD讀取數據。
D[15:0]:16位雙向數據線(RGB565)。
RST:硬復位LCD。
RS:命令/數據標志(0,讀寫命令;1,讀寫數據)。
除了以上信號,我們一般還需要用到這2個信號:RST和BL_CTR,其中RST是液晶的硬復位
腳,低電平有效,用于復位TFTLCD的驅動芯片如NT35510,實現液晶復位,在每次初始化之
前,我們建議先執行硬復位,再做初始化。BL_CTR則是背光控制引腳,高電平有效,即高電平時點亮背光,另外可以用PWM控制BL_CTR腳,從而控制背光的亮度。
Intel8080并口讀/寫的過程為:拉低片選CS,選中驅動芯片,并根據要寫入/讀取的數據
的類型,設置RS為高(數據)/低(命令),然后我們根據是讀數據還是寫數據設置RD/WR為
低,即當寫數據時,WR設為低電平,RD保持高電平,當讀數據時,RD設為低電平,WR保持高
電平,然后:當WR由低到高時,TFTLCD鎖存數據。寫時序的時序圖如下:
圖10.1.2 8080 并口寫時序圖
從上圖可以看到,在寫數據時,讀信號RD保持高電平,RS根據寫數據的類型設置為高或
低電平(高:數據,低:命令),當WR為低電平時,往D0~D15寫數據,當WR由低電平變成高
電平時,TFTLCD鎖存數據。
讀時序的時序圖如下:
圖 10.1.3 8080 并口讀時序圖
從上圖可以看到,在讀數據時,寫信號WR保持高電平,當RD為低電平時,TFTLCD控制數
據總線D0~D15,當RD由低電平變成高電平時,主機讀取數據。
Intel8080接口方式下,控制腳的信號狀態所對應的功能如下表所示:
圖 10.1.4 控制腳信號狀態功能表
在Intel8080接口下讀數據操作的時候,我們有時候(例如讀顯存的時候)需要一個假讀
命(Dummy Read),以使得微控制器的操作頻率和顯存的操作頻率相匹配。在讀取真正的數
據之前,由一個的假讀的過程。這里的假讀,其實就是第一個讀到的字節丟棄不要,從第二
個開始,才是我們真正要讀的數據。一個典型的讀顯存的時序圖,如下圖所示:
圖10.1.5 讀顯存時序圖
可以看到,在發送了列地址之后,開始讀數據,第一個是Dummy Read,也就是假讀,我
們從第二個開始,才算是真正有效的數據
現在我們以ATK-4.3’TFTLCD為例,看一下Intel8080總線讀寫時序的具體參數,如下圖
所示:
圖10.1.6 Intel總線讀寫時序
圖中各時間參數見表10.1.3 所示:
圖 10.1.7 Intel8080 并口讀寫時間參數
從上表可以看出,模塊的寫周期是非常快的,只需要33ns即可,理論上最大速度可以達
到:3030W像素每秒,即刷屏速度可以達到每秒鐘78.9 幀。模塊的讀取速度相對較慢:讀ID
(RD(ID))周期是160ns,讀顯存周期是400ns(RD(FM))。
并行接口模式就介紹到這里,現在我們以4.3寸的ATK-4.3’TFTLCD的LCD驅動芯片
NT35510為例進行介紹,其它的驅動芯片基本都類似,我們就不詳細闡述了。
NT35510自帶LCD GRAM(480*864*3字節),并且最高支持24位顏色深度(1600萬色),
不過,我們一般使用16位顏色深度(65K色),RGB565格式,這樣,在16位模式下,可以達到
最快的速度。
在16位模式下,NT35510采用RGB565格式存儲顏色數據,此時NT35510的低16位數據總線
(高8位沒有用到)與MCU(這里指Nios II)的16位數據線以及24位LCD GRAM的對應關系如下
表所示:
圖10.1.8 16位總線與24位GRAM對應關系
從上表可以看出,NT35510的24位GRAM與16位RGB565的對應關系,其實就是分別將高位的
R、G、B數據,搬運到低位做填充,“湊成”24位,再顯示。
MCU的16位數據中,最低5位代表藍色,中間6位為綠色,最高5位為紅色。數值越大,表
示該顏色越深。另外,特別注意NT35510的指令是16位寬,數據除了GRAM讀寫的時候是16位
寬,其它都是8位寬的(高8位無效),這個和ILI9320等驅動器不一樣,必須加以注意。
接下來,我們介紹一下NT35510的幾個重要命令,因為NT35510的命令很多,我們這里就
不全部介紹了,有興趣的讀者可以查看NT35510的datasheet。里面對這些命令有詳細的介
紹。我們將介紹:0XDA00,0XDB00,0XDC00,0X3600,0X2A00~0X2A03,0X2B00~0X2B03,
0X2C00,0X2E00 等14條指令。
首先來看指令:0XDA00,0XDB00,0XDC00,這三條指令是讀ID1,ID2,ID3指令,也就是
用于讀取LCD控制器的ID,該指令如下表所示
圖10.1.9 讀ID指令描述
從上表可以看出,LCD讀ID,總共由3個指令(0XDA00、0XDB00和0XDC00)構成,每個指
令輸出一個參數,每個ID以8位數據(即指令后的參數)的形式輸出(高8位固定為0),不過
這里輸出的ID,并不包含5510這樣的字樣,僅有指令0XDB00會輸出ID:0X80,其他兩個指令
讀到的ID都是0。將3個指令的輸出,組合在一起,可以得到NT35510的ID為:0X8000。
通過這個ID,即可判別所用的LCD驅動器是什么型號,這樣,我們的代碼,就可以根據控
制器的型號去執行對應驅動IC的初始化代碼,從而兼容不同驅動IC的屏,使得一個代碼支持
多款LCD。
接下來看指令:0X3600,這是存儲訪問控制指令,可以控制NT35510存儲器的讀寫方向,
簡單的說,就是在連續寫GRAM的時候,可以控制GRAM指針的增長方向,從而控制顯示方式
(讀GRAM也是一樣)。該指令如表所示:
圖10.1.10 0X3600 指令描述
從上表可以看出,0X3600指令后面,緊跟一個參數,這里我們主要關注:MY、MX、MV這三個位,
通過這三個位的設置,我們可以控制整個 NT35510 的全部掃描方向,如下表所示:
圖10.1.11 MY、MX、MV設置與LCD掃描方向關系表
這樣,我們在利用 NT35510 顯示內容的時候,就有很大靈活性了,比如顯示 BMP 圖片,BMP
解碼數據,就是從圖片的左下角開始,慢慢顯示到右上角,如果設置 TFTLCD掃描方向為從左
到右,從下到上,那么我們只需要設置一次坐標,然后就不停的往LCD填充顏色數據即可,這
樣可以大大提高顯示速度。
接下來看指令:0X2A00~0X2A03,這幾個是列地址設置指令,在從左到右,從上到下的掃
描方式(默認)下面,該指令用于設置橫坐標(x 坐標),該指令如下 表 所示:
圖10.1.12 0X2A00~0X2A03指令描述
在默認掃描方式時,這4個指令用于設置x坐標,每條指令帶有1個參數,實際上總共就是
2個坐標值:SC和EC(SC和EC都是16位的,由2個8位組成),即列地址的起始值和結束值,SC
必須小于等于EC,且0≤SC/EC≤479。一般在設置x坐標的時候,我們只需要0X2A00和0X2A01
兩條指令即可,也就是設置SC即可,因為如果EC沒有變化,我們只需要設置一次即可(在初
始化NT35510的時候設置),從而提高速度。
與0X2A00~0X2A03指令類似,指令:0X2B00~0X2B03,是頁地址設置指令,在從左到右,
從上到下的掃描方式(默認)下面,該指令用于設置縱坐標(y坐標)。該指令如下 表 所
示:
圖10.1.13 0X2B00~0X2B03指令描述
在默認掃描方式時,這4個指令用于設置y坐標,每條指令帶有1個參數,實際上總共就是
2個坐標值:SP和EP(SP和EP都是16位的,由2個8位組成),即頁地址的起始值和結束值,SP
必須小于等于EP,且0≤SP/EP≤799。一般在設置y坐標的時候,我們只需要帶0X2B00和
0X2B01兩條指令即可,也就是設置SP即可,因為如果EP沒有變化,我們只需要設置一次即可
(在初始化NT35510的時候設置),從而提高速度。
接下來看指令:0X2C00,該指令是寫GRAM指令,在發送該指令之后,我們便可以往LCD的
GRAM里面寫入顏色數據了,該指令支持連續寫,指令描述如下表所示:
圖10.1.14 0X2C00指令描述
從上表可知,在收到指令 0X2C00之后,數據有效位寬變為16位,我們可以連續
寫入LCD GRAM值,而GRAM的地址將根據MY/MX/MV設置的掃描方向進行自增。例如:假
設設置的是從左到右,從上到下的掃描方式,那么設置好起始坐標(通過SC,SP設
置)后,每寫入一個顏色值,GRAM地址將會自動自增1(SC++),如果碰到EC,則回
到 SC,同時SP++,一直到坐標:EC,EP結束,其間無需再次設置的坐標,從而大大
提高寫入速度。
最后,來看看指令:0X2E00,該指令是讀 GRAM 指令,用于讀取 NT35510 的顯存(GRAM),該指令在NT35510的數據手冊上面的描述是有誤的,真實的輸出情況如
下表所示:
表10.1.11 0X2E00指令描述
該指令用于讀取GRAM,如上表所示,NT35510在收到該指令后,第一次輸出的是dummy數
據,也就是無效的數據,第二次開始,讀取到的才是有效的GRAM數據(從坐標:SC,SP開
始),輸出規律為:每個顏色分量占8個位,一次輸出2個顏色分量。比如:第一次輸出是
R1G1,隨后的規律為:B1R2→G2B2→R3G3→B3R4→G4B4→R5G5...以此類推。如果我們只需要
讀取一個點的顏色值,那么只需要接收到參數3即可,如果要連續讀取(利用GRAM地址自增,
方法同上),那么就按照上述規律去接收顏色數據。
以上,就是操作NT35510常用的幾個指令,通過這幾個指令,我們便可以很好的控制
NT35510 顯示我們所要顯示的內容了。
圖10.1.15 TFTLCD使用流程
任何LCD,使用流程都可以簡單的用以上流程圖表示。其中硬復位和初始化序列,只需要
執行一次即可。而畫點流程就是:設置坐標→寫GRAM指令→寫入顏色數據,然后在LCD 上
面,我們就可以看到對應的點顯示我們寫入的顏色了。讀點流程為:設置坐標→讀GRAM指令
→讀取顏色數據,這樣就可以獲取到對應點的顏色數據了。
以上只是最簡單的操作,也是最常用的操作,有了這些操作,一般就可以正常使用
TFTLCD了。接下來,我們開始利用Nios II驅動TFTLCD并使其顯示。
實驗任務
本章我們使用Nios II驅動TFTLCD,并使其顯示圖片,圖片上疊加字符顯示。
硬件設計
本章實驗的硬件框架如下圖所示:
圖10.3.1 TFTLCD顯示實驗的硬件框架圖
頂層代碼如下:
1 module qsys_lcd(
2 //module clock
3 input sys_clk , //系統時鐘,50Mhz
4 input sys_rst_n , //系統復位,低電平有效
5
6 //SDRAM interface
7 output sdram_clk , //SDRAM 芯片時鐘
8 output sdram_cke , //SDRAM 時鐘有效
9 output sdram_cs_n , //SDRAM 片選
10 output sdram_ras_n, //SDRAM 行有效
11 output sdram_cas_n, //SDRAM 列有效
12 output sdram_we_n , //SDRAM 寫有效
13 output [ 1:0] sdram_ba , //SDRAM Bank地址
14 output [12:0] sdram_addr , //SDRAM 行/列地址
15 inout [15:0] sdram_data , //SDRAM 數據
16 output [ 1:0] sdram_dqm , //SDRAM 數據掩碼
17
18 //EPCS FLASH interface
19 output epcs_dclk , // EPCS 時鐘信號
20 output epcs_sce , // EPCS 片選信號
21 output epcs_sdo , // EPCS 數據輸出信號
22 input epcs_data0, // EPCS 數據輸入信號
23
24 //MCU LCD interface
25 inout [15:0] mlcd_data , // LCD 數據信號
26 output mlcd_bl , // LCD 背光信號
27 output mlcd_cs_n , // LCD 片選信號
28 output mlcd_wr_n , // LCD 寫信號
29 output mlcd_rd_n , // LCD 讀信號
30 output mlcd_rs , // LCD 命令/數據信號
31 output mlcd_rst_n // LCD 復位信號
32 //user interface
33
34 );
35
36 //wire define
37 wire clk_100m; //SDRAM 控制器時鐘
38 wire rst_n ; //系統復位信號
39 wire locked ; //PLL輸出穩定標志
40
41 //*****************************************************
42 //** main code
43 //*****************************************************
44
45 //待PLL輸出穩定之后,停止系統復位
46 assign rst_n = sys_rst_n & locked;
47
48 //例化PLL
49 pll_clk u_pll_clk(
50 .areset (~sys_rst_n),
51 .inclk0 (sys_clk ),
52 .c0 (clk_100m ),
53 .c1 (sdram_clk ),
54 .locked (locked )
55 );
56
57 //例化Nios2系統模塊
58 nios2os u_nios2os (
59 .clk_clk (clk_100m ), // 時鐘100M
60 .reset_reset_n (rst_n ), // 復位信號
61 .sdram_addr (sdram_addr ), // SDRAM 行/列地址
62 .sdram_ba (sdram_ba ), // SDRAM Bank地址
63 .sdram_cas_n (sdram_cas_n), // SDRAM 列有效
64 .sdram_cke (sdram_cke ), // SDRAM 時鐘有效
65 .sdram_cs_n (sdram_cs_n ), // SDRAM 片選
66 .sdram_dq (sdram_data ), // SDRAM 數據
67 .sdram_dqm (sdram_dqm ), // SDRAM 數據掩碼
68 .sdram_ras_n (sdram_ras_n), // SDRAM 行有效
69 .sdram_we_n (sdram_we_n ), // SDRAM 寫有效
70 .epcs_dclk (epcs_dclk ), // EPCS 時鐘信號
71 .epcs_sce (epcs_sce ), // EPCS 片選信號
72 .epcs_sdo (epcs_sdo ), // EPCS 數據輸出信號
73 .epcs_data0 (epcs_data0 ), // EPCS 數據輸入信號
74 .mlcd_data_export (mlcd_data ), // LCD 數據信號
75 .mlcd_cs_n_export (mlcd_cs_n ), // LCD 片選信號
76 .mlcd_wr_n_export (mlcd_wr_n ), // LCD 寫信號
77 .mlcd_rd_n_export (mlcd_rd_n ), // LCD 讀信號
78 .mlcd_rst_n_export(mlcd_rst_n ), // LCD 復位信號
79 .mlcd_rs_export (mlcd_rs ), // LCD 命令/數據信號
80 .mlcd_bl_export (mlcd_bl ) // LCD 背光信號
81 );
82
83 endmodule
頂層代碼主要實現PLL和Nios II系統模塊的例化。
軟件設計
創建好軟件工程后,我們將hello_world.c更改為qsys_lcd.c,并在qsyslcd的應用工程
下新建一個文件夾,命名為drive,里面存放TFTLCD的驅動代碼文件和相應的字體文件,文件
夾結構如下圖所示:
圖 10.4.1 文件結構
其中font.h是由取模軟件“PCtoLCD2002”生成的不同字體大小的ASCII碼字模文件,除
了支持0~9的10個數字字符和26個英文字母的大小寫ASCII字符集外,還支持如下字符
集: !"#$%&'()*+,-./:;<=>?@ []^_`{|}~,能顯示四種字符點陣大小:12*12、16*16、
24*24和32*32。mculcd.h是TFTLCD驅動文件的頭文件,mculcd.c是TFTLCD驅動文件的c文件。
由于這兩個文件的代碼較多,我們這里就不貼出來了,只針對幾個重要的函數進行講解。
我們先介紹一下mculcd.h里面的一個重要結構體:
//LCD重要參數集
typedef struct
{
u16 width; //LCD 寬度
u16 height; //LCD 高度
u16 id ; //LCD ID
u8 dir; //橫屏還是豎屏控制:0,豎屏;1,橫屏
u16 wramcmd; //開始寫gram指令
u16 setxcmd; //設置x坐標指令
u16 setycmd; //設置y坐標指令
}_lcd_dev;
//LCD參數
_lcd_dev lcddev; //管理LCD重要參數
該結構體用于保存一些TFTLCD重要參數信息,比如TFTLCD的長寬、LCD ID(驅動IC型
號)、LCD橫豎屏狀態等,這個結構體雖然占用了十幾個字節的內存,但是卻可以讓我們的驅
動函數支持不同尺寸的LCD,同時可以實現LCD橫豎屏切換等重要功能,所以還是利大于弊
的。有了以上了解,下面我們開始介紹mculcd.c里面的一些重要函數。
//LCD延遲函數,單位毫秒
void delay_ms(u32 n)
{
usleep(n*1000);
}
//LCD寫命令
void LCD_WR_CMD(u16 Cmd)
{
IOWR_ALTERA_AVALON_PIO_DIRECTION(MLCD_DATA_BASE,0xFFFF); // 設置DATA PIO為輸出
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_RS_BASE,0); // 拉低RS
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_RD_N_BASE,1); // RD設為高電平
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_WR_N_BASE,0); // 拉低WR
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_DATA_BASE,Cmd); // 往DATA端口寫命令
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_WR_N_BASE,1); // 拉高WR
}
//LCD寫數據
void LCD_WR_DATA(u16 Data)
{
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_RS_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_RD_N_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_WR_N_BASE,0);
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_DATA_BASE,Data);
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_WR_N_BASE,1);
}
//LCD讀數據
u16 LCD_RD_DATA()
{
u16 read_data = 0;
IOWR_ALTERA_AVALON_PIO_DIRECTION(MLCD_DATA_BASE,0x0000); // 設置DATA PIO為輸入
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_RS_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_RD_N_BASE,0);
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_WR_N_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_RD_N_BASE,1);
read_data = IORD_ALTERA_AVALON_PIO_DATA(MLCD_DATA_BASE);
return read_data;
}
//LCD寫寄存器數據
void LCD_WriteReg(u16 LCD_Reg,u16 LCD_RegValue)
{
LCD_WR_CMD(LCD_Reg); // 寫入的寄存器
LCD_WR_DATA(LCD_RegValue); // 寫入的數據
}
//LCD讀寄存器
u16 LCD_ReadReg(u16 LCD_Reg)
{
LCD_WR_CMD(LCD_Reg); // 要讀取的寄存器
usleep(5); // 延時5us
return LCD_RD_DATA(); // 返回讀取的數據
}
//開始寫GRAM
void LCD_WriteRAM_Prepare(void)
{
LCD_WR_CMD(lcddev.wramcmd);
}
//LCD寫GRAM
//RGB_Code:顏色值
void LCD_WriteRAM(u16 RGB_Code)
{
LCD_WR_DATA(RGB_Code); //寫十六位GRAM
}
從該代碼中我們可以看出,寫命令和讀寫數據完全符合我們的時序圖。需要注意的是,
由于DATA PIO為雙向的,所以在讀寫命令或數據之前需要先設置其方向,否則讀寫不成功。
接下來我們介紹的是畫點函數。該函數實現代碼如下:
//畫點
//x,y:坐標
//POINT_COLOR:此點的顏色
void LCD_DrawPoint(u16 x,u16 y)
{
LCD_SetCursor(x,y); //設置光標位置
LCD_WriteRAM_Prepare(); //開始寫入GRAM
LCD_WR_DATA(POINT_COLOR);
}
該函數實現比較簡單,就是先設置坐標,然后往坐標寫顏色。其中POINT_COLOR是我們定
義的一個全局變量,用于存放畫筆顏色,順帶介紹一下另外一個全局變量:BACK_COLOR,該
變量代表LCD的背景色。LCD_DrawPoint函數雖然簡單,但是至關重要,其他幾乎所有上層函
數,都是通過調用這個函數實現的。
有了畫點函數,自然就可以用畫點函數顯示字符串。顯示字符串函數如下:
//顯示字符串
//x,y:起點坐標
//width,height:區域大小
//size:字體大小
//*p:字符串起始地址
//mode:疊加方式(1)還是非疊加方式(0)
void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 mode,u8 *p)
{
u8 x0=x;
width+=x;
height+=y;
while((*p<='~')&&(*p>=' ')) { //判斷是不是非法字符!
if(x>=width) {
x=x0;
y+=size;
}
if(y>=height)
break;//退出
LCD_ShowChar(x,y,*p,size,mode);
x+=size/2;
p++;
}
}
字符串顯示函數可以設置顯示的位置x、y,和顯示字體的大小size,還可以以疊加方式
顯示,或者以非疊加方式顯示。疊加方式顯示多用于在顯示的圖片上再顯示字符。非疊加方
式一般用于普通的顯示。
TFTLCD最大的用處是顯示圖片,自然需要介紹一下圖片顯示函數,函數如下:
//x,y:起點坐標
//size:圖片大小
//LCD顯示圖片
void LCD_DisplayPic(u16 x,u16 y,u32 size,const u8 *pic)
{
u32 i;
LCD_SetCursor(x,y);
LCD_WriteRAM_Prepare(); //開始寫入GRAM
for(i=0; i < size; i++)
LCD_WR_DATA(pic[i*2]<<8 | pic[i*2+1]);
}
這里假設圖片經轉換后得到的頭文件數據類型是char類型,為8位,因為一個像素需要16
位(RGB565),所以需要合并兩個8位為16,如果圖片經轉換后得到的頭文件數據類型是16位
的,LCD_WR_DATA(pic[i*2]<<8 | pic[i*2+1])應改為LCD_WR_DATA(pic[i])。
最后,我們再介紹一下TFTLCD模塊的初始化函數MCULCD_Init,該函數先復位TFTLCD,然
后讀取TFTLCD控制器(驅動芯片)的型號,根據控制IC的型號執行不同的初始化代碼,由于
該函數代碼較長,我們摘錄部分如下:
//TFTLCD初始化
void MCULCD_Init(void)
{
//TFTLCD 復位
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_RST_N_BASE,0);
delay_ms(100);
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_RST_N_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_CS_N_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_RD_N_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_WR_N_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(MLCD_CS_N_BASE,0);
delay_ms(50);
//嘗試9341 ID的讀取
LCD_WR_CMD(0XD3);
lcddev.id=LCD_RD_DATA(); //dummy read
lcddev.id=LCD_RD_DATA(); //讀到0X00
lcddev.id=LCD_RD_DATA(); //讀取93
lcddev.id<<=8;
lcddev.id|=LCD_RD_DATA(); //讀取41
if(lcddev.id!=0X9341) //非9341,嘗試看看是不是NT35310
……
主函數部分的代碼如下:
1 #include <stdio.h>
2 #include <unistd.h>
3 #include "./drive/mculcd.h"
4 #include "pic01.h" //顯示的圖片
5
6 int main()
7 {
8 MCULCD_Init();
9 POINT_COLOR=MLCD_RED;
10
11 LCD_DisplayPic(0,0,lcddev.width * lcddev.height,gImage_pic01);
12
13 LCD_ShowString(30,50,300,30,24,1,"Welcome to PIONEER FPGA");
14 LCD_ShowString(30,80,400,30,24,1,"This is a TFT LCD test application");
15 LCD_ShowString(30,110,200,30,24,1,"ATOM@ALIENTEK");
16 LCD_ShowString(30,140,200,30,24,1,"2018/10/10");
17
18 return 0;
19 }
“pic01.h”是由Image2Lcd軟件轉換得到的圖片文件,該軟件我們在《開拓者FPGA開發
指南》的第四十章 SD卡圖片顯示實驗(VGA顯示)中已介紹其使用,這里我們再簡單的介紹
下使用步驟,按下圖箭頭指示的方向,首先打開選擇一幅分辨率為800*480的jpg或bmp格式的
圖片,圖片加載進來之后,在工具界面左側設置輸出數據類型為“C語言數據(*.c)”,掃描
模式為“垂直掃描”,輸出灰度為“16位真彩色”,最大寬度和高度分別為“800”和
“480”,選中“自右至左掃描”和“高位在前(MSB First)”。設置完成后在菜單欄中點
擊“保存”,并在彈出的界面中選擇C file(*.c;*.h)文件的保存路徑并輸入文件名,后綴
為.h,我們這里設置文件名為pic01.h。
圖 10.4.2 圖片轉換設置
代碼第17行的gImage_pic01是pic01.h中的數組,如下圖所示:
圖 10.4.3 轉換后得到的圖片數組
這里的字符顯示我們設置為疊加模式,當然了也可以設置為非疊加模式,疊加模式在圖
片上顯示字符效果好。
下載驗證
講完了軟件工程,接下來我們就將該實驗下載至我們的開拓者開發板進行驗證。
首先我們將4.3寸的ATK-4.3’TFTLCD與開發板上的MCU TFT LCD接口連接。再將下載器一
端連電腦,另一端與開發板上對應端口連接,最后連接電源線并打開電源開關。開拓者開發
板實物圖如下所示:
圖 10.5.1 開發板實物圖
接下來我們下載程序,驗證TFT LCD顯示功能。
我們在Quartus II軟件中將qsys_lcd.sof文件下載至我們的開拓者開發板,
qsys_lcd.sof下載完成后,我們還需要在Nios II SBT for Eclipse軟件中將qsys_lcd.elf文
件下載至我們的開拓者開發板,qsys_lcd.elf下載完成以后,我們的C程序將會執行在我們的
開拓者開發板上,運行結果如下圖所示。
圖 10.5.2 實驗結果圖
圖片上疊加顯示我們寫入的字符。至此,我們的TFT LCD顯示實驗就完成了。
總結
以上是生活随笔為你收集整理的音频电平vu显示表软件下载_正点原子开拓者 Nios II资料连载第十章MCU TFT-LCD图片显示实验...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nodejs爬虫实战(一):抽屉新热榜
- 下一篇: 如何使用python批量下载-如何用Py