【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗二十九:LCD模組
實驗二十九:LCD模組
據說Alinx 301支援 7”TFT,好奇的朋友一定疑惑道,它們3.2”TFT以及7”TFT等兩者之間究竟有何區別呢?答案很簡單,前者自帶控制器也有影象記憶體。換之,後者好似縮小版臺式的液晶,它除了介面以外什麼也沒有。
圖29.1 7”TFT的引腳。
如圖29.1所示,這隻7“TFT擁有840 * 480的解析度,應用VGA介面,所以左邊才有熟悉的 HSYNC以及 VYSNC訊號。LCD_CLOCK是畫素時鐘,最大為50Mhz,並且沒有下限。LCD_RED/GREEN/BLUE 為 18位RGB,顏色支援範圍是 218 = 262K。右邊的DE為Data Enable拉高表示資料輸入有效,LR/UD為掃描次序,例如自左向右,由高至下就是 2’b10,結果如表29.1所示:
表29.1 TFT的掃描次序。
LR | UD | 掃描次序 |
0 | 0 | 自右向左,由上至下 |
0 | 1 | 自右向左,由下至上 |
1 | 0 | 自左向右,由上至下 |
1 | 1 | 自左向右,由下至上 |
根據手冊,它支援兩種模式,MODE拉低表示傳統的VGA模式,MODE拉高則是DE模式。老實說,什麼是DE模式,筆者真有點搞不懂,手冊也沒有詳細註明,所以MODE訊號必須拉低。這隻7”TFT自帶背光,我們可以經由PWM訊號調節背光的亮度,具體內容請瀏覽手冊,我們一般都是常年拉高。
圖26.4 VGA時序。
如圖29.2所示,HSYNC以及VSYNC均為五段,具體長度如表29.2所示:
表29.2 顯示標準800 × 480。
訊號 | A | B | C | D | E |
VGA_HSYNC | 48 | 40 | 800 | 40 | 928 |
訊號 | O | P | Q | R | S |
VGA_VSYNC | 3 | 29 | 480 | 13 | 525 |
筆者曾前面說過,摺尺7”TFT應用VGA介面,驅動方法與實驗二十六差不多。所以說,懶惰的筆者就直接沿用實驗二十六的資源。
圖29.3 128×96大小的小可愛。
圖29.3是我們要顯示的小可愛 ... 啊,不管怎麼看,比卡丘最可愛了!完後,我們讓我們建模去吧。
圖29.4 LCD基礎模組的建模圖。
圖29.4是LCD基礎模組的建模圖,內容包括儲存模組以及的功能模組。相對PLL模組將時間分頻為25Mhz,因為畫素時鐘是任意的。
lcd_funcmod.v
圖29.5 LCD 功能模組。
圖29.5是LCD功能模組的建模圖,讀者可能很好奇控制模組去哪兒了?非呀,控制模組已經被整合進去了。
1. module lcd_funcmod
2. (
3. input CLOCK, RESET,
4. output LCD_CLOCK,
5. output LCD_HSYNC, LCD_VSYNC,
6. output [5:0]LCD_RED,LCD_GREEN,LCD_BLUE,
7. output LCD_DE,
8. output LCD_UD, LCD_LR,
9. output LCD_MODE,
10. output LCD_PWM,
11. output [13:0]oAddr,
12. input [15:0]iData
13. );
14. parameter SA = 11'd48, SB = 11'd40, SC = 11'd800, SD = 11'd40, SE = 11'd928;
15. parameter SO = 11'd3, SP = 11'd29, SQ = 11'd480, SR = 11'd13, SS = 11'd525;
16.
以上內容為相關的出入端宣告以及常量宣告。
17. reg [10:0]CH;
18. always @ ( posedge CLOCK or negedge RESET )
19. if( !RESET )
20. CH <= 11'd0;
21. else if( CH == SE -1 )
22. CH <= 11'd0;
23. else
24. CH <= CH + 1'b1;
25.
26. reg [9:0]CV;
27. always @ ( posedge CLOCK or negedge RESET )
28. if( !RESET )
29. CV <= 10'd0;
30. else if( CV == SS -1 )
31. CV <= 10'd0;
32. else if( CH == SE -1 )
33. CV <= CV + 1'b1;
34.
以上內容為列計數與行計數的周邊操作。
35. reg H;
36. always @ ( posedge CLOCK or negedge RESET )
37. if( !RESET )
38. H <= 1'b1;
39. else if( CH == SE -1 )
40. H <= 1'B0;
41. else if( CH == SA -1 )
42. H <= 1'b1;
43.
44. reg V;
45. always @ ( posedge CLOCK or negedge RESET )
46. if( !RESET )
47. V <= 1'b1;
48. else if( CV == SS -1 )
49. V <= 1'b0;
50. else if( CV == SO -1 )
51. V <= 1'b1;
52.
以上內容為列控制以及行控制的周邊操作。
53. parameter XSIZE = 8'd128, YSIZE = 8'd96, XOFF = 10'd0, YOFF = 10'd0;
54.
55. wire isX = ( (CH >= SA + SB + XOFF -1 ) && ( CH <= SA + SB + XOFF + XSIZE -1) );
56. wire isY = ( (CV >= SO + SP + YOFF -1 ) && ( CV <= SO + SP + YOFF + YSIZE -1) );
57. wire isReady = isX & isY;
58.
59. wire [31:0] x = CH - XOFF - SA - SB -1;
60. wire [31:0] y = CV - YOFF - SO - SP -1;
61.
以上內容為影象資訊的常量宣告,有效行列,以及地址轉換等即時宣告。
62. reg [31:0]D1;
63. reg [15:0]D2;
64.
65. always @ ( posedge CLOCK or negedge RESET )
66. if( !RESET )
67. begin
68. D1 <= 18'd0;
69. D2 <= 16'd0;
70. end
以上內容為相關的暫存器宣告以及復位操作。D1暫存影象的地址資訊,D2暫存影象資訊。
71. else
72. begin
73.
74. // step 1 : compute data address and index-n
75. if( isReady )
76. D1 <= (y << 7) + x;
77. else
78. D1 <= 14'd0;
79.
80. // step 2 : reading data from rom
81. // but do-nothing
82.
83. // step 3 : assign RGB_Sig
84. D2 <= isReady ? iData : 16'd0;
85.
86. end
87.
以上內容為核心操作。它是流水操作,步驟1轉換影象資訊地址至D1,步驟2等待影象資訊反饋,步驟3暫存影象資訊至D2。
88. reg [1:0]B1,B2,B3;
89.
90. always @ ( posedge CLOCK or negedge RESET )
91. if( !RESET )
92. { B3, B2, B1 } <= 6'b11_11_11;
93. else
94. begin
95. B1 <= { H,V };
96. B2 <= B1;
97. B3 <= B2;
98. end
99.
以上內容為對此行列延遲的周邊操作。
100. assign LCD_CLOCK = CLOCK;
101. assign { LCD_HSYNC, LCD_VSYNC } = B3;
102. assign LCD_RED = { D2[15:11],1'b0};
103. assign LCD_GREEN = D2[10:5];
104. assign LCD_BLUE = { D2[4:0],1'b0};
105. assign LCD_DE = 1'b1;
106. assign {LCD_LR, LCD_UD} = 2'b10;
107. assign LCD_MODE = 1'b0;
108. assign LCD_PWM = 1'b1;
109. assign oAddr = D1[13:0];
110.
111. endmodule
以上內容為相關的輸出驅動聲。注意LCD_RED/BLUE 都是捨棄最低位,LCD_LR/UD為2’b10,LCD_MODE拉低,LCD_DE常年拉高。
lcd_savemod.v
內容基本上與實驗二十六一樣。
lcd_basemod.v
連線部署請參考圖29.5。
1. module lcd_basemod
2. (
3. input CLOCK, RESET,
4.
5. output LCD_CLOCK,
6. output LCD_HSYNC, LCD_VSYNC,
7. output [5:0]LCD_RED,LCD_GREEN,LCD_BLUE,
8. output LCD_DE,
9. output LCD_UD, LCD_LR,
10. output LCD_MODE,
11. output LCD_PWM
12. );
以上內容為相關出入端宣告。
13. wire CLOCK_25M;
14.
15. pll_module U1
16. (
17. .inclk0 ( CLOCK ),
18. .c0 ( CLOCK_25M )
19. );
20.
以上內容為PLL的例項化。注意,7”TFT除了最大畫素時鐘是50Mhz以外,餘下可以任意設定。
21. wire [13:0]AddrU2;
22.
23. lcd_funcmod U2
24. (
25. .CLOCK( CLOCK_25M ),
26. .RESET( RESET ),
27. .LCD_CLOCK( LCD_CLOCK ),
28. .LCD_HSYNC( LCD_HSYNC ),
29. .LCD_VSYNC( LCD_VSYNC ),
30. .LCD_RED( LCD_RED ),
31. .LCD_GREEN( LCD_GREEN ),
32. .LCD_BLUE( LCD_BLUE ),
33. .LCD_DE( LCD_DE ),
34. .LCD_LR( LCD_LR ),
35. .LCD_UD( LCD_UD ),
36. .LCD_MODE( LCD_MODE ),
37. .LCD_PWM( LCD_PWM ),
38. .oAddr( AddrU2 ),
39. .iData( DataU3 )
40. );
41.
以上內容為功能模組的例項化。
42. wire [15:0]DataU3;
43.
44. lcd_savemod U3
45. (
46. .CLOCK( CLOCK_25M ),
47. .RESET( RESET ),
48. .iAddr( AddrU2 ),
49. .oData ( DataU3 )
50. );
51.
52. endmodule
以上內容為儲存模組的例項化。
圖29.6 顯示效果。
完後,綜合程式並且下載進去,如果7”TFT的左上角出現一群小可愛,結果如圖29.6,那麼表示實驗成功。
細節一:完整的個體模組
本實驗的LCD基礎模組只是演示7”TFT如何驅動而已。
相關推薦
【黑金原創教程】【FPGA那些事兒-驅動篇I 】【實驗一】流水燈模組
實驗一:流水燈模組 對於發展商而言,動土儀式無疑是最重要的任務。為此,流水燈實驗作為低階建模II的動土儀式再適合不過了。廢話少說,我們還是開始實驗吧。 圖1.1 實驗一建模圖。 如圖1.1 所示,實驗一有名為 led_funcmod的功能模組。如果無視環境訊號(時鐘訊號還有復位訊號),該功能模組只有
【黑金原創教程】【FPGA那些事兒-驅動篇I 】連載導讀
前言: 無數晝夜的來回輪替以後,這本《驅動篇I》終於編輯完畢了,筆者真的感動到連鼻涕也流下來。所謂驅動就是認識硬體,還有前期建模。雖然《驅動篇I》的硬體都是我們熟悉的老友記,例如UART,VGA等,但是《驅動篇I》貴就貴在建模技巧的昇華,亦即低階建模II。 話說低階建模II,讀過《建模篇》的朋友多少也會面
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗三:按鍵模組② — 點選與長點選
實驗三:按鍵模組② — 點選與長點選 實驗二我們學過按鍵功能模組的基礎內容,其中我們知道按鍵功能模組有如下操作: l 電平變化檢測; l 過濾抖動; l 產生有效按鍵。 實驗三我們也會z執行同樣的事情,不過卻是產生不一樣的有效按鍵: l 按下有效(點選); l 長按下有效(長點選)。 圖3
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗二:按鍵模組①
實驗二:按鍵模組① - 消抖 按鍵消抖實驗可謂是經典中的經典,按鍵消抖實驗雖曾在《建模篇》出現過,而且還惹來一堆麻煩。事實上,筆者這是在刁難各位同學,好讓對方的慣性思維短路一下,但是慘遭口水攻擊 ... 面對它,筆者宛如被甩的男人,對它又愛又恨。不管怎麼樣,如今 I’ll be back,筆者再也不會重複一
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗六:數碼管模組
實驗六:數碼管模組 有關數碼管的驅動,想必讀者已經學爛了 ... 不過,作為學習的新儀式,再爛的東西也要溫故知新,不然學習就會不健全。黑金開發板上的數碼管資源,由始至終都沒有改變過,筆者因此由身懷念。為了點亮多位數碼管從而顯示數字,一般都會採用動態掃描,然而有關動態掃描的資訊請怒筆者不再重複。在此,同樣也是
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗四:按鍵模組③ — 單擊與雙擊
實驗四:按鍵模組③ — 單擊與雙擊 實驗三我們建立了“點選”還有“長點選”等有效按鍵的多功能按鍵模組。在此,實驗四同樣也是建立多功能按鍵模組,不過卻有不同的有效按鍵。實驗四的按鍵功能模組有以下兩項有效按鍵: l 單擊(按下有效); l 雙擊(連續按下兩下有效)。 圖4.1 單擊有效按鍵,時序示意圖
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗五:按鍵模組④ — 點選,長點選,雙擊
實驗五:按鍵模組④ — 點選,長點選,雙擊 實驗二至實驗四,我們一共完成如下有效按鍵: l 點選(按下有效) l 點選(釋放有效) l 長擊(長按下有效) l 雙擊(連續按下有效) 然而,不管哪個實驗都是隻有兩項“功能”的按鍵模組而已,如今我們要建立三項“功能”的按鍵模組,亦即點選(按下有效),長
【黑金原創教程】【FPGA那些事兒-驅動篇I 】原創教程連載導讀【連載完成,共二十九章】
前言: 無數晝夜的來回輪替以後,這本《驅動篇I》終於編輯完畢了,筆者真的感動到連鼻涕也流下來。所謂驅動就是認識硬體,還有前期建模。雖然《驅動篇I》的硬體都是我們熟悉的老友記,例如UART,VGA等,但是《驅動篇I》貴就貴在建模技巧的昇華,亦即低階建模II。 話說低階建模II,讀過《建模篇》的朋友多少也會面
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗二十一:SDRAM模組④ — 頁讀寫 β
實驗二十一:SDRAM模組④ — 頁讀寫 β 未進入主題之前,讓我們先來談談一些重要的體外話。《整合篇》之際,筆者曾經比擬Verilog如何模仿for迴圈,我們知道for迴圈是順序語言的產物,如果Verilog要實現屬於自己的for迴圈,那麼它要考慮的東西除了步驟以外,還有非常關鍵的時鐘。 for(
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗十:PS/2模組④ — 普通滑鼠
實驗十:PS/2模組④ — 普通滑鼠 學習PS/2鍵盤以後,接下來就要學習 PS/2 滑鼠。PS/2滑鼠相較PS/2鍵盤,驅動難度稍微高了一點點,因為FPGA(從機)不僅僅是從PS/2滑鼠哪裡讀取資料,FPGA還要往滑鼠裡寫資料 ... 反之,FPGA只要對PS/2鍵盤讀取資料即可。然而,最傷腦筋的地方就在
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗十八:SDRAM模組① — 單字讀寫
實驗十八:SDRAM模組① — 單字讀寫 筆者與SDRAM有段不短的孽緣,它作為冤魂日夜不斷糾纏筆者。筆者嘗試過許多方法將其退散,不過屢試屢敗的筆者,最終心情像橘子一樣橙。《整合篇》之際,筆者曾經大戰幾回兒,不過內容都是點到即止。最近它破蠱而出,日夜不停:“好~痛苦!好~痛苦!”地呻吟著,嚇得筆者不敢半夜如
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗二十七:TFT模組
實驗二十七:TFT模組 - 顯示 所謂TFT(Thin Film Transistor)就是眾多LCD當中,其中一種支援顏色的LCD,相較古老的點陣LCD(12864笑),它可謂高階了。黑金的TFT LCD除了320×240大小以外,內建SSD1289控制器,同時也是獨立模組。事實上,無論是驅動點陣LCD還
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗十三:串列埠模組② — 接收
實驗十三:串列埠模組② — 接收 我們在實驗十二實現了串列埠傳送,然而這章實驗則要實現串列埠接收 ... 在此,筆者也會使用其它思路實現串列埠接收。 圖13.1 模組之間的資料傳輸。 假設我們不考慮波特率,而且一幀資料之間的傳輸也只是發生在FPGA之間,即兩隻模組之間互轉,並且兩塊模組都使用相同的時
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗七:PS/2模組① — 鍵盤
實驗七:PS/2模組① — 鍵盤 實驗七依然也是熟爛的PS/2鍵盤。相較《建模篇》的PS/2鍵盤實驗,實驗七實除了實現基本的驅動以外,我們還要深入解PS/2時序,還有PS/2鍵盤的行為。不過,為了節省珍貴的頁數,怒筆者不再重複有關PS/2的基礎內容,那些不曉得的讀者請複習《建模篇》或者自行谷歌一下。 市場
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗九:PS/2模組③ — 鍵盤與多組合鍵
實驗九:PS/2模組③ — 鍵盤與多組合鍵 筆者曾經說過,通碼除了單位元組以外,也有雙位元組通碼,而且雙位元組通碼都是 8’hE0開頭,別名又是 E0按鍵。常見的的E0按鍵有,<↑>,<↓>,<←>,<→>,<HOME>,<PRTSC>
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗二十五:SDHC模組
實驗二十五:SDHC模組 筆者曾經說過,SD卡發展至今已經衍生許多版本,實驗二十四就是針對版本SDV1.×的SD卡。實驗二十四也說過,CMD24還有CMD17會故意偏移地址29,讓原本範圍指向從原本的232 變成 223,原因是SD卡讀寫一次都有512個位元組。為此我們可以這樣計算: SDV1.x = 2
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗二十:SDRAM模組③ — 頁讀寫 α
實驗二十:SDRAM模組③ — 頁讀寫 α 完成單字讀寫與多字讀寫以後,接下來我們要實驗頁讀寫。醜話當前,實驗二十的頁讀寫只是實驗性質的東西,其中不存在任何實用價值,筆者希望讀者可以把它當成頁讀寫的熱身運動。 表示20.1 Mode Register的內容。 Mode Register
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗二十八:TFT模組
實驗二十八:TFT模組 - 觸屏 讀者在上一個實驗所玩弄過的 TFT LCD模組,除了顯示大小為 320 × 240,顏色為16位RGB的影象資訊以外,它還支援觸屏。所謂觸屏就是滑鼠還有鍵盤以外的輸入手段,例如現在流行平板還有智慧手機,觸屏輸入對我們來說,已經成為日常的一部分。描述語言一門偏向硬體的語言
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗二十二:SDRAM模組⑤ — FIFO讀寫
經過漫長的戰鬥以後,我們終於來到最後。對於普通人而言,頁讀寫就是一名戰士的墓碑(最終戰役) ... 然而,怕死的筆者想透過這個實驗告訴讀者,旅程的終點就是旅程的起點。一直以來,筆者都在煩惱“SDRAM是否應該成為儲存類?”SDRAM作為一介儲存資源(儲存器),它的好處就是大容量空間,壞處則就是麻煩的控制規
【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗十四:儲存模組
實驗十四比起動手筆者更加註重原理,因為實驗十四要討論的東西,不是其它而是低階建模II之一的模組類,即儲存模組。接觸順序語言之際,“儲存”不禁讓人聯想到變數或者陣列,結果它們好比資料的暫存空間。 1. int main() 2. { 3. int VarA; 4.