创建博客 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

东月之神

在单纯的观念里面,生命就容易变得比较深刻!

 
 
 

日志

 
 
关于我

别驻足,梦想要不停追逐,别认输,熬过黑暗才有日出,要记住,成功就在下一步,路很苦,汗水是最美的书!

LOFTER精选

verilog lcd1602显示 时钟 矩阵键盘控制  

2011-08-11 21:23:06|  分类: FPGA |  标签: |举报 |字号 订阅

module lcd1602(clk, rs, rw, en, dat, key_row, key_column);

input clk;
input[3:0] key_column;

output[3:0] key_row;

output rs;
output rw;
output en;
output [7:0] dat; //送给lcd的数据(包括指令和数据)

wire[3:0] key_scan;
reg[3:0] key_s;

reg [7:0] dat;
reg rs;

reg [15:0] div_count = 0;
reg [31:0] n;

reg [7:0] current = 0;
reg [7:0] next;
reg clkr = 0, flag;
 
reg [7:0] char;
reg [3:0] second1 = 0, minute1 = 0, hour1 = 0;
reg [3:0] second2 = 0, minute2 = 0, hour2 = 0;
reg  cnt = 0, count = 0;

key  key1(.clk(clk), .key_row(key_row), .key_column(key_column), .key_s(key_scan));
//分频器,65536分频的,必须分频降低时钟的频率,否则在LCD上显示不出来数据
always @( posedge clk )
begin
 div_count <= div_count + 1;
 if (div_count == 16'h000f)
  clkr = ~clkr;
end

always @(posedge clk)
begin
 if(n == 50000000)
 begin
  n = 0;
  second1 = second1 + 1;
  if(key_scan == 1)
  begin
   minute1 = minute1 + 1;
   if(minute1 == 10)
   begin
    minute1 = 0;
    minute2 = minute2 + 1;
    if(minute2 == 6)
     minute2 = 0;
   end
  end
  else if(key_scan == 2)
  begin
   hour1 = hour1 + 1;
   if(hour1 == 10)
   begin
    hour1 = 0;
    hour2 = hour2 + 1;
   end
   if(hour1 == 4 && hour2 == 2)
   begin
    hour1 = 0;
    hour2 = 0;
   end
  end

  if(second1 == 10)
  begin
   second1 = 0;
   second2 =  second2 + 1;
   if(second2 == 6)
   begin
    second2 = 0;
    minute1 = minute1 + 1;
    if(minute1 == 10)
    begin
     minute1 = 0;
     minute2 = minute2 + 1;
     if(minute2 == 6)
     begin
      minute2 = 0;
      hour1 = hour1 + 1;
      if(hour1 == 10 && hour2 != 2)
      begin
       hour2 = hour2 + 1;
       hour1 = 0;
      end
      else if(hour2 == 2 && hour1 == 4)
      begin
       hour2 = 0;
       hour1 = 0;
      end
        end
    end
   end
  end 
 end
 n = n + 1;
 if(n == 25000000 || n == 50000000)
  flag = !flag;
 if(flag == 1) char = " ";
 else char = ":";
end


always @(posedge clkr)
begin
 current <= next;
 case(current)
  0: begin rs <= 0; dat <= 8'h1; next <= 1; end//写指令 //功能设定指令,设定显示两行,数据线为8位,点阵为5*7
  1: begin rs <= 0; dat <= 8'h38; next <= 2; end//控制显示器开,无光标
  2: begin rs <= 0; dat <= 8'h0c; next <= 3; end//进入模式设置,每次写入数据后光标右移
  3: begin rs <= 0; dat <= 8'h6; next <= 4; end  //清屏指令
  
  4: begin rs <= 1; dat <= "B"; next <= 5; end
  5: begin rs <= 1; dat <= "y"; next <= 6; end
  6: begin rs <= 1; dat <= " "; next <= 7; end
  7: begin rs <= 1; dat <= "C"; next <= 8; end
  8: begin rs <= 1; dat <= "h"; next <= 9; end
  9: begin rs <= 1; dat <= "e"; next <= 10; end
    10: begin rs <= 1; dat <= "n"; next <= 11; end
    11: begin rs <= 1; dat <= " "; next <= 12; end
    12: begin rs <= 1; dat <= "J"; next <= 13; end
    13: begin rs <= 1; dat <= "i"; next <= 14; end
    14: begin rs <= 1; dat <= "a"; next <= 15; end
    15: begin rs <= 1; dat <= "n"; next <= 16; end
    16: begin rs <= 1; dat <= "n"; next <= 17; end
    17: begin rs <= 1; dat <= "e"; next <= 18; end
    18: begin rs <= 1; dat <= "n"; next <= 19; end
    19: begin rs <= 1; dat <= "g"; next <= 20; end
    20:
     begin//第一行的起始地址,要在第一行显示16个字符必须写入起始地址;要在第二行显示必须写入第二行的起始地址
     rs <= 0; dat <= 8'h00;  
    if(count != 1)             //count 这个计数器必须要设定,以返回,必须清屏
    begin
     next <= 0;
     count <= count + 1;
    end
    else
       begin
     next <= 20;
     if(next == 20)  //到第二行显示
     begin
      rs <= 0; dat <= 8'hc0; next <= 21;
     end
    end
   end
  21: begin rs <= 1; dat <= " "; next <= 22; end
  22: begin rs <= 1; dat <= " "; next <= 23; end
  23: begin rs <= 1; dat <= " "; next <= 24; end
  24: begin rs <= 1; dat <= " "; next <= 25; end
  25: begin rs <= 1; dat <= hour2 + "0"; next <= 26; end
  26: begin rs <= 1; dat <= hour1 + "0"; next <= 27; end
  27: begin rs <= 1; dat <= char; next <= 28; end
  28: begin rs <= 1; dat <= minute2 + "0"; next <= 29; end
  29: begin rs <= 1; dat <= minute1 + "0"; next <= 30; end
  30: begin rs <= 1; dat <= char; next <= 31; end
  31: begin rs <= 1; dat <= second2 + "0"; next <= 32; end
  32: begin rs <= 1; dat <= second1 + "0"; next <= 33; end
  33: begin rs <= 1; dat <= " "; next <= 34; end
  34: begin rs <= 1; dat <= key_scan + "0"; next <= 35; end
  35: begin rs <= 1; dat <= " "; next <= 36; end
  36: begin rs <= 1; dat <= " "; next <= 37; end
  37:
   begin     
    rs <= 0; dat <= 8'h00;  
    if(cnt != 1)  //设置计数器,以返回清屏
    begin
     next <= 0;
     cnt <= cnt + 1;
    end
    else
     next <= 20;
   end
 endcase
 end

assign en = clkr; //连续赋值,下降沿,写指令时
assign rw = 0;    //始终为低电平
endmodule
 

 

矩阵键盘模块:

module key(clk, key_row, key_column, key_s);
input clk;
input[3:0] key_column;
output[3:0] key_row;
inout[3:0] key_s;

reg[3:0] key_scan, row;
reg[25:0] n, m;

assign key_row = row;
assign key_s = key_scan;
always @(posedge clk)
begin
   if(m >= 100000)
 begin
  n = n + 1;
  if(n <= 300000)
  begin
   row = 4'b1110;
   if(key_column != 4'b1111)
   begin
    case(key_column)
     4'b0111: key_scan = 0;
     4'b1011: key_scan = 1;
     4'b1101: key_scan = 2;
     4'b1110: key_scan = 3;
    endcase
    m = 0;
   end
  end

  else if(n <= 600000)
  begin
   row = 4'b1101;
   if(key_column != 4'b1111)
   begin
    case(key_column)
     4'b0111: key_scan = 4;
     4'b1011: key_scan = 5;
     4'b1101: key_scan = 6;
     4'b1110: key_scan = 7;
    endcase
    m = 0;
   end
  end
 
  else if(n <= 900000)
  begin
   row = 4'b1011;
   if(key_column != 4'b1111)
   begin
    case(key_column)
     4'b0111: key_scan = 8;
     4'b1011: key_scan = 9;
     4'b1101: key_scan = 10;
     4'b1110: key_scan = 11;
    endcase
    m = 0;
   end
  end
 
  else if(n <= 1200000)
  begin
   row = 4'b0111;
   if(key_column != 4'b1111)
   begin
    case(key_column)
     4'b0111: key_scan = 12;
     4'b1011: key_scan = 13;
     4'b1101: key_scan = 14;
     4'b1110: key_scan = 15;
    endcase
    m = 0;
   end
  end
 
  else n = 0;
 end
 else
    m = m + 1;
end

endmodule

  评论这张
 
阅读(576)| 评论(0)
推荐 转载

历史上的今天

最近读者

热度

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2014