原创 lcd1602控制模块 V6

2012-7-24 15:23 1067 11 11 分类: FPGA/CPLD

/**
  ******************************************************************************
  * @file     LCD_con_v6.v
  * @author   西殿源
  * @version  V6
  * @date     07/19/2012
  * @brief    LCD1602控制模块
  * @info  1. 状态机分段,

           2. 配置变量整合为寄存器组,没找到可以整合的部分


  ******************************************************************************
  */

module LCD_con_v6(
 input[7:0] data_in,
 input rst_n,
 input clk,
 input wr,
 output reg[1:0] RSW_O,//RS RW
 output reg[7:0] PORT_O,//DATA
 output e,
 output reg work_clk
 );
 
 
 parameter cwr  =2'b00;
 parameter dwr  =2'b10;
 parameter no=0;
 parameter yes=1;
 parameter FREE  =3'd0;// 10'bz;//空闲状态总线高阻  1
 parameter CLR  =3'd1;// 10'b1;//清屏     2
 parameter HOME  =3'd2;// 10'b10;//光标归位    3
 parameter CURSOR =3'd3;// 10'b110;//显示效果设置  4
 parameter DISPLA =3'd4;// 10'b1100;//显示开关   5
 parameter SETMOD =3'd5;// 10'b111100;//总线模式设置 6
 parameter LOCAT =3'd6;// 10'b10000000;//显示位置  7
 parameter WRDAT =3'd7;//
   
   
 reg[7:0] data_temp; 
 reg[7:0] display_cnt;//字符显示个数计数器
 reg[2:0] state;
 reg[2:0] state_next; 
 reg[15:0] temp_fp;
 reg[1:0] rsw;
 reg[7:0] data_lcd;
 reg lcd_exe_t;//用在时序逻辑
 reg lcd_exe;//当前是否有指令或数据操作,用在组合逻辑
 
 
 
     
 always @(posedge clk,negedge rst_n) begin
  if(!rst_n) begin  
   temp_fp<=0;
   work_clk<=no;
   end
  else if(temp_fp==999) begin
   temp_fp<=0;
   work_clk<=yes;
   end
  else begin
   temp_fp<=temp_fp+1;
   work_clk<=no;
   end
 end
 
 assign e=((lcd_exe_t==yes)&&(temp_fp==2))? 1:0;//根据条件使能lcd操作时钟
 
 
 always @(posedge clk,negedge rst_n) begin
  if(!rst_n) begin  
   state<=SETMOD;//初始化状态为设置模式
   display_cnt<=0;//字符显示个数计数器
   RSW_O<=0;
   PORT_O<=0;
   lcd_exe_t<=no;
   end
  else if(wr) begin//每个clk的上升沿检测是否有数据写入请求
   state<=WRDAT;//跳到写数据状态
   data_temp<=data_in;//将输入数据读入寄存器
   end
  else if(work_clk==yes) begin//lcd内部操作时钟,此乃使能时钟,可避免混杂的时钟漫天飞
   RSW_O<=rsw;//同步输出
   PORT_O<=data_lcd;//同步输出
   lcd_exe_t<=lcd_exe;//同步输出
   state<=state_next;//状态跳转
   end
 end
 
 
 always @(state) begin
  case(state)
   //////////////////////////////////////////////////////////////////
   FREE:  
    begin
//     rsw<=0;//滥竽充数,删去也无妨
//     data_lcd<=8'd0;//滥竽充数,删去也无妨
     lcd_exe=no;
     state_next=FREE;//就在这闲逛兜圈吧吧 
     end
       
   CLR:  
    begin
     rsw=cwr;//写指令控制
     data_lcd=8'h1;//写指令操作码
     lcd_exe=yes;
     state_next=LOCAT;
     end
       
   HOME:  
    begin
     rsw=cwr;//写指令控制
     data_lcd=8'h2;//写指令操作码
     lcd_exe=yes;
     state_next=CLR;
     end
       
   CURSOR: 
    begin
     rsw=cwr;//写指令控制
     data_lcd=8'h6;//写指令操作码
     lcd_exe=yes;
     state_next=CLR;
     end
   
   DISPLA: 
    begin
     rsw=cwr;//写指令控制
     data_lcd=8'hF;//写指令操作码
     lcd_exe=yes;
     state_next=CURSOR;
     end
   
   SETMOD: 
    begin
     rsw=cwr;//写指令控制
     data_lcd=8'h3C;//写指令操作码
     lcd_exe=yes;
     state_next=DISPLA;
     end
   
   LOCAT: 
    begin
     rsw=cwr;//写指令控制
     data_lcd=8'h80;//写指令操作码
     lcd_exe=yes;
     state_next=FREE;
     end
   

   WRDAT: 
    begin
     rsw=dwr;//写数据控制
     data_lcd=data_temp;//写数据
     lcd_exe=yes;
     state_next=FREE;
     end
       
//////////////////////////////////////////////////////////////////////////////////////////       
   default  :  state_next= SETMOD;
  endcase//state
 end//always
 
endmodule


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
11
关闭 站长推荐上一条 /3 下一条