这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » holdmyhand 进程贴 → 按键篇

共15条 2/2 1 2 跳转至
高工
2012-10-28 09:42:44     打赏
11楼
不错,视频+代码分析~!

工程师
2012-10-29 10:41:59     打赏
12楼
1)LED花样彩灯实验功能完成.
8个LED闪烁两次→向右流水灯→向左跑马灯→两边向内流水→如此循环往复...
2)实际效果如视频所示:

3)程序代码如下,还未进一步精简:
//LED花样彩灯
//holdmyhand 10月28日 16:09:43
module led_hy(sys_clk, sys_rstn, led);
    input sys_clk;
    input sys_rstn;
    output [7:0] led;
    reg [7:0] led;
    reg [31:0] delay_cnt;  //延时计数器
    reg [31:0] counter;  //计数变量
    reg [1:0] current_state, next_state;  //LED当前状态,下一状态
    reg [3:0] led_h, led_l;
    parameter ALL_ON=8'b00000000, ALL_OFF=8'b11111111;  //参数定义 符号常量
    parameter S0=2'b00, S1=2'b01, S2=2'b10, S3=2'b11;
   
    always @(posedge sys_clk or negedge sys_rstn)
        begin
            if(!sys_rstn)
                delay_cnt <= 32'd0;
            else
                begin
                    if(delay_cnt==32'd24999999)
                        delay_cnt <= 32'd0;
                    else
                        delay_cnt <= delay_cnt + 1'b1;
                end
        end
    always @(posedge sys_clk or negedge sys_rstn)
        begin
            if(!sys_rstn)
                begin
                    led <= ALL_OFF;
                    counter <= 32'd0;
                    current_state <= S0;
                    led_h <= 4'b0111;
                    led_l <= 4'b1110;
                end
            else
                begin
                    if(delay_cnt==32'd24999999)
                        begin
                            case(current_state)
                                S0:begin
                                        counter <= counter + 1'b1;
                                        if(counter<32'd3)
                                            led <= ~led;
                                        else
                                            begin
                                                counter <= 32'd0;
                                                led <= 8'b01111111;
                                                next_state <= S1;
                                            end                                           
                                    end
                                S1:begin
                                        led <= led >> 1;  //右移
                                        if(led==ALL_ON)
                                            begin
                                                led <= 8'b11111110;
                                                next_state <= S2;
                                            end                                           
                                    end
                                S2:begin
                                        led <= {led[6:0], led[7]};  //移位寄存器左移一位操作
                                        if(led==8'b01111111)
                                            begin
                                                led <= {led_h, led_l};
                                                next_state <= S3;
                                            end
                                    end
                                S3:begin
                                        led_h <= led_h >> 1;
                                        led_l <= led_l << 1;
                                        led <= {led_h, led_l};
                                        if(led==ALL_ON)
                                            begin
                                                led_h <= 4'b0111;
                                                led_l <= 4'b1110;
                                                led <= ALL_OFF;
                                                next_state <= S0;
                                            end
                                    end
                                default:led <= led;
                            endcase
                        end
                    else
                        led <= led;
                    current_state <= next_state;
                end
        end
endmodule  

工程师
2012-10-29 10:44:49     打赏
13楼

还请版主多多指点啊...


工程师
2012-11-05 16:17:40     打赏
14楼

1) 数码管静态显示、动态显示及模为60的计数器显示效果如下:



2) 模为60的计数器,功能实现代码如下:
module modulo_60(sys_clk, sys_rstn, sm_seg, sm_bit);
 
//输入输出信号
    input sys_clk;
    input sys_rstn;
    output [7:0] sm_seg;
    output [7:0] sm_bit;
//寄存器定义
    reg [7:0] sm_seg;
    reg [7:0] sm_bit;
    reg [3:0] tens;  //十位数
    reg [3:0] units;  //个位数
    reg [3:0] dataout_buf;
    reg [31:0] scan_cnt;  //扫描延时计数器
    reg [31:0] delay_cnt;  //延时计数器
    reg disp_dat;
//逻辑部分
    always @(posedge sys_clk or negedge sys_rstn)//动态扫描延时
        begin
            if(!sys_rstn)
                scan_cnt <= 32'd0;
            else
                begin
                    if(scan_cnt==32'd49999)
                        scan_cnt <= 32'd0;
                    else
                        scan_cnt <= scan_cnt + 1'b1;
                end
        end
    always @(posedge sys_clk or negedge sys_rstn)//模计数延时
        begin
            if(!sys_rstn)
                delay_cnt <= 32'd0;
            else
                begin
                    if(delay_cnt==32'd49999999)
                        delay_cnt <= 32'd0;
                    else
                        delay_cnt <= delay_cnt + 1'd1;
                end
        end
    always @(posedge sys_clk or negedge sys_rstn)
        begin
            if(!sys_rstn)
                disp_dat <= 1'b0;
            else
                begin
                    if(scan_cnt==32'd49999)
                        disp_dat <= disp_dat + 1'b1;
                    else
                        disp_dat <= disp_dat;
                end
        end
    always @(posedge sys_clk or negedge sys_rstn)
        begin
            if(!sys_rstn)
                begin
                    units = 4'h0;
                    tens = 4'h0;
                end
            else
                begin
                    if(delay_cnt==32'd49999999)
                        begin
                            units = units + 1'b1;
                            if(units==4'ha)
                                begin
                                    units = 4'h0;
                                    tens = tens + 1'b1;
                                    if(tens==4'h6)
                                        tens = 4'h0;
                                end
                        end
                    else
                        begin
                            units = units;
                            tens = tens;
                        end
                end
        end   
    always @(disp_dat)
        begin
            case(disp_dat)
                1'b0: sm_bit = 8'b1111_1110;
                1'b1: sm_bit = 8'b1111_1101;
                default:
                        sm_bit = 8'b1111_1110;
            endcase
        end
    always @(sm_bit)
        begin
            case(sm_bit)
                8'b1111_1110: dataout_buf = units;
                8'b1111_1101: dataout_buf = tens;
                default:dataout_buf = 4'ha;
            endcase
        end
    always @(dataout_buf)
        begin
            case(dataout_buf)
                4'h0: sm_seg = 8'hc0;
                4'h1: sm_seg = 8'hf9;
                4'h2: sm_seg = 8'ha4;
                4'h3: sm_seg = 8'hb0;
                4'h4: sm_seg = 8'h99;
                4'h5: sm_seg = 8'h92;
                4'h6: sm_seg = 8'h82;
                4'h7: sm_seg = 8'hf8;
                4'h8: sm_seg = 8'h80;
                4'h9: sm_seg = 8'h90;
                4'ha: sm_seg = 8'h88;
                default:
                        sm_seg = 8'hc0;
            endcase
        end 
endmodule


工程师
2012-12-20 20:53:15     打赏
15楼

5.8课后作业
按键消抖控制1位数码管循环显示0-9,代码如下:
module key_dt(sys_clk,
                  sys_rstn,
                  key_in,
                  sm_seg,
                  sm_bit);
                 
    input sys_clk;
    input sys_rstn;
    input key_in;
    output [7:0] sm_seg;  //段码
    output [7:0] sm_bit;  //位码
   
    reg [7:0] sm_seg;
    wire [7:0] sm_bit;
    reg [3:0] disp_dat;  //显示数据寄存器
    reg [19:0] delay_cnt;
    wire key_scan;
    wire key_low;
    reg key_samp;
    reg key_samp_r;
    reg key_rst;
    reg key_rst_r;
//按键脉冲边沿检测
    always @(posedge sys_clk or negedge sys_rstn)
        begin
            if(!sys_rstn)
                key_samp <= 1'b1;
            else
                key_samp <= key_in;
        end
    always @(posedge sys_clk or negedge sys_rstn)
        begin
            if(!sys_rstn)
                key_samp_r <= 1'b1;
            else
                key_samp_r <= key_samp;
        end
    assign key_scan = key_samp_r & (~key_samp);
//20ms延时,再次检测
    always @(posedge sys_clk or negedge sys_rstn)
        begin
            if(!sys_rstn)
                delay_cnt <= 20'h0;
            else if(key_scan)
                delay_cnt <= 20'h0;
            else
                delay_cnt <= delay_cnt + 1'b1;
        end
    always @(posedge sys_clk or negedge sys_rstn)
        begin
            if(!sys_rstn)
                key_rst <= 1'b1;
            else if(delay_cnt==20'hfffff)
                key_rst <= key_in;
        end
    always @(posedge sys_clk or negedge sys_rstn)
        begin
            if(!sys_rstn)
                key_rst_r <= 1'b1;
            else
                key_rst_r <= key_rst;
        end
    assign key_low = key_rst_r & (~key_rst);
//按键控制1位数码管循环显示0-9
    always @(posedge sys_clk or negedge sys_rstn)
        begin
            if(!sys_rstn)
                disp_dat <= 4'd0;
            else if(key_low)
                begin
                    disp_dat <= disp_dat + 1'b1;
                    if(disp_dat==4'h9)
                        disp_dat <= 4'd0;
                end
            else
                disp_dat <= disp_dat;
        end
    always @(disp_dat)
        begin
            case(disp_dat)
                4'h0: sm_seg = 8'hc0;
                4'h1: sm_seg = 8'hf9;
                4'h2: sm_seg = 8'ha4;
                4'h3: sm_seg = 8'hb0;
                4'h4: sm_seg = 8'h99;
                4'h5: sm_seg = 8'h92;
                4'h6: sm_seg = 8'h82;
                4'h7: sm_seg = 8'hf8;
                4'h8: sm_seg = 8'h80;
                4'h9: sm_seg = 8'h90;
            endcase
        end
    assign sm_bit = 8'b0111_1111;
       
endmodule


共15条 2/2 1 2 跳转至

回复

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