完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1、测试说明:
收到安路的开发板快一个月了,由于近期工作较忙,一直没时间试用,昨天正好抽空了半天时间想好好研究研究。本来计划的是将我之前Xilinx上的程序进行移植,但是由于资源问题无法实施,正好手头有一块12846的点阵LCD,就先拿它入手吧。 为了尽量多的测试各种资源,我的设计思路是这样的: 程序包含三个子模块,一个时钟分频模块,一个LCD的驱动控制模块,一个指令数据控制模块(该模块里还有一个BRAM,用来存储显示数据),结构如下图所示: LCD的控制时序如下所示: 2、测试代码: 顶层模块 module lcd_test( input clk_25M, input rst_n, input key_start, output lcd_e, output lcd_rs, output lcd_rw, output [7:0]lcd_db ); wire clk_1M; clk_div U1( .clk_25M(clk_25M), .rst_n(rst_n), .clk_1M(clk_1M) ); wire over; wire busy; wire rw_select; //r:1'b1 w:1'b0 wire di_select; //d:1'b1 i:1'b0; wire w_start; wire [7:0]w_data; lcd_ctrl U2( .clk(clk_1M), .rst_n(rst_n), .w_data(w_data), .rw_select(rw_select), .di_select(di_select), .start(w_start), .lcd_rs(lcd_rs), .lcd_rw(lcd_rw), .lcd_e(lcd_e), .DB_data(lcd_db), .over(over), .busy(busy) ); command_ctrl U3( .clk_25M(clk_25M), .rst_n(rst_n), .key_start(key_start), .busy(busy), .over(over), .rw_select(rw_select), .di_select(di_select), .w_start(w_start), .w_data(w_data) ); endmodule 时钟分频子模块: module clk_div( input clk_25M, input rst_n, output reg clk_1M ); reg[4:0]cnt; always@(posedge clk_25M or negedge rst_n) if(!rst_n) cnt[4:0] <= 5'd0; else if(cnt[4:0] <5'd25) cnt[4:0] <= cnt[4:0] + 1'b1; else cnt[4:0] <= 5'd0; always@(posedge clk_25M or negedge rst_n) if(!rst_n) clk_1M <= 1'b0; else if(cnt[4:0] < 5'd12) clk_1M <= 1'b1; else clk_1M <= 1'b0; endmodule LCD驱动子模块: module lcd_ctrl( input clk, //1M 1000ns input rst_n, input [7:0] w_data, input rw_select, input di_select, input start, output reg lcd_rs, output reg lcd_rw, output reg lcd_e, output reg [7:0]DB_data, output reg over, output reg busy ); reg[1:0]cnt; reg[5:0]CS; reg[5:0]NS; parameter IDLE = 6'h1; parameter PREPARE = 6'h2; parameter SETSTATE = 6'h4; parameter ENABLE = 6'h8; parameter LOCKDATA = 6'h10; parameter OVER = 6'h20; //监测一次写操作的开始标识上升沿 reg start_r1; reg start_r2; wire start_u; always@(posedge clk) begin start_r1 <= start; start_r2 <= start_r1; end assign start_u = start_r1 && (~start_r2); always@(posedge clk or negedge rst_n) if(!rst_n) CS[5:0] <= IDLE; else CS[5:0] <= NS[5:0]; always@(CS[5:0] or start_u or cnt[1:0]) begin NS[5:0] = IDLE; case(CS) IDLE: NS = start_u ? PREPARE : IDLE; PREPARE: NS = SETSTATE; SETSTATE: NS = ENABLE; ENABLE: NS = LOCKDATA; LOCKDATA: NS = cnt[0] ? OVER : LOCKDATA; OVER: NS = IDLE; default: NS = IDLE; endcase end always@(posedge clk) begin case(NS) IDLE: begin lcd_e <= 1'b0; lcd_rs <= 1'b0; lcd_rw <= 1'b0; DB_data[7:0] <= 8'h0; cnt[1:0] <= 2'd0; over <= 1'b0; busy <= 1'b0; end PREPARE: begin lcd_e <= 1'b0; busy <= 1'b1; over <= 1'b0; end SETSTATE: begin lcd_rs <= di_select ? 1'b1 : 1'b0; lcd_rw <= rw_select ? 1'b1 : 1'b0; end ENABLE: begin lcd_e <= 1'b1; DB_data[7:0] <= w_data[7:0]; end LOCKDATA: begin lcd_e <= 1'b0; cnt[1:0] <= cnt[1:0] + 1'b1; end OVER: begin lcd_e <= 1'b0; cnt[1:0] <= 2'b00; over <= 1'b1; busy <= 1'b0; end endcase end endmodule 指令数据控制子模块: module command_ctrl( input clk_25M, input rst_n, input key_start, input busy, input over, output reg rw_select, output reg di_select, output reg w_start, output reg [7:0]w_data ); //检测开关下降沿 reg key_r1; reg key_r2; wire keystart; always@(posedge clk_25M) begin key_r1 <= key_start; key_r2 <= key_r1; end assign keystart = key_r2 && (~key_r1); //监测一次写操作的结束标识上升沿 reg over_r1; reg over_r2; wire over_u; always@(posedge clk_25M) begin over_r1 <= over; over_r2 <= over_r1; end assign over_u = over_r1 && (~over_r2); //LCD指令集 reg[7:0]command[8:0]; initial begin command[0] = 8'h01; //清屏 command[1] = 8'h02; //地址归位 command[2] = 8'h07; //光标右移,整体显示移动 command[3] = 8'h0f; //整体显示、光标显示、光标位置反白且闪烁 command[4] = 8'h14; //光标右移 command[5] = 8'h30; //8b控制,基本指令动作集 command[6] = 8'h80; //设定DDRAM地址 command[7] = 8'hB8;//设置页地址,第一页 command[8] = 8'h40;//设置列地址,第一列 end parameter IDLE = 6'h1; parameter START_I = 6'h2; parameter TURN_I = 6'h4; parameter READ_DATA = 6'h8; parameter START_D = 6'h10; parameter TURN_D = 6'h20; reg[5:0]CS; reg[5:0]NS; reg[3:0]cnt; reg[1:0]cnt1; reg[3:0]cnt2; reg[3:0]cnt3; reg[2:0]i; reg clka; reg [6:0]addra; wire[7:0]ramdata; always@(posedge clk_25M or negedge rst_n) if(!rst_n) CS <= IDLE; else CS <= NS; always@(CS or keystart or over_u or cnt[3:0] or cnt1[1:0] or cnt2[3:0] or cnt3[3:0]) begin NS = IDLE; case(CS) IDLE: NS = keystart ? START_I : IDLE; START_I: NS = over_u ? TURN_I : START_I; TURN_I: NS = (cnt2[3]) ? READ_DATA : START_I; READ_DATA: NS = (cnt1[1:0] == 2'b11) ? START_D : READ_DATA; START_D: NS = over_u ? TURN_D : START_D; TURN_D: NS = (cnt3[3:0] == 4'hf) ? IDLE : READ_DATA; default: NS = IDLE; endcase end always@(posedge clk_25M) begin case(NS) IDLE: begin rw_select <= 1'b0; di_select <= 1'b0; w_start <= 1'b0; w_data[7:0] <= 8'd0; cnt[3:0] <= 4'd0; cnt1[1:0] <= 2'd0; cnt2[3:0] <= 4'd0; cnt3[3:0] <= 4'd0; i[2:0] <= 3'd0; clka <= 1'b0; addra[6:0] <= 7'd0; end START_I: begin w_start <= 1'b1; rw_select <= 1'b0; di_select <= 1'b0; w_data[7:0] <= command; end TURN_I: begin i[2:0] <= i[2:0] + 1'b1; cnt2[2:0] <= cnt2[2:0] + 1'b1; end READ_DATA: begin clka <= 1'b1; cnt1[1:0] <= cnt1[1:0] + 1'b1; end START_D: begin w_start <= 1'b1; rw_select <= 1'b0; di_select <= 1'b1; w_data[7:0] <= ramdata[7:0]; clka <= 1'b0; end TURN_D: begin cnt3[3:0] <= cnt3[3:0] + 1'b1; cnt1[1:0] <= 2'd0; clka <= 1'b0; addra[6:0] <= addra[6:0] + 1'b1; end endcase end dataram U1( .doa(ramdata), .dia(), .addra(addra), .wea(), .clka(clka) ); endmodule 3、调试 由于时间紧张,这次的程序还没来得及进行板级调试,所以程序还未进行验证。好在还有一个月的试用期,争取下个月抽出多一些的时间进行调试验证,并再增加一些新的功能,丰富下测试内容。 4、体会 关于这次安路的试用板测试,因为时间缘故只是短暂的体验,但也有几点体会。 优点: 1)安路的TD工具真小,安装特别方便快捷; 2)编译速度也比较快,操作也算简单明了。 缺点: 1)不知道是我不会使用的缘故还是别的原因,我发现当程序综合或者布线等有错误的时候,根据报错信息进行修改,然后重新综合、布线等等,之前的 报错信息还在,这就优点头大; 2)在编写代码的时候,对特定的标识有自动判断并补全的功能,但是用户自定义的一些信号,没有该功能。 |
|
相关推荐
|
|
你正在撰写讨论
如果你是对讨论或其他讨论精选点评或询问,请使用“评论”功能。
1333 浏览 1 评论
助力AIoT应用:在米尔FPGA开发板上实现Tiny YOLO V4
1041 浏览 0 评论
2408 浏览 1 评论
2113 浏览 0 评论
矩阵4x4个按键,如何把识别结果按编号01-16(十进制)显示在两个七段数码管上?
2376 浏览 0 评论
1873 浏览 49 评论
6009 浏览 113 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 15:27 , Processed in 0.567899 second(s), Total 63, Slave 45 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号