10、“Hello,I'm Anmko!”LCD1602的显示实验。
LCD1602的显示实验,两行显示,不显示光标,画面不移动;
图片中的两根飞线是给背光用的,三色背光的,PCB封装不对,所以飞线了。。。还有那个电阻,最好还是换了吧,不同芯片的屏的电阻值是不一样的(我直接焊接在了LCD的引脚上)。
源代码:
/*************************************************
* Module Name : lcd1602_driver
* Engineer : Anmko
* Target Device : EP2C8Q208C8
* Tool versions : Quartus II 12.0
* Create Date : 2012-9-3
* Revision : v1.0
* Description :
**************************************************/
module lcd1602_driver
(
input clk,
input rst_n,
output lcd_en, // lcd enable
output reg lcd_rs, // record,statement
output reg lcd_rw,
output reg [7:0] lcd_data
);
parameter [127:0] line_rom1 = "Hello,I'm Anmko!";
parameter [127:0] line_rom2 = "EEPW---FPGA DIY!";
//--------------------------------------
reg [15:0] cnt;
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt <= 0;
else
cnt <= cnt + 1'b1;
end
assign lcd_en = cnt[15]; //lcd enable,keep same time; >1000ns
wire cmd_flag = (cnt == 16'h7FFF) ? 1'b1 : 1'b0; //when lcd_en is steady,write a cmd
// Gray code : 40 states
parameter IDLE = 8'h00; // IDLE
// lcd init
parameter CLEAR = 8'h01; //清屏
parameter SETFUNCTION = 8'h02;
//工作方式设置 1:8/1:4; 位数据接口:两行/一行; 显示:5x10/5x7点阵。
parameter SWITCHMODE = 8'h03;
//显示状态设置,显示:开/关; 光标:开/关; 闪烁:开/关。
parameter SETMODE = 8'h04;
//输入方式设置,读写数据后RA地址增/减1;画面:动/不动。
parameter SHIFT = 8'h05;
//光标画面滚动:画面/光标平移一位;左/右平移一位。
// parameter SETCGRAM = 8'h40; //设置CGRAM
// parameter SETDDRAM1 = 8'h81; //设置DDRAM
// parameter SETDDRAM2 = 8'h82; //设置DDRAM
// display 1th line
parameter ROW1_ADDR = 8'h09;
parameter ROW1_0 = 8'h0A;
parameter ROW1_1 = 8'h0B;
parameter ROW1_2 = 8'h0C;
parameter ROW1_3 = 8'h0D;
parameter ROW1_4 = 8'h0E;
parameter ROW1_5 = 8'h0F;
parameter ROW1_6 = 8'h10;
parameter ROW1_7 = 8'h11;
parameter ROW1_8 = 8'h12;
parameter ROW1_9 = 8'h13;
parameter ROW1_A = 8'h14;
parameter ROW1_B = 8'h15;
parameter ROW1_C = 8'h16;
parameter ROW1_D = 8'h17;
parameter ROW1_E = 8'h18;
parameter ROW1_F = 8'h19;
// display 2th line
parameter ROW2_ADDR = 8'h1A;
parameter ROW2_0 = 8'h1B;
parameter ROW2_1 = 8'h1C;
parameter ROW2_2 = 8'h1D;
parameter ROW2_3 = 8'h1E;
parameter ROW2_4 = 8'h1F;
parameter ROW2_5 = 8'h20;
parameter ROW2_6 = 8'h21;
parameter ROW2_7 = 8'h22;
parameter ROW2_8 = 8'h23;
parameter ROW2_9 = 8'h24;
parameter ROW2_A = 8'h25;
parameter ROW2_B = 8'h26;
parameter ROW2_C = 8'h27;
parameter ROW2_D = 8'h28;
parameter ROW2_E = 8'h29;
parameter ROW2_F = 8'h2A;
//---------------------------------------
reg [7:0] state;
//---------------------------------------
// FSM: 状态机
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
lcd_rs <= 0;
lcd_data <= 8'hXX;
end
else if(cmd_flag)
begin
// write statement
case(state)
IDLE :begin
lcd_rs <= 0; lcd_rw <= 0;
lcd_data <= 8'hxx;
state <= CLEAR;
end
//lcd init
CLEAR :begin
lcd_rs <= 0; lcd_rw <= 0;
lcd_data <= 8'b0000_0001;
state <= SETFUNCTION;
end
SETFUNCTION :begin
lcd_rs <= 0; lcd_rw <= 0; //3C
lcd_data <= 8'b0011_1100;
state <= SWITCHMODE;
end
SWITCHMODE :begin
lcd_rs <= 0; lcd_rw <= 0; //08
lcd_data <= 8'b0000_1000;
state <= SETMODE;
end
SETMODE :begin
lcd_rs <= 0; lcd_rw <= 0; //06
lcd_data <= 8'b0000_0110;
state <= SHIFT;
end
SHIFT :begin
lcd_rs <= 0; lcd_rw <= 0; //0c
lcd_data <= 8'b0000_1100;
state <= ROW1_ADDR;
end
ROW1_ADDR :begin
lcd_rs <= 0; lcd_rw <= 0;
lcd_data <= 8'b1000_0000;
state <= ROW1_0;
end
ROW1_0 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[127:120];
state <= ROW1_1;
end
ROW1_1 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[119:112];
state <= ROW1_2;
end
ROW1_2 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[111:104];
state <= ROW1_3;
end
ROW1_3 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[103:96];
state <= ROW1_4;
end
ROW1_4 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[95:88];
state <= ROW1_5;
end
ROW1_5 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[87:80];
state <= ROW1_6;
end
ROW1_6 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[79:72];
state <= ROW1_7;
end
ROW1_7 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[71:64];
state <= ROW1_8;
end
ROW1_8 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[63:56];
state <= ROW1_9;
end
ROW1_9 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[55:48];
state <= ROW1_A;
end
ROW1_A :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[47:40];
state <= ROW1_B;
end
ROW1_B :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[39:32];
state <= ROW1_C;
end
ROW1_C :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[31:24];
state <= ROW1_D;
end
ROW1_D :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[23:16];
state <= ROW1_E;
end
ROW1_E :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[15:8];
state <= ROW1_F;
end
ROW1_F :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom1[7:0];
state <= ROW2_ADDR;
end
ROW2_ADDR :begin
lcd_rs <= 0; lcd_rw <= 0;
lcd_data <= 8'b1100_0000;
state <= ROW2_0;
end
ROW2_0 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[127:120];
state <= ROW2_1;
end
ROW2_1 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[119:112];
state <= ROW2_2;
end
ROW2_2 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[111:104];
state <= ROW2_3;
end
ROW2_3 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[103:96];
state <= ROW2_4;
end
ROW2_4 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[95:88];
state <= ROW2_5;
end
ROW2_5 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[87:80];
state <= ROW2_6;
end
ROW2_6 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[79:72];
state <= ROW2_7;
end
ROW2_7 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[71:64];
state <= ROW2_8;
end
ROW2_8 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[63:56];
state <= ROW2_9;
end
ROW2_9 :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[55:48];
state <= ROW2_A;
end
ROW2_A :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[47:40];
state <= ROW2_B;
end
ROW2_B :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[39:32];
state <= ROW2_C;
end
ROW2_C :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[31:24];
state <= ROW2_D;
end
ROW2_D :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[23:16];
state <= ROW2_E;
end
ROW2_E :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[15:8];
state <= ROW2_F;
end
ROW2_F :begin
lcd_rs <= 1; lcd_rw <= 0;
lcd_data <= line_rom2[7:0];
state <= ROW1_ADDR;
end
default : state <= IDLE;
endcase
end
end
endmodule
11、LCD1602的数字时钟显示
LCD时钟显示。LCD1602显示时、分、秒,按键S1、S2分别对小时进行加、减;S3、S4分别对分进行加10、加1;S5、S6分别对秒进行加10、加1;S8是复位键。
纯逻辑控制LCD1602的变量显示还是挺麻烦的,变量少的话还能凑合(本实验显示6个变量),一多的话估计很麻烦。。。为了简便实用的应用1602,看来还有一段的路要走啊。。。
视频地址:http://union.bokecc.com/flash/player.swf?vid=EB73420B701A4992&siteid=290666218ACBA694&playerid=EEA982EE6B20F4D1&playertype=1
sof下载:
——回复可见内容——
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 | |
【分享评测,赢取加热台】使用8051单片机驱动WS2812被打赏40分 |