(注:如果本文有代码 则均搜索于网络或本人编写仅供学习交流之用)
FPGA驱动LCD1602
驱动1602其实比实现IIC协议要简单
要注意读写模式 命令/数据线以及数据的发送和时序问题即可
难点还是在于时钟的生成
开发板自带的LCD1602是具有8位数据线 1个使能信号线
1个读写控制信号 1个数据/命令模式选择信号
使用流程如下
-
发命令配置LCD
-
设置数据地址
-
发送数据
因为要延时5ms 系统晶振50Mhz
50M = 20ns , 20ns * 131072 *2 ~= 5ms, 5 ms is LCD Cycle
在系统时钟的边沿开始计数,计数到一定值时归零并产生一个时钟信号,下次计数满时将时钟信号翻转即可产生新时钟。
// 50M = 20ns , 20ns * 131072 *2 ~= 5ms, 5 ms is LCD Cycle
always @(posedge sys_clk_50m or negedge sys_rst_n) begin
if (sys_rst_n ==1'b0)
div_cnt <= #`U_DLY 17'b0;
else
div_cnt <= #`U_DLY div_cnt + 17'b1;
end
always @(posedge sys_clk_50m or negedge sys_rst_n) begin
if (sys_rst_n ==1'b0)
clk_lcd <= #`U_DLY 1'b0;
else if ( div_cnt == {17{1'b1}} )
clk_lcd <= #`U_DLY ~clk_lcd;
else ;
end
接下来就是控制读写信号线 和 数据.命令控制信号线
来发送初始化LCD的命令---- 然后设置数据地址---- 写入要显示的数据
1
assign RW = 1'b0; //RW=0时对LCD模块执行写操作
assign LCD_EN = LCD_EN_Sel ? clk_lcd : 1'b0; //通过LCD_EN_Sel信号来控制LCD_EN的开启与关闭
always @(posedge clk_lcd or negedge rst)
begin
if(!rst)
begin
state <= Clear_Lcd; //复位:清屏并光标复位
RS <= 1'b0; //复位:RS=0时为写指令;
DB8 <= 8'b0; //复位:使DB8总线输出全0
LCD_EN_Sel <= 1'b1; //复位:开启夜晶使能信号
disp_count <= 4'b0;
end
else
case(state) //初始化LCD模块
Clear_Lcd:
begin
state <= Set_Disp_Mode;
DB8 <= 8'b00000001; //清屏并光标复位
end
Set_Disp_Mode:
begin
state <= Disp_On;
DB8 <= 8'b00111000; //设置显示模式:8位2行5x8点阵
end
Disp_On:
begin
state <= Shift_Down;
DB8 <= 8'b00001100; //显示器开、光标不显示、光标不允许闪烁
end
Shift_Down:
begin
state <= Write_Addr;
DB8 <= 8'b00000110; //文字不动,光标自动右移
end
Write_Addr:
begin
state <= Write_Data_First;
DB8 <= 8'b10000001; //写入第一行显示起始地址:第一行第二个位置
Data_First_Buf <= Data_First; //将第一行显示的数据赋给Data_First_Buf?
end
Write_Data_First: //写第一行数据
begin
if(disp_count == 14) //disp_count等于14时表示第一行数据已写完
begin
DB8 <= 8'b11000001; //送入写第二行的指令
RS <= 1'b0;
disp_count <= 4'b0;
Data_Second_Buf <= Data_Second;
state <= Write_Data_Second; //写完第一行进入写第二行状态
end
else
begin
DB8 <= Data_First_Buf[111:104];
Data_First_Buf <= (Data_First_Buf << 8);
RS <= 1'b1; //RS=1表示写数据
disp_count <= disp_count + 1'b1;
state <= Write_Data_First;
end
end
Write_Data_Second: //写第二行数据
begin
if(disp_count == 14)
begin
LCD_EN_Sel <= 1'b0;
RS <= 1'b0;
disp_count <= 4'b0;
state <= Idel; //写完进入空闲状态
end
else
begin
DB8 <= Data_Second_Buf[111:104];
Data_Second_Buf <= (Data_Second_Buf << 8);
RS <= 1'b1;
disp_count <= disp_count + 1'b1;
state <= Write_Data_Second;
end
end
Idel:
begin
state <= Idel; //在Idel状态循环
end
default: state <= Clear_Lcd; //若state为其他值,则将state置为Clear_Lcd
endcase
end
用户1847523 2015-8-23 23:45
用户1711475 2015-3-16 11:24
sunyzz 2015-3-9 20:54
用户403664 2015-3-9 10:01
1、低调,嘿嘿 2、木有被调包,淡定。3、拍照技术太烂啦,以后怎么帮女朋友拍照?