摘要:
本次试验主要是在IDE软件环境下,利用DMA方式向LCM填充一定的数据,使LCM显示你想要的图像数据。
试验目的:利用NIOS II控制LCM显示;
试验工具:Quartus II 9.1+SOPC Builder +NIOS II IDE 9.1+terasic TRDB-LCM
一、硬件设计
1、LCM驱动器的设计
由于要在软件上控制LCM,就要自己写一个LCM的驱动,这个驱动主要是能够在SOPC里面符合Avalon总线形式,这样就可以利用软件形式实现LCM的控制,首先,我们来看一看驱动的Verilog代码。
1 module LCM_Controller(
2 // LCM Side
3 avs_s0_export_o_LCM_DATA,
4 avs_s0_export_o_LCM_VSYNC,
5 avs_s0_export_o_LCM_HSYNC,
6 avs_s0_export_o_LCM_DCLK,
7 avs_s0_export_o_LCM_GRST,
8 avs_s0_export_o_LCM_SHDB,
9 // Control Signals ----Avalon
10 avs_s0_export_i_iCLK,
11 avs_s0_address,
12 avs_s0_write_n,
13 avs_s0_writedata,
14 avs_s0_waitrequest,
15 csi_clockreset_clk,
16 csi_clockreset_reset_n );
17 // LCM Side
18 output [7:0] avs_s0_export_o_LCM_DATA;
19 output avs_s0_export_o_LCM_VSYNC;
20 output avs_s0_export_o_LCM_HSYNC;
21 output avs_s0_export_o_LCM_DCLK;
22 output avs_s0_export_o_LCM_GRST;
23 output avs_s0_export_o_LCM_SHDB;
24 // Control Signals
25 input avs_s0_export_i_iCLK;
26 input csi_clockreset_clk;
27 input csi_clockreset_reset_n;
28 output avs_s0_waitrequest;
29 // Avalon总线接口
30 input [31:0] avs_s0_writedata;
31 input [1:0] avs_s0_address;
32 input avs_s0_write_n;
33 // Internal Register and Wire
34 reg [10:0] H_Cont;
35 reg [10:0] V_Cont;
36 reg mVGA_H_SYNC;
37 reg mVGA_V_SYNC;
38 reg rRST;
39 reg [7:0] mDATA;
40
41 // Horizontal Parameter ( Pixel )
42 parameter H_SYNC_CYC = 1;
43 parameter H_SYNC_BACK = 151;
44 parameter H_SYNC_ACT = 960;
45 parameter H_SYNC_FRONT = 59;
46 parameter H_SYNC_TOTAL = 1171;
47 // Virtical Parameter ( Line )
48 parameter V_SYNC_CYC = 1;
49 parameter V_SYNC_BACK = 13;
50 parameter V_SYNC_ACT = 240;
51 parameter V_SYNC_FRONT = 8;
52 parameter V_SYNC_TOTAL = 262;
53
54 assign avs_s0_export_o_LCM_SHDB = 1'b1;
55 assign avs_s0_export_o_LCM_GRST = 1'b1;
56 assign avs_s0_export_o_LCM_DCLK = ~avs_s0_export_i_iCLK;
57 assign avs_s0_export_o_LCM_VSYNC = mVGA_V_SYNC;
58 assign avs_s0_export_o_LCM_HSYNC = mVGA_H_SYNC;
59 assign avs_s0_export_o_LCM_DATA = rDATA;
60
61 // write to export
62 always@(posedge csi_clockreset_clk or negedge csi_clockreset_reset_n)
63 begin
64 if (!csi_clockreset_reset_n)
65 rRST <=1;
66 else
67 begin
68 if (avs_s0_address == 2'b01 && !avs_s0_write_n)
69 rRST <=1'b1;
70 else if (avs_s0_address == 2'b00 &&!avs_s0_write_n)
71 rRST <=1'b0;
72 end
73 end
74
75 wire lcm_valid,fifo_empty,fifo_full,wrq;
76 wire [9:0]rddw;
77 wire [7:0]rDATA;
78 assign lcm_valid=( H_Cont>H_SYNC_BACK && //add it
79 H_Cont<(H_SYNC_TOTAL-H_SYNC_FRONT) &&
80 V_Cont>V_SYNC_BACK &&
81 V_Cont<(V_SYNC_TOTAL-V_SYNC_FRONT) &&
82 fifo_empty==0 )? 1 : 0;
83
84 assign wrq=(!fifo_full)&&(!avs_s0_write_n)&&(avs_s0_address==2'b00);
85 assign avs_s0_waitrequest=fifo_full;
86 fifo u1(
87 .data(avs_s0_writedata[7:0]),
88 .rdclk(avs_s0_export_i_iCLK),
89 .rdreq(lcm_valid),
90 .wrclk(csi_clockreset_clk),
91 .wrreq(wrq),
92 .q(rDATA),
93 .rdempty(fifo_empty),
94 .rdusedw(rddw),
95 .aclr(rRST),
96 .wrfull(fifo_full)
97 );
98
99 // H_Sync Generator, Ref. 18.42 MHz Clock
100 always@(posedge avs_s0_export_i_iCLK or negedge csi_clockreset_reset_n)
101 begin
102 if(!csi_clockreset_reset_n)
103 begin
104 H_Cont <= 0;
105 mVGA_H_SYNC <= 0;
106 end
107 else
108 begin
109 // H_Sync Counter
110 if( H_Cont < H_SYNC_TOTAL )
111 H_Cont <= H_Cont+1;
112 else
113 H_Cont <= 0;
114 // H_Sync Generator
115 if( H_Cont < H_SYNC_CYC )
116 mVGA_H_SYNC <= 0;
117 else
118 mVGA_H_SYNC <= 1;
119 end
120 end
121
122 // V_Sync Generator, Ref. H_Sync
123 always@(posedge avs_s0_export_i_iCLK or negedge csi_clockreset_reset_n)
124 begin
125 if(!csi_clockreset_reset_n)
126 begin
127 V_Cont <= 0;
128 mVGA_V_SYNC <= 0;
129 end
130 else
131 begin
132 // When H_Sync Re-start
133 if(H_Cont==0)
134 begin
135 // V_Sync Counter
136 if( V_Cont < V_SYNC_TOTAL )
137 V_Cont <= V_Cont+1;
138 else
139 V_Cont <= 0;
140 // V_Sync Generator
141 if( V_Cont < V_SYNC_CYC )
142 mVGA_V_SYNC <= 0;
143 else
144 mVGA_V_SYNC <= 1;
145 end
146 end
147 end
148
149 endmodule
这里面,我稍微解释一下这段代码。
1 // write to export
2 always@(posedge csi_clockreset_clk or negedge csi_clockreset_reset_n)
3 begin
4 if (!csi_clockreset_reset_n)
5 rRST <=1;
6 else
7 begin
8 if (avs_s0_address == 2'b01 && !avs_s0_write_n)
9 rRST <=1'b1;
10 else if (avs_s0_address == 2'b00 &&!avs_s0_write_n)
11 rRST <=1'b0;
12 end
13 end
14
15 wire lcm_valid,fifo_empty,fifo_full,wrq;
16 wire [9:0]rddw;
17 wire [7:0]rDATA;
18 assign lcm_valid=( H_Cont>H_SYNC_BACK && //add it
19 H_Cont<(H_SYNC_TOTAL-H_SYNC_FRONT) &&
20 V_Cont>V_SYNC_BACK &&
21 V_Cont<(V_SYNC_TOTAL-V_SYNC_FRONT) &&
22 fifo_empty==0 )? 1 : 0;
23
24 assign wrq=(!fifo_full)&&(!avs_s0_write_n)&&(avs_s0_address==2'b00);
25 assign avs_s0_waitrequest=fifo_full;
26 fifo u1(
27 .data(avs_s0_writedata[7:0]),
28 .rdclk(avs_s0_export_i_iCLK),
29 .rdreq(lcm_valid),
30 .wrclk(csi_clockreset_clk),
31 .wrreq(wrq),
32 .q(rDATA),
33 .rdempty(fifo_empty),
34 .rdusedw(rddw),
35 .aclr(rRST),
36 .wrfull(fifo_full)
37 );
38
这段代码,前面1-13行,主要是做一个写端口,做的就是对r_RST信号的控制,后面的就是我做的一个fifo,首先,我来讲讲为什么要做这个fifo,我们来看看NIOS II的时钟频率是100M,现在我们要做的是用NIOS II打开一个DMA通道,往LCM里面写数据,而LCM像素时钟这里,是设置成18.42M,这样的话,两边的时钟不匹配,如果要进行数据通畅传输的话,就需要一种fifo,这里,就定义了一个双口时钟不一致的fifo来完成这样的功能,这就是要加入这个fifo的原因,好了,下面来看看是怎么实现的。
首先是写数据端口,写入的时钟是SOPC里面的CPU的时钟csi_clockreset_clk,写使能信号为wrq=(!fifo_full)&&(!avs_s0_write_n)&&(avs_s0_address==2'b00),就是当fifo不满的情况下,就可以向fifo写入数据;
再看看读端口,读的时钟自然就是外面传入的时钟,为18.42M,读的使能信号为
assign lcm_valid=( H_Cont>H_SYNC_BACK && //add it
H_Cont<(H_SYNC_TOTAL-H_SYNC_FRONT) &&
V_Cont>V_SYNC_BACK &&
V_Cont<(V_SYNC_TOTAL-V_SYNC_FRONT) &&
fifo_empty==0 )? 1 : 0;
表示在fifo不是空的情况下,LCM处于数据有效区的情况下,就进行读取数据。
1 // H_Sync Generator, Ref. 18.42 MHz Clock
2 always@(posedge avs_s0_export_i_iCLK or negedge csi_clockreset_reset_n)
3 begin
4 if(!csi_clockreset_reset_n)
5 begin
6 H_Cont <= 0;
7 mVGA_H_SYNC <= 0;
8 end
9 else
10 begin
11 // H_Sync Counter
12 if( H_Cont < H_SYNC_TOTAL )
13 H_Cont <= H_Cont+1;
14 else
15 H_Cont <= 0;
16 // H_Sync Generator
17 if( H_Cont < H_SYNC_CYC )
18 mVGA_H_SYNC <= 0;
19 else
20 mVGA_H_SYNC <= 1;
21 end
22 end
23
24 // V_Sync Generator, Ref. H_Sync
25 always@(posedge avs_s0_export_i_iCLK or negedge csi_clockreset_reset_n)
26 begin
27 if(!csi_clockreset_reset_n)
28 begin
29 V_Cont <= 0;
30 mVGA_V_SYNC <= 0;
31 end
32 else
33 begin
34 // When H_Sync Re-start
35 if(H_Cont==0)
36 begin
37 // V_Sync Counter
38 if( V_Cont < V_SYNC_TOTAL )
39 V_Cont <= V_Cont+1;
40 else
41 V_Cont <= 0;
42 // V_Sync Generator
43 if( V_Cont < V_SYNC_CYC )
44 mVGA_V_SYNC <= 0;
45 else
46 mVGA_V_SYNC <= 1;
47 end
48 end
49 end
50
51 endmodule
上面是产生LCM的行同步信号和场同步信号,这里就不多讲,不懂的,请看相关的LCM显示的文章。
2、定义自己的ip核
关于这里面,如何定制自己的ip核,这里我就不多说,毕竟要说的话,内容太多啦,大家可以看看其他人的博客,都有讲,由于我这里的命名都是按照规定的要求做的,系统自动识别端口类型,一步步next就ok啦!建议大家看看黑金动力关于自定义ip核那篇博客。
3、构建自己的SOPC系统
按照下图所示,建立属于自己的SOPC系统
添加好所有的ip核之后,自动分配一下基地址,分配一下中断号,Generate就OK啦!
4、在Quartus里面建立顶层文件
代码如下:
1 // --------------------------------------------------------------------
2 // Copyright (c) 2005 by Terasic Technologies Inc.
3 // --------------------------------------------------------------------
4 //
5 // Permission:
6 //
7 // Terasic grants permission to use and modify this code for use
8 // in synthesis for all Terasic Development Boards and Altera Development
9 // Kits made by Terasic. Other use of this code, including the selling
10 // ,duplication, or modification of any portion is strictly prohibited.
11 //
12 // Disclaimer:
13 //
14 // This VHDL/Verilog or C/C++ source code is intended as a design reference
15 // which illustrates how these types of functions can be implemented.
16 // It is the user's responsibility to verify their design for
17 // consistency and functionality through the use of formal
18 // verification methods. Terasic provides no warranty regarding the use
19 // or functionality of this code.
20 //
21 // --------------------------------------------------------------------
22 //
23 // Terasic Technologies Inc
24 // 356 Fu-Shin E. Rd Sec. 1. JhuBei City,
25 // HsinChu County, Taiwan
26 // 302
27 //
28 // web: http://www.terasic.com/
29 // email: support@terasic.com
30 //
31 // --------------------------------------------------------------------
32 //
33 // Major Functions: DE2 LCD Module + CMOS Sensor
34 //
35 // --------------------------------------------------------------------
36 //
37 // Revision History :
38 // --------------------------------------------------------------------
39 // Ver :| Author :| Mod. Date :| Changes Made:
40 // V1.0 :| Johnny Chen :| 06/03/29 :| Initial Revision
41 // --------------------------------------------------------------------
42
43 module DE2_LCD
44 (
45 //////////////////// Clock Input ////////////////////
46 CLOCK_27, // 27 MHz
47 CLOCK_50, // 50 MHz
48 EXT_CLOCK, // External Clock
49 //////////////////// Push Button ////////////////////
50 KEY, // Pushbutton[3:0]
51 //////////////////// DPDT Switch ////////////////////
52 SW, // Toggle Switch[17:0]
53 //////////////////// 7-SEG Dispaly ////////////////////
54 HEX0, // Seven Segment Digit 0
55 HEX1, // Seven Segment Digit 1
56 HEX2, // Seven Segment Digit 2
57 HEX3, // Seven Segment Digit 3
58 HEX4, // Seven Segment Digit 4
59 HEX5, // Seven Segment Digit 5
60 HEX6, // Seven Segment Digit 6
61 HEX7, // Seven Segment Digit 7
62 //////////////////////// LED ////////////////////////
63 LEDG, // LED Green[8:0]
64 LEDR, // LED Red[17:0]
65 //////////////////////// UART ////////////////////////
66 UART_TXD, // UART Transmitter
67 UART_RXD, // UART Receiver
68 //////////////////////// IRDA ////////////////////////
69 IRDA_TXD, // IRDA Transmitter
70 IRDA_RXD, // IRDA Receiver
71 ///////////////////// SDRAM Interface ////////////////
72 DRAM_DQ, // SDRAM Data bus 16 Bits
73 DRAM_ADDR, // SDRAM Address bus 12 Bits
74 DRAM_LDQM, // SDRAM Low-byte Data Mask
75 DRAM_UDQM, // SDRAM High-byte Data Mask
76 DRAM_WE_N, // SDRAM Write Enable
77 DRAM_CAS_N, // SDRAM Column Address Strobe
78 DRAM_RAS_N, // SDRAM Row Address Strobe
79 DRAM_CS_N, // SDRAM Chip Select
80 DRAM_BA_0, // SDRAM Bank Address 0
81 DRAM_BA_1, // SDRAM Bank Address 0
82 DRAM_CLK, // SDRAM Clock
83 DRAM_CKE, // SDRAM Clock Enable
84 //////////////////// Flash Interface ////////////////
85 FL_DQ, // FLASH Data bus 8 Bits
86 FL_ADDR, // FLASH Address bus 22 Bits
87 FL_WE_N, // FLASH Write Enable
88 FL_RST_N, // FLASH Reset
89 FL_OE_N, // FLASH Output Enable
90 FL_CE_N, // FLASH Chip Enable
91 //////////////////// SRAM Interface ////////////////
92 SRAM_DQ, // SRAM Data bus 16 Bits
93 SRAM_ADDR, // SRAM Address bus 18 Bits
94 SRAM_UB_N, // SRAM High-byte Data Mask
95 SRAM_LB_N, // SRAM Low-byte Data Mask
96 SRAM_WE_N, // SRAM Write Enable
97 SRAM_CE_N, // SRAM Chip Enable
98 SRAM_OE_N, // SRAM Output Enable
99 //////////////////// ISP1362 Interface ////////////////
100 OTG_DATA, // ISP1362 Data bus 16 Bits
101 OTG_ADDR, // ISP1362 Address 2 Bits
102 OTG_CS_N, // ISP1362 Chip Select
103 OTG_RD_N, // ISP1362 Write
104 OTG_WR_N, // ISP1362 Read
105 OTG_RST_N, // ISP1362 Reset
106 OTG_FSPEED, // USB Full Speed, 0 = Enable, Z = Disable
107 OTG_LSPEED, // USB Low Speed, 0 = Enable, Z = Disable
108 OTG_INT0, // ISP1362 Interrupt 0
109 OTG_INT1, // ISP1362 Interrupt 1
110 OTG_DREQ0, // ISP1362 DMA Request 0
111 OTG_DREQ1, // ISP1362 DMA Request 1
112 OTG_DACK0_N, // ISP1362 DMA Acknowledge 0
113 OTG_DACK1_N, // ISP1362 DMA Acknowledge 1
114 //////////////////// LCD Module 16X2 ////////////////
115 LCD_ON, // LCD Power ON/OFF
116 LCD_BLON, // LCD Back Light ON/OFF
117 LCD_RW, // LCD Read/Write Select, 0 = Write, 1 = Read
118 LCD_EN, // LCD Enable
119 LCD_RS, // LCD Command/Data Select, 0 = Command, 1 = Data
120 LCD_DATA, // LCD Data bus 8 bits
121 //////////////////// SD_Card Interface ////////////////
122 SD_DAT, // SD Card Data
123 SD_DAT3, // SD Card Data 3
124 SD_CMD, // SD Card Command Signal
125 SD_CLK, // SD Card Clock
126 //////////////////// USB JTAG link ////////////////////
127 TDI, // CPLD -> FPGA (data in)
128 TCK, // CPLD -> FPGA (clk)
129 TCS, // CPLD -> FPGA (CS)
130 TDO, // FPGA -> CPLD (data out)
131 //////////////////// I2C ////////////////////////////
132 I2C_SDAT, // I2C Data
133 I2C_SCLK, // I2C Clock
134 //////////////////// PS2 ////////////////////////////
135 PS2_DAT, // PS2 Data
136 PS2_CLK, // PS2 Clock
137 //////////////////// VGA ////////////////////////////
138 VGA_CLK, // VGA Clock
139 VGA_HS, // VGA H_SYNC
140 VGA_VS, // VGA V_SYNC
141 VGA_BLANK, // VGA BLANK
142 VGA_SYNC, // VGA SYNC
143 VGA_R, // VGA Red[9:0]
144 VGA_G, // VGA Green[9:0]
145 VGA_B, // VGA Blue[9:0]
146 //////////// Ethernet Interface ////////////////////////
147 ENET_DATA, // DM9000A DATA bus 16Bits
148 ENET_CMD, // DM9000A Command/Data Select, 0 = Command, 1 = Data
149 ENET_CS_N, // DM9000A Chip Select
150 ENET_WR_N, // DM9000A Write
151 ENET_RD_N, // DM9000A Read
152 ENET_RST_N, // DM9000A Reset
153 ENET_INT, // DM9000A Interrupt
154 ENET_CLK, // DM9000A Clock 25 MHz
155 //////////////// Audio CODEC ////////////////////////
156 AUD_ADCLRCK, // Audio CODEC ADC LR Clock
157 AUD_ADCDAT, // Audio CODEC ADC Data
158 AUD_DACLRCK, // Audio CODEC DAC LR Clock
159 AUD_DACDAT, // Audio CODEC DAC Data
160 AUD_BCLK, // Audio CODEC Bit-Stream Clock
161 AUD_XCK, // Audio CODEC Chip Clock
162 //////////////// TV Decoder ////////////////////////
163 TD_DATA, // TV Decoder Data bus 8 bits
164 TD_HS, // TV Decoder H_SYNC
165 TD_VS, // TV Decoder V_SYNC
166 TD_RESET, // TV Decoder Reset
167 //////////////////// GPIO ////////////////////////////
168 GPIO_0, // GPIO Connection 0
169 GPIO_1 // GPIO Connection 1
170 );
171
172 //////////////////////// Clock Input ////////////////////////
173 input CLOCK_27; // 27 MHz
174 input CLOCK_50; // 50 MHz
175 input EXT_CLOCK; // External Clock
176 //////////////////////// Push Button ////////////////////////
177 input [3:0] KEY; // Pushbutton[3:0]
178 //////////////////////// DPDT Switch ////////////////////////
179 input [17:0] SW; // Toggle Switch[17:0]
180 //////////////////////// 7-SEG Dispaly ////////////////////////
181 output [6:0] HEX0; // Seven Segment Digit 0
182 output [6:0] HEX1; // Seven Segment Digit 1
183 output [6:0] HEX2; // Seven Segment Digit 2
184 output [6:0] HEX3; // Seven Segment Digit 3
185 output [6:0] HEX4; // Seven Segment Digit 4
186 output [6:0] HEX5; // Seven Segment Digit 5
187 output [6:0] HEX6; // Seven Segment Digit 6
188 output [6:0] HEX7; // Seven Segment Digit 7
189 //////////////////////////// LED ////////////////////////////
190 output [8:0] LEDG; // LED Green[8:0]
191 output [17:0] LEDR; // LED Red[17:0]
192 //////////////////////////// UART ////////////////////////////
193 output UART_TXD; // UART Transmitter
194 input UART_RXD; // UART Receiver
195 //////////////////////////// IRDA ////////////////////////////
196 output IRDA_TXD; // IRDA Transmitter
197 input IRDA_RXD; // IRDA Receiver
198 /////////////////////// SDRAM Interface ////////////////////////
199 inout [15:0] DRAM_DQ; // SDRAM Data bus 16 Bits
200 output [11:0] DRAM_ADDR; // SDRAM Address bus 12 Bits
201 output DRAM_LDQM; // SDRAM Low-byte Data Mask
202 output DRAM_UDQM; // SDRAM High-byte Data Mask
203 output DRAM_WE_N; // SDRAM Write Enable
204 output DRAM_CAS_N; // SDRAM Column Address Strobe
205 output DRAM_RAS_N; // SDRAM Row Address Strobe
206 output DRAM_CS_N; // SDRAM Chip Select
207 output DRAM_BA_0; // SDRAM Bank Address 0
208 output DRAM_BA_1; // SDRAM Bank Address 0
209 output DRAM_CLK; // SDRAM Clock
210 output DRAM_CKE; // SDRAM Clock Enable
211 //////////////////////// Flash Interface ////////////////////////
212 inout [7:0] FL_DQ; // FLASH Data bus 8 Bits
213 output [21:0] FL_ADDR; // FLASH Address bus 22 Bits
214 output FL_WE_N; // FLASH Write Enable
215 output FL_RST_N; // FLASH Reset
216 output FL_OE_N; // FLASH Output Enable
217 output FL_CE_N; // FLASH Chip Enable
218 //////////////////////// SRAM Interface ////////////////////////
219 inout [15:0] SRAM_DQ; // SRAM Data bus 16 Bits
220 output [17:0] SRAM_ADDR; // SRAM Address bus 18 Bits
221 output SRAM_UB_N; // SRAM High-byte Data Mask
222 output SRAM_LB_N; // SRAM Low-byte Data Mask
223 output SRAM_WE_N; // SRAM Write Enable
224 output SRAM_CE_N; // SRAM Chip Enable
225 output SRAM_OE_N; // SRAM Output Enable
226 //////////////////// ISP1362 Interface ////////////////////////
227 inout [15:0] OTG_DATA; // ISP1362 Data bus 16 Bits
228 output [1:0] OTG_ADDR; // ISP1362 Address 2 Bits
229 output OTG_CS_N; // ISP1362 Chip Select
230 output OTG_RD_N; // ISP1362 Write
231 output OTG_WR_N; // ISP1362 Read
232 output OTG_RST_N; // ISP1362 Reset
233 output OTG_FSPEED; // USB Full Speed, 0 = Enable, Z = Disable
234 output OTG_LSPEED; // USB Low Speed, 0 = Enable, Z = Disable
235 input OTG_INT0; // ISP1362 Interrupt 0
236 input OTG_INT1; // ISP1362 Interrupt 1
237 input OTG_DREQ0; // ISP1362 DMA Request 0
238 input OTG_DREQ1; // ISP1362 DMA Request 1
239 output OTG_DACK0_N; // ISP1362 DMA Acknowledge 0
240 output OTG_DACK1_N; // ISP1362 DMA Acknowledge 1
241 //////////////////// LCD Module 16X2 ////////////////////////////
242 inout [7:0] LCD_DATA; // LCD Data bus 8 bits
243 output LCD_ON; // LCD Power ON/OFF
244 output LCD_BLON; // LCD Back Light ON/OFF
245 output LCD_RW; // LCD Read/Write Select, 0 = Write, 1 = Read
246 output LCD_EN; // LCD Enable
247 output LCD_RS; // LCD Command/Data Select, 0 = Command, 1 = Data
248 //////////////////// SD Card Interface ////////////////////////
249 inout SD_DAT; // SD Card Data
250 inout SD_DAT3; // SD Card Data 3
251 inout SD_CMD; // SD Card Command Signal
252 output SD_CLK; // SD Card Clock
253 //////////////////////// I2C ////////////////////////////////
254 inout I2C_SDAT; // I2C Data
255 output I2C_SCLK; // I2C Clock
256 //////////////////////// PS2 ////////////////////////////////
257 input PS2_DAT; // PS2 Data
258 input PS2_CLK; // PS2 Clock
259 //////////////////// USB JTAG link ////////////////////////////
260 input TDI; // CPLD -> FPGA (data in)
261 input TCK; // CPLD -> FPGA (clk)
262 input TCS; // CPLD -> FPGA (CS)
263 output TDO; // FPGA -> CPLD (data out)
264 //////////////////////// VGA ////////////////////////////
265 output VGA_CLK; // VGA Clock
266 output VGA_HS; // VGA H_SYNC
267 output VGA_VS; // VGA V_SYNC
268 output VGA_BLANK; // VGA BLANK
269 output VGA_SYNC; // VGA SYNC
270 output [9:0] VGA_R; // VGA Red[9:0]
271 output [9:0] VGA_G; // VGA Green[9:0]
272 output [9:0] VGA_B; // VGA Blue[9:0]
273 //////////////// Ethernet Interface ////////////////////////////
274 inout [15:0] ENET_DATA; // DM9000A DATA bus 16Bits
275 output ENET_CMD; // DM9000A Command/Data Select, 0 = Command, 1 = Data
276 output ENET_CS_N; // DM9000A Chip Select
277 output ENET_WR_N; // DM9000A Write
278 output ENET_RD_N; // DM9000A Read
279 output ENET_RST_N; // DM9000A Reset
280 input ENET_INT; // DM9000A Interrupt
281 output ENET_CLK; // DM9000A Clock 25 MHz
282 //////////////////// Audio CODEC ////////////////////////////
283 inout AUD_ADCLRCK; // Audio CODEC ADC LR Clock
284 input AUD_ADCDAT; // Audio CODEC ADC Data
285 inout AUD_DACLRCK; // Audio CODEC DAC LR Clock
286 output AUD_DACDAT; // Audio CODEC DAC Data
287 inout AUD_BCLK; // Audio CODEC Bit-Stream Clock
288 output AUD_XCK; // Audio CODEC Chip Clock
289 //////////////////// TV Devoder ////////////////////////////
290 input [7:0] TD_DATA; // TV Decoder Data bus 8 bits
291 input TD_HS; // TV Decoder H_SYNC
292 input TD_VS; // TV Decoder V_SYNC
293 output TD_RESET; // TV Decoder Reset
294 //////////////////////// GPIO ////////////////////////////////
295 inout [35:0] GPIO_0; // GPIO Connection 0
296 inout [35:0] GPIO_1; // GPIO Connection 1
297
298 // Turn on all display
299 assign LCD_ON = 1'b1;
300 assign LCD_BLON = 1'b1;
301
302 // All inout port turn to tri-state
303 assign DRAM_DQ = 16'hzzzz;
304 assign FL_DQ = 8'hzz;
305 assign SRAM_DQ = 16'hzzzz;
306 assign OTG_DATA = 16'hzzzz;
307 assign LCD_DATA = 8'hzz;
308 assign SD_DAT = 1'bz;
309 assign ENET_DATA = 16'hzzzz;
310 assign AUD_ADCLRCK = 1'bz;
311 assign AUD_DACLRCK = 1'bz;
312 assign AUD_BCLK = 1'bz;
313 assign TD_RESET = 1'b1;
314
315 //////////////////////// For TFT LCD Module ///////////////////////
316 reg [7:0] LCM_DATA; // LCM Data 8 Bits
317 wire LCM_GRST; // LCM Global Reset
318 wire LCM_SHDB; // LCM Sleep Mode
319 wire LCM_DCLK; // LCM Clcok
320 reg LCM_HSYNC; // LCM HSYNC
321 reg LCM_VSYNC; // LCM VSYNC
322 wire LCM_SCLK; // LCM I2C Clock
323 wire LCM_SDAT; // LCM I2C Data
324 wire LCM_SCEN; // LCM I2C Enable
325 wire CLK_18;
326
327 assign GPIO_0[18] = LCM_DATA[6];
328 assign GPIO_0[19] = LCM_DATA[7];
329 assign GPIO_0[20] = LCM_DATA[4];
330 assign GPIO_0[21] = LCM_DATA[5];
331 assign GPIO_0[22] = LCM_DATA[2];
332 assign GPIO_0[23] = LCM_DATA[3];
333 assign GPIO_0[24] = LCM_DATA[0];
334 assign GPIO_0[25] = LCM_DATA[1];
335 assign GPIO_0[26] = LCM_VSYNC;
336 assign GPIO_0[28] = LCM_SCLK;
337 assign GPIO_0[29] = LCM_DCLK;
338 assign GPIO_0[30] = LCM_GRST;
339 assign GPIO_0[31] = LCM_SHDB;
340 assign GPIO_0[33] = LCM_SCEN;
341 assign GPIO_0[35] = LCM_HSYNC;
342
343 Reset_Delay delay1 (.iRST(KEY[0]),.iCLK(CLOCK_50),.oRESET(CPU_RESET));
344 Audio_PLL PLL2 (.inclk0(CLOCK_27),.c0(CLK_18));
345
346 NIOS2_LCD u1(
347 // 1) global signals:
348 .clk_0(CLOCK_50),
349 //.pll_0_lcd(CLK_18),
350 .pll_0_sdram(DRAM_CLK),
351 .pll_0_sysclk(),
352 .reset_n(CPU_RESET),
353
354 // the_DE2_LCM_0
355 .avs_s0_export_i_iCLK_to_the_DE2_LCM_0(CLK_18),
356 .avs_s0_export_o_LCM_DATA_from_the_DE2_LCM_0(LCM_DATA),
357 .avs_s0_export_o_LCM_DCLK_from_the_DE2_LCM_0(LCM_DCLK),
358 .avs_s0_export_o_LCM_GRST_from_the_DE2_LCM_0(LCM_GRST),
359 .avs_s0_export_o_LCM_HSYNC_from_the_DE2_LCM_0(LCM_HSYNC),
360 .avs_s0_export_o_LCM_SHDB_from_the_DE2_LCM_0(LCM_SHDB),
361 .avs_s0_export_o_LCM_VSYNC_from_the_DE2_LCM_0(LCM_VSYNC),
362 //.avs_s0_export_o_iDATA_to_the_DE2_LCM_0,
363
364 // the_LEDG
365 .out_port_from_the_LEDG(LEDG),
366
367 // the_sdram_0
368 .zs_addr_from_the_sdram_0(DRAM_ADDR),
369 .zs_ba_from_the_sdram_0({DRAM_BA_1,DRAM_BA_0}),
370 .zs_cas_n_from_the_sdram_0(DRAM_CAS_N),
371 .zs_cke_from_the_sdram_0(DRAM_CKE),
372 .zs_cs_n_from_the_sdram_0(DRAM_CS_N),
373 .zs_dq_to_and_from_the_sdram_0(DRAM_DQ),
374 .zs_dqm_from_the_sdram_0({DRAM_UDQM,DRAM_LDQM}),
375 .zs_ras_n_from_the_sdram_0(DRAM_RAS_N),
376 .zs_we_n_from_the_sdram_0(DRAM_WE_N),
377
378 // the_sw
379 .in_port_to_the_sw(SW),
380
381 // the_tri_state_bridge_0_avalon_slave
382 .address_to_the_cfi_flash_0(FL_ADDR),
383 .data_to_and_from_the_cfi_flash_0(FL_DQ),
384 .read_n_to_the_cfi_flash_0(FL_OE_N),
385 .select_n_to_the_cfi_flash_0(FL_CE_N),
386 .write_n_to_the_cfi_flash_0(FL_WE_N),
387
388 // the_uart_0
389 .rxd_to_the_uart_0(UART_RXD),
390 .txd_from_the_uart_0(UART_TXD));
391
392 I2S_LCM_Config u2 ( // Host Side
393 .iCLK(CLOCK_50),
394 .iRST_N(KEY[0]),
395 // I2C Side
396 .I2S_SCLK(LCM_SCLK),
397 .I2S_SDAT(GPIO_0[34]),
398 .I2S_SCEN(LCM_SCEN) );
399
400 endmodule
401
二、软件编程(IDE)
这里,我就主要讲代码贴出来,分享一下就可以啦,至于具体的工程,大家学习一下基础东西再说吧。
01
#include <stdio.h>
02
#include <alt_types.h>
03
#include <sys/alt_irq.h>
04
#include <io.h>
05
#include <sys/alt_dma.h>
06
#include <unistd.h> //usleep
07
#include "system.h"
08
//#include <altera_avalon_dma_reg.h>
09
#include <malloc.h>
10
#define FRAME_BUFFER_SIZE 0x38400 //960*240=230400
11
#define STEP 0x38400
12
13
14
volatile
int
complete_flag = 0;
15
void
dma_complete(
void
*handle,
void
*data)
16
{
17
complete_flag=1;
18
//IOWR(DE2_LCM_0_BASE,1,0x01);
19
usleep(1000);
20
}
21
int
main()
22
{
23
int
i;
24
alt_u32 red,green,blue;
25
unsigned
char
*frame_buff_ptr;
26
unsigned
char
*frame_buff_ptr_g;
27
unsigned
char
*frame_buff_ptr_b;
28
alt_dma_txchan tx;
29
complete_flag=1;
30
frame_buff_ptr=(
char
*)
malloc
(FRAME_BUFFER_SIZE);
31
if
(frame_buff_ptr==NULL)
32
{
33
printf
(
"Not enough memory!!\n"
);
34
exit
(1);
35
}
36
//red=255;green=255;blue=255;
37
//red=0;green=0;blue=0;
38
red=255;green=0;blue=0;
39
for
(i=0;i<FRAME_BUFFER_SIZE;i++)
40
{
41
*(frame_buff_ptr+i)=(i%3==0?red:i%3==1?green:blue);
42
}
43
printf
(
"\nBuff initialed!\n"
);
44
tx=alt_dma_txchan_open(
"/dev/dma_0"
);
45
if
(tx==NULL)
46
{
47
printf
(
"Error for initalize txchan!!\n"
);
48
}
49
else
50
{
51
printf
(
"Start DMA...\n"
);
52
alt_dma_txchan_ioctl(tx,ALT_DMA_TX_ONLY_ON,DE2_LCM_0_BASE);
53
alt_dma_txchan_ioctl(tx,ALT_DMA_SET_MODE_8,NULL);
54
while
(1)
55
{
56
if
(complete_flag==1)
57
{
58
complete_flag=0;
59
if
(alt_dma_txchan_send(tx,frame_buff_ptr,STEP,dma_complete,NULL)<0)
60
{
61
printf
(
"error!\n"
);
62
exit
(1);
63
}
64
}
65
}
66
}
67
68
return
0;
69
}
1、首先是分配一帧大小的数组,这里其实,分配的空间是在SDRAM里面,因为我们的运行空间是在SDRAM,这是一个很好的操作SDRAM的方法。
01
frame_buff_ptr=(
char
*)
malloc
(FRAME_BUFFER_SIZE);
02
if
(frame_buff_ptr==NULL)
03
{
04
printf
(
"Not enough memory!!\n"
);
05
exit
(1);
06
}
07
//red=255;green=255;blue=255;
08
//red=0;green=0;blue=0;
09
red=255;green=0;blue=0;
10
for
(i=0;i<FRAME_BUFFER_SIZE;i++)
11
{
12
*(frame_buff_ptr+i)=(i%3==0?red:i%3==1?green:blue);
13
}
2、这里是打开一个DMA传送通道,并将DMA的模式设为8位。
01
tx=alt_dma_txchan_open(
"/dev/dma_0"
);
02
if
(tx==NULL)
03
{
04
printf
(
"Error for initalize txchan!!\n"
);
05
}
06
else
07
{
08
printf
(
"Start DMA...\n"
);
09
alt_dma_txchan_ioctl(tx,ALT_DMA_TX_ONLY_ON,DE2_LCM_0_BASE);
10
alt_dma_txchan_ioctl(tx,ALT_DMA_SET_MODE_8,NULL);
11
......
3、进入while死循环,不断向LCM发送数据
01
while
(1)
02
{
03
if
(complete_flag==1)
04
{
05
complete_flag=0;
06
if
(alt_dma_txchan_send(tx,frame_buff_ptr,STEP,dma_complete,NULL)<0)
07
{
08
printf
(
"error!\n"
);
09
exit
(1);
10
}
11
}
12
}
4、回调函数
1
void
dma_complete(
void
*handle,
void
*data)
2
{
3
complete_flag=1;
4
//IOWR(DE2_LCM_0_BASE,1,0x01);
5
usleep(1000);
6
}
注:这里特意增加了一个usleep(1000),为什么要在这里增加这个呢,首先是由于没有添加这个的时候,出现的不一定是红色的图像,也可能是绿色,也有可能是蓝色,这种现象,我也解释不清楚,但是,当我增加了这个之后,效果就好多了,一直就是理想中的红色,不知道这是为什么?不知道那位达人能给我解答。