斷斷續續地學了verilog HDL和FPGA一段時間,一直沒有完整的做一個東西,看到論壇上有做TFT控制器的,于是就仿制了一個.
verilog程序大部分是自己寫的,一些部分如異步寫入,HSync,VSync時序產生部分參考了"dzng11"
廢話不說了:直接上圖上資料
IMG_20120220_101406.jpg (1022.02 KB, 下載次數: 111)
下載附件
2019-6-9 15:58 上傳
IMG_20120220_094510.jpg (1.3 MB, 下載次數: 120)
下載附件
驅動板
2019-6-9 15:58 上傳
捕獲.PNG (8.82 KB, 下載次數: 123)
下載附件
編譯信息,一定要設置為面積優化
2019-6-9 15:58 上傳
電路原理圖如下:
0.png (102.72 KB, 下載次數: 134)
下載附件
2019-6-10 00:11 上傳
0.png (5.42 KB, 下載次數: 125)
下載附件
2019-6-10 00:11 上傳
verilog HDL源程序如下:
- /**********************************************************************
- 通用4.3寸tft驅動
- 地址1位
- -----------------------------------------------------------------——----
- A0=0寄存器,寄存器0-7
- 0 SRAM數據
- 1 xIdex x軸寄存器
- 2 yIdex y軸寄存器
- 3 yend 結束寄存器,用于窗口繪圖加速
- 4 前景顏色
- 5 背景色
- 6
- 7 系統狀態0-15位
- bo-b2 b3 b4-b6 b7-b9 b10-b12
- 背光 顯示開/關 顯示方式 要寫入的頁 當前顯示頁
- 必須位x00 必須位x00
- x可改變(b7) x可改變(b10)
- -----------------------------------------------------------------------
- AO=1數據
- 2011.12.5
- ***********************************************************************/
- /*
- 接口說明:
- Clk54:系統晶振,選擇54M晶振
- SysRst:系統復位線.
- ExDataBus:外部16位數據總線
- ExCs:控制器片選,
- ExRs:數據批令選擇
- ExWr:寫信號
- ExRd:讀信號
- RamAddrBus:顯存地址線.
- RamDataBus:顯存數據總線
- RamCs:顯存片選
- RamWe:顯存寫選通.
- LedOn:背光控制PWM
- DE:TFT屏
- DE:VSyncTFT屏,
- HSync:TFT屏
- RGB:TFT屏
- Pclk:TFT屏);
- */
- module tft43(Clk54, SysRst, ExDataBus, ExCs, ExRs, ExWr, ExRd, RamAddrBus,
- RamDataBus, RamCs, RamWe,RamOe, LedOn, DE, VSync, HSync, RGB, Pclk);
- input Clk54, SysRst, ExCs, ExRs, ExRd, ExWr;
- inout [15:0] ExDataBus;
- inout [15:0] RamDataBus;
- output [17 : 0] RamAddrBus;
- output [15:0] RGB;
- output RamCs, RamWe,RamOe, LedOn, DE, VSync, HSync, Pclk;
- reg [2:0] ClkCnt_Q3;
- reg DotClkEn_Q;
- reg Pclk_Q;
- reg WrEn_Q;
- reg [15:0]ExBusOut_Q;
- reg [15:0] ExOutM;
- reg [15:0] WriteRgb_Q;
- reg ExWrClk_Q;
- reg ExRsR_Q;
- reg ExCsR_Q;
- reg ExRdClk_Q;
- reg ExRdClk_Q1;
- reg ExRdClk_Q2;
-
- reg ExWrClk_Q1;
- reg ExWrClk_Q2;
-
- reg [12:0] SramAddr;
- reg [15:0] PrePareData;
- reg [7:0] IndexData;
- reg InRamWe;
- reg IncAddr;
- reg XRegOver;
- reg YRegOver;
- reg AskWr;
- reg [15:0] RGB_Q;
- reg [15:0] InBusOut_Q;
- reg [8:0] XRegValue_Q;
- reg [8:0] YRegValue_Q;
- reg [15:0] SysCmdValue_Q;
- reg [2:0] RegAddr_Q;
- reg RamWeReg_Q;
- reg RamTriState_Q;
- reg [2:0] FillCount_Q;
- reg [15:0] BRGBValue_Q;
- reg [15:0] FRGBValue_Q;
- reg [17:0] RamAddrBus_Q;
- reg FillHead_Q;
- reg [8:0] HsCount_Q;
- reg [8:0] DotCount_Q;
- reg SelDispRam_Q;
- reg RamCsReg_Q;
- reg DsMark;
- reg HsMark;
- reg [1:0]DsState_Q;
- reg [1:0]HsState_Q;
- reg DE_Q;
- reg [4:0]LedCount_Q;
- reg LedOn_Q,LedOn_W;
- assign Pclk = Pclk_Q;
- assign RGB = RGB_Q;
- assign RamAddrBus = {RamAddrBus_Q};
- assign RamWe = RamWeReg_Q;
- assign RamCs = RamCsReg_Q;
- assign RamOe = RamCsReg_Q;/////
- assign RamDataBus = (RamTriState_Q | Clk54)?16'bzzzzzzzzzzzzzzzz:InBusOut_Q;
- assign VSync = DE_Q;
- assign HSync = DE_Q;//1'b0;
- assign DE = DE_Q;
- assign LedOn = LedOn_Q;
- assign ExDataBus = ExOutM;
- /*
- --1.將54M主時鐘6分頻,產生9M時鐘并輸出至引腳Pclk
- --2.輸出DotClkEn為9M信號同步其他進程.高電平為1個主時鐘周期,低電平5個主時鐘周期
- --3.技巧: 001,010,011,100,101,110.共6個狀態,高位剛好是6分頻等寬.
- */
- always @(posedge Clk54 or negedge SysRst)
- begin
- if (!SysRst) begin
- ClkCnt_Q3 = 3'd1;
- Pclk_Q = 1'b0;
- DotClkEn_Q = 1'b0;
- end else begin
- if (ClkCnt_Q3[2] & ClkCnt_Q3[1]) begin
- ClkCnt_Q3 <= 3'd1;
- end else begin
- ClkCnt_Q3 <= ClkCnt_Q3 + 3'd1;
- end
- Pclk_Q <= (SysCmdValue_Q[3])?1'b0:ClkCnt_Q3[2];
- DotClkEn_Q <= ((~ClkCnt_Q3[2]) & ClkCnt_Q3[1] & ClkCnt_Q3[0]);
- end
- end
- /*
- --外部接口在RD及CS低電平期間輸出內部數據
- --RS為0時輸出忙信號.RS為1時輸出當前地址的內部數據
- */
- always @(SysRst or ExBusOut_Q or WrEn_Q or ExCs or ExRs or ExWr or ExRd)
- begin
- if (!SysRst) begin
- ExOutM = 16'bzzzzzzzzzzzzzzzz;
- end else begin
- if ((~ExCs) & ExWr & (~ExRd)) begin
- ExOutM = (ExRs)?ExBusOut_Q:({15'd0,WrEn_Q});
- end else begin
- ExOutM = 16'bzzzzzzzzzzzzzzzz;
- end
- end
- end
- /*
- --外部異步WR寫入數據.
- */
- always @(posedge ExWr or negedge SysRst)
- begin
- if (!SysRst) begin
- WriteRgb_Q = 16'd0;
- ExWrClk_Q = 1'b0;
- RegAddr_Q = 3'd0;
- end else begin
- if (!ExCs) begin
- if (!ExRs) begin
- RegAddr_Q <= ExDataBus[2:0];
- end else begin
- WriteRgb_Q <= ExDataBus;
- ExWrClk_Q <= ~ExWrClk_Q;
- end
- end
- end
- end
- /*
- --外部異步RD讀出數據.
- */
- always @(negedge ExRd or negedge SysRst)
- begin
- if (!SysRst) begin
- ExRsR_Q = 1'b0;
- ExCsR_Q = 1'b1;
- end else begin
- ExCsR_Q <= ExCs;
- ExRsR_Q <= ExRs;
- end
- end
- always @(posedge ExRd or negedge SysRst)
- begin
- if (!SysRst) begin
- ExRdClk_Q = 1'b0;
- end else begin
- if ((~ExCsR_Q) & ExRsR_Q) begin
- ExRdClk_Q <= ~ExRdClk_Q;
- end
- end
- end
- /******************************************
- --主時鐘打兩拍同步采用外部讀寫信號
- ******************************************/
- always @(posedge Clk54 or negedge SysRst)
- begin
- if (!SysRst) begin
- ExRdClk_Q1 = 1'b0;
- ExRdClk_Q2 = 1'b0;
- ExWrClk_Q1 = 1'b0;
- ExWrClk_Q2 = 1'b0;
-
- end else begin
- ExRdClk_Q1 <= ExRdClk_Q;
- ExRdClk_Q2 <= ExRdClk_Q1;
- ExWrClk_Q1 <= ExWrClk_Q;
- ExWrClk_Q2 <= ExWrClk_Q1;
- end
- end
- always @(posedge Clk54 or negedge SysRst)
- begin
- if (!SysRst) begin
- InBusOut_Q = 16'd0;
- ExBusOut_Q = 16'd0;
- XRegValue_Q = 9'd0;
- YRegValue_Q = 9'd0;
- SysCmdValue_Q = 16'b0000000000110000;
- WrEn_Q = 1'b0;
- RamWeReg_Q = 1'b1;
- RamTriState_Q = 1'b1;
- RGB_Q = 16'd0;
- FillCount_Q = 3'd7;
- BRGBValue_Q = 16'd0;
- FRGBValue_Q = 16'd0;
- RamAddrBus_Q = 18'd0;
- RamCsReg_Q = 1'b1;
- PrePareData = 16'd0;
- end else begin
- if (ExRdClk_Q2 ^ ExRdClk_Q1) begin
- IncAddr = 1'b1;
- end else begin
- IncAddr = 1'b0;
- end
- if (ExWrClk_Q2 ^ ExWrClk_Q1) begin
- AskWr = 1'b1;
- end else begin
- AskWr = WrEn_Q;
- end
- XRegOver = (XRegValue_Q == 9'b111011111)?1'b1:1'b0;
- YRegOver = (YRegValue_Q == 9'b100001111)?1'b1:1'b0;
- PrePareData = WriteRgb_Q;
- IndexData[7:0] = WriteRgb_Q[7:0];
- InRamWe = 1'b1;
- if (!ClkCnt_Q3[0]) begin
- if (AskWr) begin
- case (RegAddr_Q)
- 3'b000:begin
- XRegValue_Q <= PrePareData[8:0];
- WrEn_Q <= 1'b0;
- end
- 3'b001:begin
- YRegValue_Q <= PrePareData[8:0];
- WrEn_Q <= 1'b0;
- end
- 3'b010:begin
- InRamWe = 1'b0;
- IncAddr = 1'b1;
- WrEn_Q <= 1'b0;
- end
- 3'b100:begin
- FRGBValue_Q <= PrePareData;
- WrEn_Q <= 1'b0;
- end
- 3'b101:begin
- BRGBValue_Q <= PrePareData;
- WrEn_Q <= 1'b0;
- end
- 3'b110:begin
- SysCmdValue_Q <= PrePareData;
- WrEn_Q <= 1'b0;
- end
-
- 3'b011:begin
- if (!IndexData[FillCount_Q]) begin
- PrePareData = BRGBValue_Q;
- InRamWe = SysCmdValue_Q[12];
- end else begin
- PrePareData = FRGBValue_Q;
- InRamWe = 1'b0;
- end
- IncAddr = 1'b1;
- WrEn_Q <= (FillCount_Q[0] | FillCount_Q[1] | FillCount_Q[2]);
- FillCount_Q <= FillCount_Q + 3'd7;
- end
- 3'b111:begin
- if (FillHead_Q) begin
- IncAddr = 1'b1;
- InRamWe = 1'b0;
- if (YRegOver & XRegOver) begin
- WrEn_Q <= 1'b0;
- end
- end else begin
- WrEn_Q <= 1'b1;
- end
- end
- endcase
- end
- RGB_Q <= (SysCmdValue_Q[3])?16'd0:RamDataBus;
- SramAddr[12:4] = YRegValue_Q[8:0];
- SramAddr[3:0] = XRegValue_Q[8:5];
- RamAddrBus_Q[4:0] <= XRegValue_Q[4:0];
- RamAddrBus_Q[17] <= SysCmdValue_Q[7];
- end else begin
- if (AskWr) begin
- WrEn_Q <= 1'b1;
- end
- ExBusOut_Q <= RamDataBus;
- SramAddr[12:4] = HsCount_Q[8:0];
- SramAddr[3:0] = DotCount_Q[8:5];
- RamAddrBus_Q[4:0] <= DotCount_Q[4:0];
- RamAddrBus_Q[17] <= SelDispRam_Q;
- end
- InBusOut_Q <= PrePareData;
- RamTriState_Q <= InRamWe;
- RamWeReg_Q <= InRamWe;
- SramAddr[12:0] = SramAddr[12:0] - {4'd0,SramAddr[12:4]};
- RamAddrBus_Q[16:5] <= SramAddr[11:0];
- /*根據配置字調整XY*/
- if (IncAddr) begin
- case (SysCmdValue_Q[6:4])
- 3'b001:begin
- if (XRegOver) begin
- XRegValue_Q <= 9'd0;
- end else begin
- XRegValue_Q <= XRegValue_Q + 9'd1;
- end
- end
- 3'b011:begin
- if (XRegOver) begin
- XRegValue_Q <= 9'd0;
- if (YRegOver) begin
- YRegValue_Q <= 9'd0;
- end else begin
- YRegValue_Q <= YRegValue_Q + 9'd1;
- end
- end else begin
- XRegValue_Q <= XRegValue_Q + 9'd1;
- end
- end
- 3'b110:begin
- if (YRegOver) begin
- YRegValue_Q <= 9'd0;
- end else begin
- YRegValue_Q <= YRegValue_Q + 9'd1;
- end
- end
- 3'b111:begin
- if (YRegOver) begin
- YRegValue_Q <= 9'd0;
- if (XRegOver) begin
- XRegValue_Q <= 9'd0;
- end else begin
- XRegValue_Q <= XRegValue_Q + 9'd1;
- end
- end else begin
- YRegValue_Q <= YRegValue_Q + 9'd1;
- end
- end
- default:begin
- end
- endcase
- end
- RamCsReg_Q <= SysCmdValue_Q[3];
- end
- end
- /*--產生TFT行同步*/
- always @(posedge Clk54 or negedge SysRst)
- begin
- if (!SysRst) begin
- DotCount_Q = 9'd0;
- DsState_Q = 2'd0;
- DsMark = 1'b0;
- end else begin
- if (DotClkEn_Q) begin
- case (DsState_Q)
- 2'd0:/*=>--41 相當于<= 40*/
- DsMark = (DotCount_Q[5] & DotCount_Q[3]);
- 2'd1:/*when "01" =>--2 相當于<= 1*/
- DsMark = DotCount_Q[0];
- 2'd2:/*=>--480 相當于<= 479*/
- DsMark = (DotCount_Q[0] & DotCount_Q[1] & DotCount_Q[2] & DotCount_Q[3] &
- DotCount_Q[4] & DotCount_Q[6] & DotCount_Q[7] & DotCount_Q[8]);
- 2'd3:/*--2 相當于<= 1*/
- DsMark = DotCount_Q[0];
- endcase
- DsState_Q <= DsState_Q + {1'b0,DsMark};
- DotCount_Q <= (DsMark)?9'd0:(DotCount_Q + 9'd1);
- end
- end
- end
- /*--產生TFT幀同步信號*/
- always @(posedge Clk54 or negedge SysRst)
- begin
- if (!SysRst) begin
- DE_Q = 1'b0;
- end else begin
- DE_Q <= (SysCmdValue_Q[3])?1'b0:(HsState_Q[1] & (~HsState_Q[0]) & DsState_Q[1] & (~DsState_Q[0]));
- end
- end
- /*--產生幀同步時鐘*/
- always @(posedge Clk54 or negedge SysRst)
- begin
- if (!SysRst) begin
- HsCount_Q = 9'd0;
- HsState_Q = 2'd0;
- FillHead_Q = 1'b0;
- SelDispRam_Q = 1'b0;
- LedCount_Q = 5'd0;
- end else begin
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
tft43.rar
(9.52 MB, 下載次數: 112)
2019-6-9 15:59 上傳
點擊文件名下載附件
CPLD工程 下載積分: 黑幣 -5
stm32程序.7z
(559.44 KB, 下載次數: 87)
2019-6-10 00:09 上傳
點擊文件名下載附件
stm32工程 下載積分: 黑幣 -5
|