1.1 按键输入控制及显示输出主程序:
//==========================================================================
//
// Author: Step
// Module: isp_154
// Description:
// Web: www.stepfapga.com
//--------------------------------------------------------------------------
// Info:
// V1.0---yyyy/mm/dd---Initial version
//
//==========================================================================
//timescale
`timescale 1ns / 1ns
//define
//include
//module
module isp_154 (
input clk_12m,
input key_l, key_r, key_o,
input [7:0] adc_i,
output lcd_csn,
output lcd_sck,
output lcd_sda,
output lcd_res,
output lcd_dcn
);
wire adc_done= 1'b1;
wire sample_done, display_done;
wire sample_en, display_en;
//Arbiter, control sample and display in different time
Arbiter u_Arbiter (
.clk_in (clk_12m ), // system clock
.rst_n_in (1'b1 ), //system reset, active low
.sample_done (sample_done ),
.display_done (display_done ),
.sample_en (sample_en ),
.display_en (display_en )
);
wire adc_done_o;
wire [7:0] trig_data;
Time_Scale u_Time_Scale (
.clk_in (clk_12m ), // system clock
.rst_n_in (1'b1 ), //system reset, active low
.key_l (key_l ), // encoder B
.key_r (key_r ), // encoder OK
.key_o (key_o ), //
.trig_data (trig_data ),
.adc_done (adc_done ),
.adc_done_o (adc_done_o )
);
wire ram_adc_clk_en;
wire [7:0] ram_adc_addr;
wire [7:0] ram_adc_data;
ADC_Sample u_ADC_Sample (
.clk_in (clk_12m ), // system clock
.rst_n_in (1'b1 ), //system reset, active low
.adc_done (adc_done_o ),
.adc_data (adc_i ),
.trig_data (trig_data ),
.sample_en (sample_en ),
.sample_done (sample_done ),
.ram_adc_clk_en (ram_adc_clk_en ),
.ram_adc_addr (ram_adc_addr ),
.ram_adc_data (ram_adc_data )
);
wire [7:0] QA;
wire ram_lcd_clk_en;
wire [7:0] ram_lcd_addr;
wire [7:0] ram_lcd_data;
dp_ram u1 (
.ResetA ( 1'b0 ),
.WrA ( 1'b1 ),
.ClockEnA ( ram_adc_clk_en ),
.ClockA ( clk_12m ),
.AddressA ( ram_adc_addr ),
.DataInA ( ram_adc_data ),
.QA ( QA ),
.ResetB ( 1'b0 ),
.WrB ( 1'b0 ),
.ClockEnB ( ram_lcd_clk_en ),
.ClockB ( clk_12m ),
.AddressB ( ram_lcd_addr ),
.DataInB ( 8'b0 ),
.QB ( ram_lcd_data )
);
LCD_RGB u_LCD_RGB (
.clk ( clk_12m ),
.rst_n ( 1'b1 ),
.display_en ( display_en ),
.display_done ( display_done ),
.ram_lcd_clk_en ( ram_lcd_clk_en ),
.ram_lcd_addr ( ram_lcd_addr ),
.ram_lcd_data ( ram_lcd_data ),
.lcd_csn ( lcd_csn ),
.lcd_res ( lcd_res ),
.lcd_dcn ( lcd_dcn ),
.lcd_sck ( lcd_sck ),
.lcd_sda ( lcd_sda )
);
endmodule //isp_154
1.2 RGB LCD的控制
// --------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------
// Module: LCD_RGB
//
// Author: Step
//
// Description: Drive TFT_RGB_LCD_1.8 to display
//
// Web: www.stepfpga.com
//
// --------------------------------------------------------------------
// Code Revision History :
// --------------------------------------------------------------------
// Version: |Mod. Date: |Changes Made:
// V1.1 |2016/10/30 |Initial ver
// --------------------------------------------------------------------
module LCD_RGB #
(
parameter LCD_W = 8'd240, //
parameter LCD_H = 8'd240 //
)
(
input clk, // system clock
input rst_n, //system reset, active low
input display_en,
output reg display_done,
output reg ram_lcd_clk_en,
output reg [7:0] ram_lcd_addr,
input [7:0] ram_lcd_data,
output reg lcd_csn,
output reg lcd_res,
output lcd_blk,
output reg lcd_dcn,
output reg lcd_sck, // SPI clock
output reg lcd_sda // Master out slave in
);
localparam INIT_DEPTH = 16'd59; // the number of init command and data
localparam RED = 16'hf800;
localparam GREEN = 16'h07e0;
localparam BLUE = 16'h001f;
localparam BLACK = 16'h0000;
localparam WHITE = 16'hffff;
localparam YELLOW = 16'hffe0;
localparam IDLE = 3'd0;
localparam MAIN = 3'd1;
localparam INIT = 3'd2;
localparam SCAN = 3'd3;
localparam WRITE = 3'd4;
localparam DELAY = 3'd5;
localparam LOW = 1'b0;
localparam HIGH = 1'b1;
assign lcd_blk = HIGH; // backlight active high level
wire [15:0] color_t = WHITE;
wire [15:0] color_b = BLACK;
reg [7:0] x_cnt;
reg [7:0] y_cnt;
reg [7:0] ram_data_r;
reg [7:0] ram_data_r1;
reg [8:0] data_reg; //
reg [8:0] reg_setxy [10:0];
reg [8:0] reg_init [58:0];
reg [2:0] cnt_main;
reg [2:0] cnt_init;
reg [2:0] cnt_scan;
reg [4:0] cnt_write;
reg [23:0] cnt_delay;
reg [23:0] num_delay;
reg [6:0] cnt;
reg high_word;
reg [2:0] state;
reg [2:0] state_back;
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
display_done <= 1'b0;
x_cnt <= 8'd0;
y_cnt <= 8'd0;
ram_lcd_clk_en <= 1'b0;
ram_lcd_addr <= 8'd0;
cnt_main <= 3'd0;
cnt_init <= 3'd0;
cnt_scan <= 3'd0;
cnt_write <= 5'd0;
cnt_delay <= 16'd0;
num_delay <= 16'd10;
cnt <= 7'd0;
high_word <= 1'b1;
state <= IDLE;
state_back <= IDLE;
end else begin
case(state)
IDLE:begin
display_done <= 1'b0;
x_cnt <= 8'd0;
y_cnt <= 8'd0;
ram_lcd_clk_en <= 1'b0;
ram_lcd_addr <= 8'd0;
cnt_main <= 3'd0;
cnt_init <= 3'd0;
cnt_scan <= 3'd0;
cnt_write <= 5'd0;
cnt_delay <= 16'd0;
num_delay <= 16'd10;
cnt <= 7'd0;
high_word <= 1'b1;
state <= MAIN;
state_back <= MAIN;
lcd_csn <= 1'b1;
lcd_sck <= LOW;
end
MAIN:begin
case(cnt_main)
3'd0: begin state <= INIT; cnt_main <= cnt_main + 1'b1; end
3'd1: begin display_done <= 1'b0; cnt_main <= cnt_main + 1'b1; end
3'd2: begin
if(display_en) cnt_main <= cnt_main + 1'b1;
else cnt_main <= cnt_main;
end
3'd3: begin state <= SCAN; cnt_main <= cnt_main + 1'b1; end
3'd4: begin display_done <= 1'b1; cnt_main <= 1'b1; end
default: state <= IDLE;
endcase
end
INIT:begin
case(cnt_init)
3'd0: begin lcd_res <= 1'b0; cnt_init <= cnt_init + 1'b1; end
3'd1: begin num_delay <= 24'd1_200_000; state <= DELAY; state_back <= INIT; cnt_init <= cnt_init + 1'b1; end
3'd2: begin lcd_res <= 1'b1; cnt_init <= cnt_init + 1'b1; end
3'd3: begin num_delay <= 24'd1_200_000; state <= DELAY; state_back <= INIT; cnt_init <= cnt_init + 1'b1; end
3'd4: begin
if(cnt>=INIT_DEPTH) begin
cnt <= 7'd0;
cnt_init <= cnt_init + 1'b1;
end else begin
data_reg <= reg_init[cnt];
if(cnt==7'd0) num_delay <= 24'd1_600_000; // long time delay is necessary
cnt <= cnt + 16'd1;
state <= WRITE;
state_back <= INIT;
end
end
3'd5: begin cnt_init <= 1'b0; state <= MAIN; end
default: state <= IDLE;
endcase
end
SCAN:begin
case(cnt_scan)
3'd0: begin
if(cnt >= 11) begin
cnt <= 7'd0;
cnt_scan <= cnt_scan + 1'b1;
end else begin
data_reg <= reg_setxy[cnt];
cnt <= cnt + 7'd1;
state <= WRITE;
state_back <= SCAN;
end
end
3'd1: begin ram_lcd_clk_en <= HIGH; ram_lcd_addr <= y_cnt; cnt_scan <= cnt_scan + 1'b1; end
3'd2: begin cnt_scan <= cnt_scan + 1'b1; end
3'd3: begin ram_lcd_clk_en <= LOW; ram_data_r1 <= ram_data_r; ram_data_r <= ram_lcd_data; cnt_scan <= cnt_scan + 1'b1; end
3'd4: begin
if(x_cnt>=LCD_W) begin
x_cnt <= 8'd0;
if(y_cnt>=LCD_H) begin y_cnt <= 8'd0; cnt_scan <= cnt_scan + 1'b1; end
else begin y_cnt <= y_cnt + 1'b1; cnt_scan <= 3'd1; end
end else begin
if(high_word)
data_reg <= {1'b1,y_cnt&&(y_cnt-1'b1)&&(((x_cnt>=ram_data_r)&&(x_cnt<=ram_data_r1))||((x_cnt<=ram_data_r)&&(x_cnt>=ram_data_r1)))? color_t[15:8]:color_b[15:8]};
else begin
data_reg <= {1'b1,y_cnt&&(y_cnt-1'b1)&&(((x_cnt>=ram_data_r)&&(x_cnt<=ram_data_r1))||((x_cnt<=ram_data_r)&&(x_cnt>=ram_data_r1)))? color_t[7:0]:color_b[7:0]};
x_cnt <= x_cnt + 1'b1;
end
/* //dot
if(high_word)
data_reg <= {1'b1,(x_cnt==ram_lcd_data)? color_t[15:8]:color_b[15:8]};
else begin
data_reg <= {1'b1,(x_cnt==ram_lcd_data)? color_t[7:0]:color_b[7:0]};
x_cnt <= x_cnt + 1'b1;
end
*/
high_word <= ~high_word;
state <= WRITE;
state_back <= SCAN;
end
end
3'd5: begin cnt_scan <= 1'b0; state <= MAIN; end
default: state <= IDLE;
endcase
end
WRITE:begin
if(cnt_write >= 5'd18) cnt_write <= 1'b0;
else cnt_write <= cnt_write + 1'b1;
case(cnt_write)
//lock data_reg
5'd0: begin lcd_dcn <= data_reg[8]; lcd_csn <= 1'b0; end
5'd1: begin lcd_sck <= LOW; lcd_sda <= data_reg[7]; end
5'd2: begin lcd_sck <= HIGH; end
5'd3: begin lcd_sck <= LOW; lcd_sda <= data_reg[6]; end
5'd4: begin lcd_sck <= HIGH; end
5'd5: begin lcd_sck <= LOW; lcd_sda <= data_reg[5]; end
5'd6: begin lcd_sck <= HIGH; end
5'd7: begin lcd_sck <= LOW; lcd_sda <= data_reg[4]; end
5'd8: begin lcd_sck <= HIGH; end
5'd9: begin lcd_sck <= LOW; lcd_sda <= data_reg[3]; end
5'd10: begin lcd_sck <= HIGH; end
5'd11: begin lcd_sck <= LOW; lcd_sda <= data_reg[2]; end
5'd12: begin lcd_sck <= HIGH; end
5'd13: begin lcd_sck <= LOW; lcd_sda <= data_reg[1]; end
5'd14: begin lcd_sck <= HIGH; end
5'd15: begin lcd_sck <= LOW; lcd_sda <= data_reg[0]; end
5'd16: begin lcd_sck <= HIGH; end
5'd17: begin lcd_sck <= LOW; end
5'd18: begin lcd_csn <= 1'b1; state <= DELAY; end
default: state <= IDLE;
endcase
end
DELAY:begin
if(cnt_delay >= num_delay) begin
cnt_delay <= 16'd0;
num_delay <= 16'd10;
state <= state_back;
end else cnt_delay <= cnt_delay + 1'b1;
end
default:state <= IDLE;
endcase
end
end
// data for setxy
always @(*) begin
reg_setxy[0] = {1'b0,8'h2a};
reg_setxy[1] = {1'b1,8'h00};
reg_setxy[2] = {1'b1,8'h50};
reg_setxy[3] = {1'b1,8'h01};
reg_setxy[4] = {1'b1,8'h3f};
reg_setxy[5] = {1'b0,8'h2b};
reg_setxy[6] = {1'b1,8'h00};
reg_setxy[7] = {1'b1,8'h00};
reg_setxy[8] = {1'b1,8'h00};
reg_setxy[9] = {1'b1,LCD_H-8'h01};
reg_setxy[10] = {1'b0,8'h2c};
end
// data for init
always @(*) begin
reg_init[0] = {1'b0,8'h11};
reg_init[1] = {1'b0,8'h36};
reg_init[2] = {1'b1,8'ha0};
reg_init[3] = {1'b0,8'h3A};
reg_init[4] = {1'b1,8'h05};
reg_init[5] = {1'b0,8'hB2};
reg_init[6] = {1'b1,8'h0C};
reg_init[7] = {1'b1,8'h0C};
reg_init[8] = {1'b1,8'h00};
reg_init[9] = {1'b1,8'h33};
reg_init[10] = {1'b1,8'h33};
reg_init[11] = {1'b0,8'hB7};
reg_init[12] = {1'b1,8'h35};
reg_init[13] = {1'b0,8'hBB};
reg_init[14] = {1'b1,8'h19};
reg_init[15] = {1'b0,8'hC0};
reg_init[16] = {1'b1,8'h2C};
reg_init[17] = {1'b0,8'hC2};
reg_init[18] = {1'b1,8'h01};
reg_init[19] = {1'b0,8'hC3};
reg_init[20] = {1'b1,8'h12};
reg_init[21] = {1'b0,8'hC4};
reg_init[22] = {1'b1,8'h20};
reg_init[23] = {1'b0,8'hC6};
reg_init[24] = {1'b1,8'h0F};
reg_init[25] = {1'b0,8'hD0};
reg_init[26] = {1'b1,8'hA4};
reg_init[27] = {1'b1,8'hA1};
reg_init[28] = {1'b0,8'hE0};
reg_init[29] = {1'b1,8'hD0};
reg_init[30] = {1'b1,8'h04};
reg_init[31] = {1'b1,8'h0D};
reg_init[32] = {1'b1,8'h11};
reg_init[32] = {1'b1,8'h13};
reg_init[33] = {1'b1,8'h2B};
reg_init[34] = {1'b1,8'h3F};
reg_init[35] = {1'b1,8'h54};
reg_init[36] = {1'b1,8'h4C};
reg_init[37] = {1'b1,8'h18};
reg_init[38] = {1'b1,8'h0D};
reg_init[39] = {1'b1,8'h0B};
reg_init[40] = {1'b1,8'h1F};
reg_init[41] = {1'b1,8'h23};
reg_init[42] = {1'b0,8'hE1};
reg_init[43] = {1'b1,8'hD0};
reg_init[44] = {1'b1,8'h04};
reg_init[45] = {1'b1,8'h0C};
reg_init[46] = {1'b1,8'h11};
reg_init[47] = {1'b1,8'h13};
reg_init[48] = {1'b1,8'h2C};
reg_init[49] = {1'b1,8'h3F};
reg_init[50] = {1'b1,8'h44};
reg_init[51] = {1'b1,8'h51};
reg_init[52] = {1'b1,8'h2F};
reg_init[53] = {1'b1,8'h1F};
reg_init[54] = {1'b1,8'h1F};
reg_init[55] = {1'b1,8'h20};
reg_init[56] = {1'b1,8'h23};
reg_init[57] = {1'b0,8'h21};
reg_init[58] = {1'b0,8'h29};
end
endmodule