这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 十八笔画的进程贴_按键、数码管过程

共16条 2/2 1 2 跳转至
助工
2012-11-08 21:32:59     打赏
11楼

LED作业全集:(1)全亮全灭 (2)左右向流水灯 (3)左右向跑马灯 (4)中间、两边流水。


视频地址:http://union.bokecc.com/flash/single/290666218ACBA694_AD132EF5DA99333D_false_EEA982EE6B20F4D1_1/player.swf



代码如下: 
module led1(clk,rst,led);
 input clk;
 input rst;
 output led;
reg [7:0] led;
reg [31:0] count;
reg [2:0] state;
reg [2:0] cnt;
reg [3:0] led_h,led_l;

always @(posedge clk or negedge rst)
 begin
    if(!rst)
       count<=32'd0;
    else
        begin
               if(count==32'd29999999)
                          count<=32'd0; 
              else
                         count<=count+1'b1;
       end
 end

always @ (posedge clk or negedge rst)
    begin
          if(!rst)
              begin
                   led<=8'b11111111;
                   state<=3'd0;
                   led_h=4'd1111;
                   led_l=4'd1111;
                   cnt<=3'd0;
              end
         else
             begin
                  if(count==32'd29999999)
                      begin
                            case(state)
                                  3'd0:
                                             begin
                                                    if(cnt<3'd4)
                                                          begin
                                                                  led<=~led;           // 亮灭间断
                                                                   cnt<= cnt + 1'b1;
                                                          end
                                                    else
                                                          begin
                                                              cnt<=3'd0;
                                                               led<=8'b11111111;
                                                                 state<= state + 1'b1;
                                                            end
                                             end
                                   3'd1:
                                              begin
                                                   led <= led>>1;             //led left move
                                                  if(led == 8'b00000000)
                                                         begin
                                                                  state<= state + 1'b1;
                                                                   led<=8'b11111111;
                                                          end
                                               end
                                   3'd2:
                                           begin
                                                  led<= led << 1;         //led right move
                                                 if(led == 8'b0000000)
                                                       begin
                                                               state<= state + 1'b1;
                                                               led<=8'b11111110;
                                                       end
                                            end
                                   3'd3:
                                           begin
                                                  led<={led[6:0],led[7]};   // right pao
                                                    if(led == 8'b01111111)
                                                       begin
                                                             state<= state + 1'b1;
                                                              led <= 8'b01111111;
                                                        end
                                             end
                                   3'd4:
                                               begin
                                                          led<={led[0],led[7:1]};   // left pao
                                                           if(led == 8'b11111110)
                                                              begin
                                                                      state<= state + 1'b1;
                                                                      led_h<=4'b1111;
                                                                      led_l<=4'b1111;
                                                                      led<=8'b11111111;
                                                               end
                                               end
                                   3'd5:
                                                begin
                                                        led_h<=led_h<<1;
                                                        led_l<=led_l>>1;
                                                        led<={led_h,led_l};
                                                         if(led == 8'b00000000)
                                                               begin
                                                                       state<= state + 1'b1;
                                                                       led_h<=4'b1111;
                                                                        led_l<=4'b1111;
                                                                        led<=8'b11111111;  
                                                               end
                                              end
                                     3'd6:
                                                 begin
                                                   led_h<=led_h>>1;
                                                   led_l<=led_l<<1;
                                                   led<={led_h,led_l};
                                                   if(led == 8'b00000000)
                                                         begin
                                                               state<= state + 1'b1;
                                                                led<=8'b11111111;
                                                         end
                                                 end
                                     default: state<= 3'd0;
                                    endcase
                          end
                    end
            end
 
endmodule
   
    


助工
2012-11-13 23:24:21     打赏
12楼

数码管篇之拨码开关控制数码管依次点亮


视频稍后上传。

module led2(clk,rst,sw,disp_seg,disp_bit);
input clk;
input rst;
input [7:0] sw;
output disp_seg;
output disp_bit;
reg [7:0] disp_seg;
reg [7:0] disp_bit;
reg [3:0] disp_data;
reg [31:0] count;

always @ (posedge clk or negedge rst)
      begin
            if(!rst)
                count <= 32'd0;
           else
              begin
                   if(count == 32'd49999999)
                       count <= 32'd0;
                  else
                         count <= count + 1'b1;
              end
  end
 
always @ (posedge clk or negedge rst)
    begin
           if(!rst)
               disp_data <= 4'd0;
          else
               begin
                  if(count == 32'd49999999)
                        disp_data <= disp_data + 1'b1;
                 else
                        disp_data <= disp_data;
              end
      end

always @ (sw)
     begin
          case (sw)
               8'b11111110:  //sw1                     //sw1
                        begin
                              disp_bit = 8'b11111110;
                             disp_seg = 8'hf9;
                       end
             8'b11111101:  //sw2                   
                        begin
                               disp_bit = 8'b11111101;
                                 disp_seg = 8'ha4;
                        end
              8'b11111011: //sw3
                       begin
                             disp_bit = 8'b11111011;
                              disp_seg = 8'hb0;
                       end
              8'b11110111: //sw4
                        begin
                             disp_bit = 8'b11101111;
                              disp_seg = 8'h99;
                     end
             8'b11101111: //sw5
                   begin
                            disp_bit = 8'b11101111;
                           disp_seg = 8'h92;
                     end
              8'b11011111: //sw6
                      begin
                           disp_bit = 8'b11011111;
                           disp_seg = 8'h82;
                     end
                8'b10111111: //sw7
                        begin
                               disp_bit = 8'b10111111;
                                disp_seg = 8'hf8;
                         end
                8'b01111111: //sw8
                   begin
                         disp_bit = 8'b01111111;
                       disp_seg = 8'h80;
                    end
              default: disp_bit = 8'b11111111;
              endcase
 end
 
endmodule
  


助工
2012-11-13 23:30:33     打赏
13楼

数码管之60秒计时
视频稍后上传。



module led2(clk,rst,disp_seg,disp_bit);
input clk;
input rst;
output disp_seg;
output disp_bit;
reg [7:0] disp_seg;
reg [7:0] disp_seg_l;
reg [7:0] disp_seg_h;
reg [7:0] disp_bit;
reg [3:0] disp_data_l;
reg [2:0] disp_data_h;
reg [31:0] count;
reg [14:0] scan_count;
reg count_1s;
reg scan_fre;


initial
    begin
       disp_data_l <= 4'd0;
       disp_data_h <= 3'd0;
      scan_fre <= 1'b0;
   end

always @ (posedge clk or negedge rst)
 begin
  if(!rst)
   count <= 32'd0;
  else
   begin
    if(count == 32'd4999999)    // 1s=(50*10^6)/(4999999+1)
     begin
      count <= 32'd0;
      count_1s <= ~count_1s;
     end
    else
     count <= count + 1'b1;
   end
 end
 
always @ (posedge clk or negedge rst)
 begin
  if(!rst)
   scan_count <= 15'd0;
  else
   begin
    if(scan_count == 15'd4999)      //1ms
     begin
      scan_count <= 15'd0;
      scan_fre <= ~scan_fre;
     end
    else
     scan_count <= scan_count + 1'b1;
   end
 end

always @ (posedge count_1s or negedge rst)
 begin
  if(!rst)
   begin
    disp_data_h <= 3'd0;
    disp_data_l <= 4'd0;
   end
  else
   begin
    if(disp_data_l == 4'd9 && disp_data_h < 3'd5 )
     begin
      disp_data_l<= 4'd0;
      disp_data_h <= disp_data_h + 1'b1;
     end
    else if(disp_data_l == 4'd9 && disp_data_h == 3'd5 )
     begin
      disp_data_h <= 3'd0;
      disp_data_l <= 4'd0;
     end
    else
     begin
      disp_data_l<= disp_data_l + 1'b1;
     end
   end
 end
 
always @ (disp_data_l)
 begin
  case (disp_data_l)
  0:  disp_seg_l = 8'hc0;
  1:  disp_seg_l = 8'hf9;
  2: disp_seg_l = 8'ha4;
  3:  disp_seg_l = 8'hb0;
  4:  disp_seg_l = 8'h99;
  5:  disp_seg_l = 8'h92;
  6:  disp_seg_l = 8'h82;
  7:  disp_seg_l = 8'hf8;
  8:  disp_seg_l = 8'h80;
  9:  disp_seg_l = 8'h90;
  endcase
 end
 
always @ (disp_data_h)
 begin
  case (disp_data_h)
  0:  disp_seg_h = 8'hc0;
  1:  disp_seg_h = 8'hf9;
  2: disp_seg_h = 8'ha4;
  3:  disp_seg_h = 8'hb0;
  4:  disp_seg_h = 8'h99;
  5:  disp_seg_h = 8'h92;
  endcase
 end

  
always @ (scan_fre) 
 begin
 if(scan_fre)
  begin
   disp_bit <= 8'b11111101;
   disp_seg <= disp_seg_h;
  end
 
 if(!scan_fre) 
  begin
   disp_bit <= 8'b11111110;
   disp_seg <= disp_seg_l;
  end
 end
endmodule
  


助工
2012-11-14 21:42:27     打赏
14楼

按键作业之控制数码管。视频稍后上传。

 



代码如下:
module key(clk,rst,key_in,disp_bit,disp_seg);
input clk;
input rst;
input key_in;
output disp_bit;
output disp_seg;

reg [7:0] disp_seg;
wire [7:0]disp_bit;
reg [3:0] key_count;
reg [19:0] delay_count;
reg key_high;         
reg key_high_r;
wire key_high2low;         // =0 表示下降沿 检测到下降沿说明按键已经按下    =1 表示高电平 说明按键未按下
reg key_low;
reg key_low_r;
wire key_low2high;         // =1 表示上升沿 检测到上升沿说明按键已经释放    =0 表示低电平 说明按键未释放

always @ (posedge clk or negedge rst)
 begin
  if(!rst)
   key_high <= 1'b1;
  else
   key_high <= key_in;
 end

always @ (posedge clk or negedge rst)
 begin
  if(!rst)
   key_high_r <= 1'b1;
  else
   key_high_r <= key_high;
 end
assign key_high2low = key_high_r & (~key_high);        // 1->0   key_high2low= 1&(~0)=1   1->1   key_high2low= 1&(~1)=0   

always @ (posedge clk or negedge rst)
 begin
  if(!rst)
   delay_count <= 20'h0;
  else if(key_high2low)               // 1->0
    delay_count <= 20'h0;
   else
    delay_count <= delay_count + 1'b1; 
 end

always @ (posedge clk or negedge rst)
 begin
  if(!rst)
   key_low <= 1'b1;
  else if(delay_count <= 20'hffff)     // 延时20ms到
   key_low <= key_in;
 end

always @ (posedge clk or negedge rst)
 begin
  if(!rst)
   key_low_r <= 1'b1;
  else
   key_low_r <= key_low;
 end
assign key_low2high = key_low_r & (~key_low);     

always @ (posedge clk or negedge rst)
 begin
  if(!rst)
   key_count <= 4'h0;
  else if(key_low2high)
    begin
     if(key_count == 4'hf)
      key_count <= 4'h0;
     else
      key_count <= key_count + 1'b1;
    end
   else
    key_count <= key_count; 
 end
 
always @ (key_count)
 begin
  case (key_count)
  4'h0: disp_seg = 8'hc0;
  4'h1: disp_seg = 8'hf9;
  4'h2: disp_seg = 8'ha4;
  4'h3: disp_seg = 8'hb0;
  4'h4: disp_seg = 8'h99;
  4'h5: disp_seg = 8'h92;
  4'h6: disp_seg = 8'h82;
  4'h7: disp_seg = 8'hf8;
  4'h8: disp_seg = 8'h80;
  4'h9: disp_seg = 8'h90;
  4'ha: disp_seg = 8'h88;
  4'hb: disp_seg = 8'h83;
  4'hc: disp_seg = 8'hc6;
  4'hd: disp_seg = 8'ha1;
  4'he: disp_seg = 8'h86;
  4'hf: disp_seg = 8'h8e;
  endcase
 end
assign disp_bit = 8'b00000000;
endmodule


高工
2012-11-14 21:46:37     打赏
15楼
很详细,有图有真相~!

助工
2012-12-17 21:50:52     打赏
16楼

LCD1602程序中关于一段式和三段式的总结:
1 根据51FPGA提供的教程验证了控制1602的方法;
2 仔细阅读、体会anmko关于一段式、二段式、三段式的总结帖,链接
http://forum.eepw.com.cn/thread/221172/15#141,然后将51FPGA的教程修改为三段式格式。
3 在调试过程中遇见的问题包括以下几个方面:
(1) timescale应当修改为`timescale,否则综合时报错。
        `timescale是Verilog HDL 中的一种时间尺度预编译指令,它用来定义模块的仿真 时的时间单位和时间精度。格式如下:`timescale  仿真时间单位/时间精度。
(2) 同一个寄存器的值不要再两个不同的进程(always)中进行状态的改变,这个问题是在程序综合的过程中提示错误发现的。基础不够牢固啊!
(3)理解阻塞式语句和非阻塞式语句的区别。在该三段式程序中,阻塞式语句用在组合逻辑进程中,非阻塞式语句用在时序逻辑进程中。
4  1602程序主要包括状态切换和数据信号输出两个部分,状态切换又包括当前状态和下一状态两个部分。 一段式将状态切换和数据信号输出在一个进程中完成;三段式将过程分为当前状态、下一状态、数据信号输出三个进程来完成。
5  LCD1602的一段式与三段式程序如下所示:
(1)一段式程序:
always@(posedge clk_div or negedge sys_rstn) //State Machine
begin
 if(!sys_rstn)
  begin
   state   <= idle;
   lcd_data <= 8'bzzzzzzzz;
   char_cnt <= 5'd0;   
  end
 else
  begin
  case(state)
  idle: begin      //初始状态
     state <= clear;
     lcd_data <= 8'bzzzzzzzz;
    end
  clear: begin      //清屏
     state <= set_function;
     lcd_rs<=1'b0;
     lcd_data <= 8'b00000001;   
    end  
  set_function:      //功能设置(38H)
    begin
     state <= switch_mode;
     lcd_rs<=1'b0;
     lcd_data <= 8'b00111000;    
    end
  switch_mode:       //显示开关控制(0CH)
    begin
     state <= set_mode;
     lcd_rs<=1'b0;
     lcd_data <= 8'b00001100;
    end 
  set_mode:begin      //输入方式设置(06H
     state <= shift; 
     lcd_rs<=1'b0;
     lcd_data <= 8'b00000110;
    end
  shift: begin      //光标、画面位移设置(10H):
     state <= set_ddram1;
     lcd_rs<=1'b0;
     lcd_data <= 8'b0001_0000;   
    end  
  set_ddram1:          //设置DDRAM的地址 
    begin
     state <= write_ram1;
     lcd_rs<=1'b0;
     lcd_data <= 8'b1000_0000;//Line1   00H+80H=80H
    end
  set_ddram2:       //设置DDRAM的地址
    begin
     state <= write_ram2;
     lcd_rs<=1'b0;
     lcd_data <= 8'b1100_0000;//Line2  40H+80H=B0H
    end
  write_ram1:    
    begin         
     if(char_cnt <=5'd10)
      begin
       char_cnt <= char_cnt + 1'b1;
       lcd_rs<=1'b1;
       lcd_data <= data_disp;
       state <= write_ram1;
      end
     else
      begin
       state <= set_ddram2; 
      end    
    end
  write_ram2:    
    begin         
     if(char_cnt <=5'd26)
      begin
       char_cnt <= char_cnt + 1'b1;
       lcd_rs<=1'b1;
       lcd_data <= data_disp;
       state <= write_ram2;
      end
     else
      begin
       char_cnt <=5'd0;
       state <= shift; 
      end    
    end
  default:  state <= idle;
  endcase
  end
end
(2)三段式程序:

// 当前状态进程
always @(posedge clk_div or negedge rst)
begin
 if(!rst)
  begin
   current_state <= idle;
   char_cnt <=5'd0;
  end
 else
  case(next_state)
   write_ram1:
       begin
        if(char_cnt <5'd10)
          begin
           char_cnt <= char_cnt + 1'b1;
           current_state <= set_ddram1;
          end
         else
          begin
           char_cnt <= char_cnt + 1'b1;
           current_state <= write_ram1;
          end
       end
   write_ram2:
       begin
        if(char_cnt <=5'd26)
         begin
          char_cnt <= char_cnt + 1'b1;
          current_state <= set_ddram2;
         end
        else
         begin
          char_cnt <=5'd0;
          current_state <= write_ram2;
         end
       end
   default :
       begin
         if((next_state == set_ddram2))
          begin
           current_state <= next_state;
          end
         else
          begin
           char_cnt <=5'd0;
           current_state <= next_state;
          end
       end
  endcase
end

// 下一状态进程
always @(current_state)
begin
  case (current_state)
   idle         :  next_state = clear; 
   clear        :  next_state = set_function; 
   set_function :  next_state = switch_mode;
   switch_mode  :  next_state = set_mode;
   set_mode     :  next_state = shift;
   shift     :  next_state = set_ddram1;
   set_ddram1   :  next_state = write_ram1;
   write_ram1   :  next_state = set_ddram2;         
   set_ddram2   :  next_state = write_ram2;
   write_ram2   :  next_state = shift;     
   default      :  next_state = idle;
  endcase
end
       
always@(posedge clk_div or negedge rst) 
begin
 if(!rst)
  begin
   lcd_rs <= 1'b0;
   lcd_data <= 8'bzzzzzzzz;  
  end
 else
  begin
   case(next_state)
    idle         : lcd_rs<=1'b0;  
    clear        : lcd_rs<=1'b0;
    set_function : lcd_rs<=1'b0;  
    switch_mode  : lcd_rs<=1'b0;
    set_mode     : lcd_rs<=1'b0;
    shift        : lcd_rs<=1'b0;
    set_ddram1   : lcd_rs<=1'b0;
    set_ddram2   : lcd_rs<=1'b0;
    write_ram1   : lcd_rs<=1'b1;   
    write_ram2   : lcd_rs<=1'b1;
    default      : lcd_rs<=1'b0;
   endcase
   
   case(next_state)
    idle         :  lcd_data <= 8'bzzzzzzzz;
    clear        :  lcd_data <= 8'b00000001;    
    set_function :  lcd_data <= 8'b00111000;    
    switch_mode  :  lcd_data <= 8'b00001100;
    set_mode     :  lcd_data <= 8'b00000110;
    shift        :  lcd_data <= 8'b00010000;    
    set_ddram1   :  lcd_data <= 8'b10000000;   //Line1
    set_ddram2   :  lcd_data <= 8'b11000000;   //Line2  
    write_ram1   :  lcd_data <= data_disp;
    write_ram2   :  lcd_data <= data_disp;
   endcase
  end
end


        在三段式程序的调试过程中,遇见第二行从第一个字符开始执行的情况,解决方法是在当前状态的进程中增加 set_ddram2的状态值判断,此时   char_cnt 不能等于0即可。


1602 一段式与三段式.rar


共16条 2/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]