LCD1602写自定义字符的Verilog源码
开发工具:Quartus II 9.1;
仿真软件:Questa Sim 10.0c;
硬件平台:Terasic DE2-115(EP2C35F672C6);
外设:hd44780控制器lcd1602;
3个工程文件:"lcd1602_cgram_controller.v" + "lcd1602_cgram_driver.v" + "lcd1602_cgram_driver_tsb.v";
设计思路:
底层直接操作lcd1602的模块为"*_controller.v"文件,三段式状态机,完成初始化液晶工作模式(无光标、5X8、2行...)、在CGRAM写入自定义的8个字符(源文件里条形图,可用于音频FFT波形图显示),完成CGRAM写数据之后进入通用的显示状态,每次显示完一个字符产生的ack信号;
"_driver.v"完成循环调用显示8个自定义字符;
"_driver_tsb.v"完成仿真时的驱动(原本是和"_driver.v"在同一个文件,为了方便后续综合,分开了);
注意事项:
系统工作频率为50MHz,lcd操作的指令、数据周期为2ms(1ms下也能用);
CYCLONEII的芯片上电未复位之前的寄存器是0,因此程序下载到板子上的时候液晶是不显示的,没有复位引脚的需要自行设计软件复位;
lcd_on,lcd_blon为DE2-115板子特有设计;
源码1...
- `timescale ns / ps
- //`define SIM
- `define SYS_CLK 50_000_000
- //achieve lcd1602 cgram display
- //author wuyuehang1990
- //version 0.1
- module lcd1602_cgram_controller(
- sys_clk,
- sys_rst_n,
- sys_dat_i,
- sys_addr_i,
- lcd_ack_o,
- lcd_en,
- lcd_rw,
- lcd_rs,
- lcd_bus,
- lcd_on,
- lcd_blon
- );
- input sys_clk;
- input sys_rst_n;
- input [:] sys_dat_i;//CGRAM ONLY DISP 8 DIFFERENT FONTS//00~07
- input [:] sys_addr_i;//DDRAM ADDR
- output reg lcd_ack_o;
- //lcd interface
- output lcd_en;
- output lcd_rw;
- output reg lcd_rs;
- output reg [:] lcd_bus;
- //spec io
- output lcd_on;
- output lcd_blon;
- `ifdef SIM
- parameter ST_WIDTH = ;
- parameter CLR = "CLR.....";
- parameter FUNC = "FUNC....";
- parameter ONOFF = "ON/OFF..";
- parameter ENTRY = "ENTRY...";
- parameter SETCGRAM = "SETCGRAM";
- parameter WRCGRAM = "WR_CGRAM";
- parameter SETDDRAM = "SETDDRAM";
- parameter WRDDRAM = "WR_DDRAM";
- parameter ACK = "ACK.....";
- `else
- `define FSM
- parameter ST_WIDTH = `FSM;
- parameter CLR = `FSM'b0_0000_0001;//01
- parameter FUNC = `FSM'b0_0000_0010;//38(8BUS-2LINE) 37(8BUS-1LINE)
- parameter ONOFF = `FSM'b0_0000_0100;//0C(ON-SHINE)
- parameter ENTRY = `FSM'b0_0000_1000;//06(DISP_FIXED-CURSOR_SHIFT)
- parameter SETCGRAM = `FSM'b0_0001_0000;
- parameter WRCGRAM = `FSM'b0_0010_0000;
- parameter SETDDRAM = `FSM'b0_0100_0000;
- parameter WRDDRAM = `FSM'b0_1000_0000;
- parameter ACK = `FSM'b1_0000_0000;
- `endif
- //generate 1KHz(1ms)
- reg [:] cnt_1KHz=;
- reg clk_1KHz=;
- reg pulse1ms=;
- always @ (posedge sys_clk) begin
- if(sys_rst_n == 'b0) begin
- cnt_1KHz <= ;
- end
- else if(cnt_1KHz > 'd99999) begin
- cnt_1KHz <= ;
- end
- else begin
- cnt_1KHz <= cnt_1KHz + 'd1;
- end
- end
- always @ (posedge sys_clk) begin
- if(cnt_1KHz < 'd49999) begin
- clk_1KHz <= 'd1;
- end
- else begin
- clk_1KHz <= 'd0;
- end
- end
- always @ (posedge sys_clk) begin
- if(cnt_1KHz == 'd99999) pulse1ms <= 1'd1;
- else pulse1ms <= 'd0;
- end
- //generate lcd_en,lcd_rw;
- assign lcd_en = clk_1KHz;
- assign lcd_rw = 'b0;
- //generate spec io
- assign lcd_on = 'b1;
- assign lcd_blon = 'b1;
- //FSM
- reg [:] cnt64=;//count 64 hex char
- reg [ST_WIDTH-:] c_st = FUNC;
- reg [ST_WIDTH-:] n_st = FUNC;
- //fsm-1
- always @ (posedge sys_clk) begin
- if('b0 == sys_rst_n) c_st <= FUNC;
- else c_st <= n_st;
- end
- //fsm-2
- always @ (*) begin
- n_st = FUNC;
- case(c_st)
- FUNC:begin
- n_st = (pulse1ms == 'b1)?ONOFF:FUNC;
- end
- ONOFF:begin
- n_st = (pulse1ms == 'b1)?ENTRY:ONOFF;
- end
- ENTRY:begin
- n_st = (pulse1ms == 'b1)?CLR:ENTRY;
- end
- CLR:begin
- n_st = (pulse1ms == 'b1)?SETCGRAM:CLR;
- end
- SETCGRAM:begin
- n_st = (pulse1ms == 'b1)?WRCGRAM:SETCGRAM;
- end
- WRCGRAM:begin
- if((pulse1ms == 'b1) && (cnt64 == 6'd63))
- n_st = SETDDRAM;
- else if(pulse1ms == 'b1)
- n_st = SETCGRAM;
- else
- n_st = WRCGRAM;
- end
- SETDDRAM:begin
- n_st = (pulse1ms == 'b1)?WRDDRAM:SETDDRAM;
- end
- WRDDRAM:begin
- n_st = (pulse1ms == 'b1)?ACK:WRDDRAM;
- end
- ACK:begin
- n_st = SETDDRAM;
- end
- default:begin
- n_st = FUNC;
- end
- endcase
- end
- //FSM-3
- //generate lcd_bus lcd_rs and lcd_ack
- always @ (posedge sys_clk) begin
- if('b0 == sys_rst_n) begin
- lcd_ack_o <= ;
- lcd_rs <= ;
- lcd_bus <= 'h38;
- cnt64 <= ;
- end
- else begin
- case(n_st)
- FUNC:begin
- lcd_rs <= ;
- lcd_ack_o <= ;
- lcd_bus <= 'h38;//3c(2-line-5*10)//38(2-line-5*8)
- cnt64 <= 'd63;
- end
- ONOFF:begin
- lcd_rs <= ;
- lcd_ack_o <= ;
- lcd_bus <= 'h0d;//no cursor
- cnt64 <= 'd63;
- end
- ENTRY:begin
- lcd_rs <= ;
- lcd_ack_o <= ;
- lcd_bus <= 'h06;
- cnt64 <= 'd63;
- end
- CLR:begin
- lcd_rs <= ;
- lcd_ack_o <= ;
- lcd_bus <= 'h01;
- cnt64 <= 'd63;
- end
- SETCGRAM:begin
- lcd_ack_o <= ;
- lcd_rs <= ;
- cnt64 <= (pulse1ms == 'b1)?cnt64 + 1'd1:cnt64;
- lcd_bus <= {'b01,cnt64};
- end
- WRCGRAM:begin
- lcd_ack_o <= ;
- lcd_rs <= ;
- cnt64 <= cnt64;
- /*
- case(cnt64)
- 6'd0,6'd1,6'd2,6'd3,6'd4,6'd5,6'd6,6'd7:lcd_bus <= 8'h00;//empty
- 6'd8,6'd9,6'd10,6'd11,6'd12,6'd13:lcd_bus <= 8'h00;
- 6'd14:lcd_bus <= 8'h1f;
- 6'd15:lcd_bus <= 8'h00;//1step
- 6'd16,6'd17,6'd18,6'd19,6'd20:lcd_bus <= 8'h00;
- 6'd21,6'd22:lcd_bus <= 8'h1f;
- 6'd23:lcd_bus <= 8'h00;//2step
- 6'd24,6'd25,6'd26,6'd27:lcd_bus <= 8'h00;
- 6'd28,6'd29,6'd30:lcd_bus <= 8'h1f;
- 6'd31:lcd_bus <= 8'h00;//3step
- 6'd32,6'd33,6'd34:lcd_bus <= 8'h00;
- 6'd35,6'd36,6'd37,6'd38:lcd_bus <= 8'h1f;
- 6'd39:lcd_bus <= 8'h00;//4step
- 6'd40,6'd41:lcd_bus <= 8'h00;
- 6'd42,6'd43,6'd44,6'd45,6'd46:lcd_bus <= 8'h1f;
- 6'd47:lcd_bus <= 8'h00;//5step
- 6'd48:lcd_bus <= 8'h00;
- 6'd49,6'd50,6'd51,6'd52,6'd53,6'd54:lcd_bus <= 8'h1f;
- 6'd55:lcd_bus <= 8'h00;//6step
- 6'd56,6'd57,6'd58,6'd59,6'd60,6'd61,6'd62:lcd_bus <= 8'h1f;
- 6'd63:lcd_bus <= 8'h00;//7step
- endcase
- */
- case(cnt64)
- 'd0,6'd1,'d2,6'd3,'d4,6'd5,'d6:lcd_bus <= 8'h00;
- 'd7:lcd_bus <= 8'h1f;//s1
- 'd8,6'd9,'d10,6'd11,'d12,6'd13:lcd_bus <= 'h00;
- 'd14:lcd_bus <= 8'h1f;
- 'd15:lcd_bus <= 8'h1f;//s2
- 'd16,6'd17,'d18,6'd19,'d20:lcd_bus <= 8'h00;
- 'd21,6'd22:lcd_bus <= 'h1f;
- 'd23:lcd_bus <= 8'h1f;//s3
- 'd24,6'd25,'d26,6'd27:lcd_bus <= 'h00;
- 'd28,6'd29,'d30:lcd_bus <= 8'h1f;
- 'd31:lcd_bus <= 8'h1f;//4step
- 'd32,6'd33,'d34:lcd_bus <= 8'h00;
- 'd35,6'd36,'d37,6'd38:lcd_bus <= 'h1f;
- 'd39:lcd_bus <= 8'h1f;//5step
- 'd40,6'd41:lcd_bus <= 'h00;
- 'd42,6'd43,'d44,6'd45,'d46:lcd_bus <= 8'h1f;
- 'd47:lcd_bus <= 8'h1f;//6step
- 'd48:lcd_bus <= 8'h00;
- 'd49,6'd50,'d51,6'd52,'d53,6'd54:lcd_bus <= 'h1f;
- 'd55:lcd_bus <= 8'h1f;//7step
- 'd56,6'd57,'d58,6'd59,'d60,6'd61,'d62:lcd_bus <= 8'h1f;
- 'd63:lcd_bus <= 8'h1f;//8step
- endcase
- end
- SETDDRAM:begin
- lcd_ack_o <= ;
- lcd_rs <= ;
- lcd_bus <= sys_addr_i;
- cnt64 <= cnt64;
- end
- WRDDRAM:begin
- lcd_ack_o <= ;
- lcd_rs <= ;
- cnt64 <= cnt64;
- lcd_bus <= sys_dat_i;
- end
- ACK:begin
- lcd_ack_o <= ;
- lcd_rs <= ;
- lcd_bus <= lcd_bus;
- cnt64 <= cnt64;
- end
- default:begin
- lcd_ack_o <= ;
- lcd_rs <= ;
- lcd_bus <= 'h38;
- cnt64 <= cnt64;
- end
- endcase
- end
- end
- endmodule
源码2...
- `timescale ns / ps
- module lcd1602_cgram_driver(
- sys_clk,
- sys_rst_n,
- lcd_en,
- lcd_rw,
- lcd_rs,
- lcd_bus,
- lcd_on,
- lcd_blon
- );
- input sys_clk;
- input sys_rst_n;
- output lcd_rs;
- output lcd_rw;
- output lcd_en;
- output lcd_on;
- output lcd_blon;
- output [:] lcd_bus;
- reg [:] sys_dat_i=;
- reg [:] sys_addr_i=;
- wire lcd_ack_o;
- always @ (posedge sys_clk) begin
- if(sys_rst_n == 'b0) begin
- sys_dat_i <= ;
- sys_addr_i <= 'h80;
- end
- else if(lcd_ack_o == 'b1) begin
- if(sys_dat_i == 'd7) begin
- sys_dat_i <= ;
- sys_addr_i <= 'h80;
- end
- else begin
- sys_dat_i <= sys_dat_i + 'd1;
- sys_addr_i <= sys_addr_i + 'd1;
- end
- end
- else begin
- sys_dat_i <= sys_dat_i;
- sys_addr_i <= sys_addr_i;
- end
- end
- lcd1602_cgram_controller hal(
- .sys_clk( sys_clk ),
- .sys_rst_n( sys_rst_n ),
- .sys_dat_i( sys_dat_i ),
- .sys_addr_i( sys_addr_i ),
- .lcd_ack_o( lcd_ack_o ),
- .lcd_en( lcd_en ),
- .lcd_rw( lcd_rw ),
- .lcd_rs( lcd_rs ),
- .lcd_bus( lcd_bus ),
- .lcd_on( lcd_on ),
- .lcd_blon( lcd_blon )
- );
- endmodule
源码3...
- `timescale ns / ps
- module lcd1602_cgram_driver_tsb();
- reg sys_clk;
- reg sys_rst_n;
- initial begin
- sys_clk=;
- sys_rst_n=;
- # sys_rst_n=;
- end
- always begin
- # sys_clk=~sys_clk;
- end
- wire lcd_rw;
- wire lcd_rs;
- wire lcd_en;
- wire [:] lcd_bus;
- wire lcd_on;
- wire lcd_blon;
- lcd1602_cgram_driver api(
- .sys_clk( sys_clk ),
- .sys_rst_n( sys_rst_n ),
- .lcd_en( lcd_en ),
- .lcd_rw( lcd_rw ),
- .lcd_rs( lcd_rs ),
- .lcd_bus( lcd_bus ),
- .lcd_on( lcd_on ),
- .lcd_blon( lcd_blon )
- );
- endmodule
LCD1602写自定义字符的Verilog源码的更多相关文章
- Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析
这是关于RecyclerView的第二篇,说的是如何自定义Item动画,但是请注意,本文不包含动画的具体实现方法,只是告诉大家如何去自定义动画,如何去参考源代码. 我们知道,RecyclerView默 ...
- Jquery+Ajax+asp.net+sqlserver-编写的通用邮件管理(源码)
开始 邮件管理通常用在各个内部系统中,为了方便快捷的使用现有的代码开发一个邮件管理系统而诞生的. 准备条件 这是我的设计表结构,大家一看就懂了 --邮件接收表CREATE TABLE [dbo]. ...
- spring security 之自定义表单登录源码跟踪
上一节我们跟踪了security的默认登录页的源码,可以参考这里:https://www.cnblogs.com/process-h/p/15522267.html 这节我们来看看如何自定义单表认 ...
- 实现简单的手写涂鸦板(demo源码)
在一些软件系统中,需要用到手写涂鸦的功能,然后可以将涂鸦的结果保存为图片,并可以将"真迹"通过网络发送给对方.这种手写涂鸦功能是如何实现的了?最直接的,我们可以使用Windows提 ...
- 自定义TableViewCell 的方式实现自定义TableView(带源码)
转载于:http://www.cnblogs.com/macroxu-1982/archive/2012/08/30/2664121.html 实现的效果 实现过程 Step One 创建 自定义Ta ...
- [原创]分享本人自己PY写的BOOST编译程序(源码)
本程序WINDOWS专用,只做抛砖引玉,希望诸位按照各自需求自行修改,主要目的是为了让诸位编译时可以省一些组合指令的时间,只需要修改几个参数即可自动编译. 支持64位编译模式. 改进版本:http:/ ...
- 一个基于jQuery写的弹窗效果(附源码)
最近项目中频繁遇到需要弹出窗口的功能,一直使用浏览器默认的Alert和Confirm弹窗,感觉视觉效果不是那么好,而从网上下载的话又找不到合适的,找到的话有些也是十分臃肿,有时候感觉学习配置的功夫自己 ...
- client-go客户端自定义开发Kubernetes及源码分析
介绍 client-go 是一种能够与 Kubernetes 集群通信的客户端,通过它可以对 Kubernetes 集群中各资源类型进行 CRUD 操作,它有三大 client 类,分别为:Clien ...
- 十四.自定义yum仓库、源码编译安装
pc7:192.168.4.7 1.自定义yum仓库1.1 源码仓库下:/root/tools/other]# createrepo .]# ls ntfs-3g-2014.2.15-6.el6.x8 ...
随机推荐
- [Weekly] 2014.03.01-2014.03.08
这周写过好多东西,虽然还没有完全弄明白线段树,但是progress还是有的! 不过有时候真的很想哭,因为自己的梦想连别人看看韩剧.无所事事还要分量轻,实在不明白政治课的Teamwork意义何在,花两分 ...
- Tri-Training: Exploiting Unlabeled Data Using Three Classifiers
Abstract – In many practical data mining applications such as web page classification, unlabeled tra ...
- cassandra 环境搭建
1 下载安装包 http://www.planetcassandra.org/cassandra/?dlink=http://downloads.datastax.com/community/dsc- ...
- 永不消逝的电波(二)HackRF入门:家用无线门铃信号重放
0×00 前言 在第一篇文章:永不消逝的电波(一):无线电入门篇 我们了解了一下无线电的发展史以及无线电的一些物理知识,在第二篇里我们将用HackRF录制家用门铃的无线信号,然后重放门铃信号. 门铃从 ...
- Asp.net中Json的序列化和反序列化(一)
JSON是专门为浏览器中的网页上运行的JavaScript代码而设计的一种数据格式.在网站应用中使用JSON的场景越来越多,本文介绍ASP.NET中JSON的序列化和反序列化,主要对JSON的简单介绍 ...
- 黑马程序员——【Java基础】——正则表达式
---------- android培训.java培训.期待与您交流! ---------- 一.概述 1. 概念:符合一定规则的表达式. 2. 作用:用于专门操作字符串. 3. 特点:用一些特定的符 ...
- HDU 3555 Bomb
RT. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> ...
- HDU5898、 HDU 2089(数位DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5898 题意:很明确,找出区间[l , r]中符合连续奇数为偶数,连续偶数为奇数的个数. 思路:dp[i ...
- 12-8下午 php语法
<?php //var_dump(empty($a)); //判断变量是否为空//var_dump(isset($a)); //判断变量是否定义//$a = 10;//unset($a); // ...
- IOS ASIFormDataRequest使用简介(2/25)
ASIHTTPRequest类库中的ASIFormDataRequest是实现HTTP协议中的处理POST表单的很好的类库.使用起来非常简单.下面特酷吧简要总结其用法. 在说明之前先需要了解HTTP请 ...