|
本帖最后由 cruelfox 于 2015-2-27 09:54 编辑
5年前买的160x64点阵单色液晶模块,没有控制器,没有资料。当初尝试单片机驱动,以失败而告终。最近想起来这个模块,搜了一下,发现有日本人将它玩起来了:http://d.hatena.ne.jp/libio50m-EX/20111106 。此外,在国内某论坛上,有人贴了个51程序(但是图片已看不到了): http://bbs.mydigit.cn/read.php?tid=324300 。根据这线索我写了个FPGA代码来尝试驱动。
模块共有DR2, CL2, M, DL1, CL1 五条信号线,经过两晚上折腾,终于驱动成功。
- module lcddriver(clk, dl1, m, cl1, cl2, dr2, bmp_byte, vram_addr);
- input clk;
- output reg dl1;
- output reg m;
- output cl1;
- output cl2;
- output reg dr2;
- input [7:0] bmp_byte;
- output reg [10:0] vram_addr=11'd1;
- reg [7:0] col_cnt;
- reg [5:0] row_cnt;
- reg col_latch;
- always @(posedge clk) begin
- if(col_cnt<8'd159) begin
- col_cnt <= col_cnt + 1'b1;
- col_latch <= 0;
- end
- else begin
- col_cnt <= 0;
- // if(row_cnt<7'd79)
- row_cnt <= row_cnt + 1'b1;
- // else
- // row_cnt <= 0;
- col_latch <= 1;
- end
- end
- always @(posedge clk) begin
- if(col_cnt==8'd159) begin
- if(row_cnt==0)
- dl1 <= 1;
- else
- dl1 <= 0;
- end
- end
- /* test patterns
- always @(posedge clk) begin
- // if (col_cnt[3]!=row_cnt[3]) // pattern 8x8
- // if (col_cnt[3:0] < row_cnt[3:0]) // pattern triangle
- if( ( col_cnt >= row_cnt+16 ) && (col_cnt <= row_cnt + 96)) // pattern
- dr2 <= 1;
- else
- dr2 <= 0;
- end
- */
- reg [11:0] ac;
- always @(posedge clk) begin
- if(ac>=1600) begin
- m <= ~m;
- ac <= 1;
- end
- else
- ac <= ac+1'b1;
- end
- assign cl2 = clk;
- assign cl1 = col_latch & (~cl2);
- reg [2:0] bitcnt=1;
- reg [7:0] sr;
- always @(posedge clk) begin
- dr2 <= sr[7];
- bitcnt <= bitcnt+1'b1;
- if(bitcnt==3'd0) begin
- sr <= bmp_byte;
- if(vram_addr >=1279)
- vram_addr <= 0;
- else
- vram_addr <= vram_addr + 1'b1;
- end
- else begin
- sr <= {sr[6:0],1'b0};
- end
- end
- endmodule
复制代码 CL2, DR2 用来串行输入显示数据,分别是时钟和数据。我用的时钟是50MHz系统时钟分频得到的390kHz。在每行160位数据移位进去后,需要锁存一下,产生列驱动。这个锁存信号是CL1,CL1还有一个作用是行扫描驱动的移位,而行扫描的数据是DL1(在第0行时为1,其它时候为0)。
下面是这个demo的顶层模块,vram是一个双端口RAM。写RAM没启用,demo只能显示初始化的数据。
- module lcddummy(clk50, dl1, m, cl1, cl2, dr2);
- input clk50;
- output dl1;
- output m;
- output cl1;
- output cl2;
- output dr2;
- reg [6:0] clcnt;
- always @(posedge clk50)
- clcnt <= clcnt + 1'b1;
- wire [10:0] raddr;
- wire [7:0] rdata;
- lcddriver dummy(.clk(clcnt[6]),
- .dl1(dl1),
- .m(m),
- .cl1(cl1),
- .cl2(cl2),
- .dr2(dr2),
- .bmp_byte(rdata),
- .vram_addr(raddr));
- /* --- fake ram
- always @(posedge clcnt[6]) begin
- if( raddr < 600)
- rdata <= raddr[7:0];
- else
- rdata <= 8'h80;
- end
- */
- vram bitmap(.rdclock(clcnt[6]),
- .rdaddress(raddr),
- .q(rdata),
- .wren(0));
- endmodule
复制代码
|
赞赏
-
2
查看全部赞赏
-
|