13_基于FPGA的液晶1602显示
实验原理
1602常用与显示数字和字母,显示容量为16*2个字符,内部有80个字节的RAM缓冲区,当要向1602送数显示时,要先发送显示地址指针80H+地址码。
内部地址码分布:
1602有16个管脚,其中用于编程操作的有RS(数据命令),RW(读写),E(使能端),D0-D7(并行数据端口)。
由于只要向1602写数据,因此给出写时序图和其时序图上的时序参数:
(其指令说明请详细查看1602数据手册)
Verilog的编程只要遵循时序图描写出时序图那样的信号和满足其时序参数就可以实现FPGA控制1602显示,并且可用状态机实现。
其中由于是往1602写数据因此RW可一直置0电平,使能信号E可以做成时钟信号用于控制数据的传输。
硬件原理图
该插口是1602和12864共用的插口(PSB-IO28是背光源正极因此要输出高电平)
实验代码
/********************************版权声明************************************** ** 大西瓜团队 ** **----------------------------文件信息-------------------------- ** 文件名称: my1602.v ** 创建日期: ** 功能描述:液晶1602显示Daxigua!,QQnumber ** 硬件平台:大西瓜第三代开发板,http://daxiguafpga.taobao.com ** 版权声明:本代码属个人知识产权,本代码仅供交流学习. **---------------------------修改文件的相关信息---------------- ** 修改人: ** 修改日期: ** 修改内容: *******************************************************************************/ module my1602(clk,RS,RW,E,Data,back_light); input clk; //50MHZ时钟的输入 output RS,RW,E; //1602的控制信号使能,数据/命令,读/写 output [7:0]Data; //数据端 output back_light; //背光 reg RS; reg [7:0]Data;
parameter address=8'h80; //第一行 parameter address2=8'hc0; //第二行
assign RW=1'b0; //只用显示时,一直是写的状态 assign back_light=1'b1; //背光灯打开
reg clk_e; reg [15:0]count; always @(posedge clk) begin count=count+1'b1; if(count==16'hf000) begin clk_e=~clk_e; //作为使能端 count=16'd0; end end
reg [1:0]jishu; reg [4:0]zhuangtai; //状态机状态 reg temp; always @(posedge clk_e) begin case(zhuangtai) 5'b00000:begin temp<=1'b0; RS<=1'b0; Data<=8'h38;//显示模式设置 zhuangtai<=zhuangtai+1'b1; end
5'b00001:begin RS<=1'b0; Data<=8'h0c;//显示开及光标设置 zhuangtai<=zhuangtai+1'b1; end
5'b00010:begin RS<=1'b0; Data<=8'h06;//显示光标移动设置 zhuangtai<=zhuangtai+1'b1; end
5'b00011:begin RS<=1'b0; Data<=8'h01;//显示清屏 zhuangtai<=zhuangtai+1'b1;//前面几个状态是初始化的状态 end
5'b00100:begin RS<=1'b0; Data<=address;//设置显示起始地址,第一行起始位置开始显示 zhuangtai<=zhuangtai+1'b1; end
5'b00101:begin//显示"Daxigua!" RS<=1'b1; Data<="D"; zhuangtai<=zhuangtai+1'b1; end
5'b00110:begin RS<=1'b1; Data<="a"; zhuangtai<=zhuangtai+1'b1; end
5'b00111:begin RS<=1'b1; Data<="x"; zhuangtai<=zhuangtai+1'b1; end
5'b01000:begin RS<=1'b1; Data<="i"; zhuangtai<=zhuangtai+1'b1; end
5'b01001:begin RS<=1'b1; Data<="g"; zhuangtai<=zhuangtai+1'b1; end
5'b01010:begin RS<=1'b1; Data<="u"; zhuangtai<=zhuangtai+1'b1; end
5'b01011:begin RS<=1'b1; Data<="a"; zhuangtai<=zhuangtai+1'b1; end
5'b01100:begin RS<=1'b1; Data<="!"; zhuangtai<=zhuangtai+1'b1; end
5'b01101:begin RS<=1'b0; Data<=address2;//切换到第二行显示 zhuangtai<=zhuangtai+1'b1; end
5'b01110:begin RS<=1'b1; Data<="Q";//后面显示大西瓜QQ号 zhuangtai<=zhuangtai+1'b1; end
5'b01111:begin RS<=1'b1; Data<="Q"; zhuangtai<=zhuangtai+1'b1; end
5'b10000:begin RS<=1'b1; Data<=":"; zhuangtai<=zhuangtai+1'b1; end
5'b10001:begin RS<=1'b1; Data<="2"; zhuangtai<=zhuangtai+1'b1; end
5'b10010:begin RS<=1'b1; Data<="0"; zhuangtai<=zhuangtai+1'b1; end
5'b10011:begin RS<=1'b1; Data<="3"; zhuangtai<=zhuangtai+1'b1; end
5'b10100:begin RS<=1'b1; Data<="7"; zhuangtai<=zhuangtai+1'b1; end
5'b10101:begin RS<=1'b1; Data<="6"; zhuangtai<=zhuangtai+1'b1; end
5'b10110:begin RS<=1'b1; Data<="9"; zhuangtai<=zhuangtai+1'b1; end
5'b10111:begin RS<=1'b1; Data<="7"; zhuangtai<=zhuangtai+1'b1; end
5'b11000:begin RS<=1'b1; Data<="8"; zhuangtai<=zhuangtai+1'b1; end
5'b11001:begin RS<=1'b1; Data<="8"; zhuangtai<=zhuangtai+1'b1; end
5'b11010:begin if(jishu==2'b10) begin temp<=1'b1;//最后使能端一直拉高 zhuangtai<=4'b0111; Data<=8'd0; end
else begin zhuangtai<=4'b0000; jishu=jishu+1'b1; Data<=8'd0; end end default zhuangtai<=4'b0000; endcase end
reg D1,D2,D3,D4,D5; always @(posedge clk) begin D1<=clk_e; D2<=D1; D3<=D2; D4<=D3; D5<=D4; end assign E=D5|temp; endmodule |
实验操作
实验效果
大西瓜FPGA-->https://daxiguafpga.taobao.com
配套开发板:https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-24211932856.3.489d7241aCjspB&id=633897209972
博客资料、代码、图片、文字等属大西瓜FPGA所有,切勿用于商业! 若引用资料、代码、图片、文字等等请注明出处,谢谢!
每日推送不同科技解读,原创深耕解读当下科技,敬请关注微信公众号"科乎"。