(原创)NIOSII IDE下控制LCM显示

摘要:

  本次试验主要是在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 ornegedge 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 elseif (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 ornegedge 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 ornegedge 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 ornegedge 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 elseif (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 ornegedge 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 ornegedge 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)

  这里,我就主要讲代码贴出来,分享一下就可以啦,至于具体的工程,大家学习一下基础东西再说吧。

#include <stdio.h>
#include <alt_types.h>
#include <sys/alt_irq.h>
#include <io.h>
#include <sys/alt_dma.h>
#include <unistd.h> //usleep
#include "system.h"
//#include <altera_avalon_dma_reg.h>
#include <malloc.h>
#define FRAME_BUFFER_SIZE 0x38400 //960*240=230400
#define STEP 0x38400


volatile int complete_flag = 0;
void dma_complete(void *handle,void *data)
{
	complete_flag=1;
	//IOWR(DE2_LCM_0_BASE,1,0x01);
	usleep(1000);
}
int main()
{
  int i;
  alt_u32 red,green,blue;
  unsigned char *frame_buff_ptr;
  unsigned char *frame_buff_ptr_g;
  unsigned char *frame_buff_ptr_b;
  alt_dma_txchan tx;
  complete_flag=1;
  frame_buff_ptr=(char*)malloc(FRAME_BUFFER_SIZE);
  if(frame_buff_ptr==NULL)
  {
	  printf("Not enough memory!!\n");
	  exit(1);
  }
  //red=255;green=255;blue=255;
  //red=0;green=0;blue=0;
  red=255;green=0;blue=0;
  for(i=0;i<FRAME_BUFFER_SIZE;i++)
  {
	  *(frame_buff_ptr+i)=(i%3==0?red:i%3==1?green:blue);
  }
  printf("\nBuff initialed!\n");
  tx=alt_dma_txchan_open("/dev/dma_0");
  if(tx==NULL)
  {
	  printf("Error for initalize txchan!!\n");
  }
  else
  {
	  printf("Start DMA...\n");
	  alt_dma_txchan_ioctl(tx,ALT_DMA_TX_ONLY_ON,DE2_LCM_0_BASE);
	  alt_dma_txchan_ioctl(tx,ALT_DMA_SET_MODE_8,NULL);
	  while(1)
	  {
		  if(complete_flag==1)
		  {
			  complete_flag=0;
			  if(alt_dma_txchan_send(tx,frame_buff_ptr,STEP,dma_complete,NULL)<0)
			  {
				  printf("error!\n");
				  exit(1);
			  }
		  }
	  }
  }

  return 0;
}

 1、首先是分配一帧大小的数组,这里其实,分配的空间是在SDRAM里面,因为我们的运行空间是在SDRAM,这是一个很好的操作SDRAM的方法。

  frame_buff_ptr=(char*)malloc(FRAME_BUFFER_SIZE);
  if(frame_buff_ptr==NULL)
  {
	  printf("Not enough memory!!\n");
	  exit(1);
  }
  //red=255;green=255;blue=255;
  //red=0;green=0;blue=0;
  red=255;green=0;blue=0;
  for(i=0;i<FRAME_BUFFER_SIZE;i++)
  {
	  *(frame_buff_ptr+i)=(i%3==0?red:i%3==1?green:blue);
  }

 2、这里是打开一个DMA传送通道,并将DMA的模式设为8位。

tx=alt_dma_txchan_open("/dev/dma_0");
  if(tx==NULL)
  {
	  printf("Error for initalize txchan!!\n");
  }
  else
  {
	  printf("Start DMA...\n");
	  alt_dma_txchan_ioctl(tx,ALT_DMA_TX_ONLY_ON,DE2_LCM_0_BASE);
	  alt_dma_txchan_ioctl(tx,ALT_DMA_SET_MODE_8,NULL);
......

 3、进入while死循环,不断向LCM发送数据

	  while(1)
	  {
		  if(complete_flag==1)
		  {
			  complete_flag=0;
			  if(alt_dma_txchan_send(tx,frame_buff_ptr,STEP,dma_complete,NULL)<0)
			  {
				  printf("error!\n");
				  exit(1);
			  }
		  }
	  }

  4、回调函数

void dma_complete(void *handle,void *data)
{
	complete_flag=1;
	//IOWR(DE2_LCM_0_BASE,1,0x01);
	usleep(1000);
}

    注:这里特意增加了一个usleep(1000),为什么要在这里增加这个呢,首先是由于没有添加这个的时候,出现的不一定是红色的图像,也可能是绿色,也有可能是蓝色,这种现象,我也解释不清楚,但是,当我增加了这个之后,效果就好多了,一直就是理想中的红色,不知道这是为什么?不知道那位达人能给我解答。 

原文地址:https://www.cnblogs.com/yingfang18/p/1880155.html