按键消抖+PWM显示(附代码)

目录

前言

一、呼吸灯是啥?

二、模块划分

1、顶层模块

2.按键消抖模块

3、PWM模块

总结


前言

该工程实现了频率可调的LED呼吸灯,分为了三个模块,一个顶层


提示:以下是本篇文章正文内容,下面案例可供参考

一、呼吸灯是啥?

        玩转电路从点亮一个芯片开始,啊,不对,是点亮一个LED开始,哈哈哈。几乎所有语言的学习开始都是点亮led,或者Hello word,开始认识世界。慢慢的就是接触按键,按键消抖,这种类型的项目。作为学习,该项目把按键消抖和呼吸灯结合到一起。记录一下吧

二、模块划分

1、顶层模块

代码如下(示例):

//======================================================================
//Company            : 
//Filenam            : .v
//Author            : HX
//Created On        : 2024-03-13 11:03
//Last Modified        : 
//Description        : The project is divided into three modules:
//                    U1 is the PLL module,
//                    U2 is the PWM module, 
//                    U3 is the button jitter reduction and blink frequency control module 
//======================================================================
`timescale 1ns / 1ps

module breath_led(
    input                           clk                ,   //   clk 50Mhz
    input                           rst_n              ,   //   system reset
    input                             key                   ,   //   input button
    output      [3:0]               led                    //   ouput four led,"0" active
    );
 
    wire                            clk_50M            ;   //
    wire        [15:0]              Blink_Speed        ;   //   blink frequency control

    PLL u1_PLL(
        .clk_out1(            ),     // output clk_out1 25Mhz
        .clk_out2(clk_50M    ),     // output clk_out2 50Mhz
        .clk_out3(            ),     // output clk_out3 100Mhz
        .clk_out4(            ),     // output clk_out4 200Mhz
        .reset   (~rst_n    ),     // input reset   "1"active
        .locked  (          ),     // output locked
        .clk_in1 (clk       )       // input clk_in1 50Mhz
    );      
    
   led_pwm u2_led_pwm(
        .clk        (clk_50M    ), // input clk 50Mhz
        .rst_n      (rst_n        ), // input reset
        .Blink_Speed(Blink_Speed), // blink frequency control
        .led        (led        )  // output led,"0"active
    );
    
    led_key u3_led_key(
        .clk         (clk_50M    ), // input clk 50Mhz
        .rst_n       (rst_n      ), // input reset
        .key         (key        ), // input button
        .Blink_Speed (Blink_Speed)  // blink frequency control
    );

endmodule

分了三个模块,PLL,按键消抖和PWM调波

2.按键消抖模块

代码如下(示例):

`timescale 1ns / 1ps
//======================================================================
//Company            : 
//Filenam            : .v
//Author            : HX
//Last Modified        : 2024-03-13 11:34
//Last Modified        : 2023-12-14 18:10
//Description        : button jitter reduction module
//                      blink frequency control module
//                  
//                  
//=====================================================================
module led_key(
    input                           clk                   ,   //    system clk 50Mhz
    input                           rst_n                 ,   //    system reset
    input                           key                   ,   //    input button
    output      reg     [15:0]         Blink_Speed                     //    output blink freqyency control
    );
    
    parameter                       FREQ        =   50    ;   //    ferquency ()Mhz
    parameter                       TIME_MAX    =   20    ;   //    button running timem
//  parameter                       TIME_MAX    =   1     ;   //    button running timem (1 ms for simulation test)
    
    localparam                      TIME_VAL    =   TIME_MAX * FREQ * 1000    ;   //the cycle of running time
    
    reg                             key_value             ;   //    buttom active 
    reg                             key_flag              ;   //    buttom be pressed
    reg         [   19:0    ]       key_cnt               ;   //    buttom Shake free count
    reg                             key_r1                ;   //    reg1 key
    reg                             key_r2                ;   //    reg2 key   
    reg         [    2:0    ]       blink_cnt             ;   //    blink frequency count
    
/**************************************************************************
//take two beats for key
//generata key_value and key_flag
**************************************************************************/
    always  @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            key_r1 <= 1'b1;
            key_r2 <= 1'b1;
        end
        else begin
            key_r1 <= key;
            key_r2 <= key_r1;
        end
    end 

    always @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            key_cnt <= 20'd0;
        end
        else begin
            if( key_r2 == !key_r1)begin
                key_cnt <= TIME_VAL;
            end 
            else begin
                if( key_cnt > 20'd0) 
                    key_cnt <= key_cnt - 1'b1;
                else 
                    key_cnt <= 20'd0;
            end                
        end
    end
    
    always @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            key_value <= 1'b1;
            key_flag  <= 1'b0;
        end
        else if (key_cnt == 20'd1)begin
            key_value <= key;
            key_flag  <= 1'b1;
        end 
        else begin
            key_value <= key_value;
            key_flag  <= 1'b0;       
        end
    end
/**************************************************************************
//generate blink count and Blink_Speed
**************************************************************************/
    always  @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            blink_cnt  <= 3'd0;
        end
        else if(key_flag&&!key_value)begin
            blink_cnt <= blink_cnt + 1'b1;
        end
        else begin
            blink_cnt <= blink_cnt ;
        end
    end
    
    always  @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            Blink_Speed  <= 16'd25;
        end
        else 
        case(blink_cnt)
            3'd0 :    Blink_Speed  <= 16'd25;
            3'd1 :    Blink_Speed  <= 16'd50;
            3'd2 :    Blink_Speed  <= 16'd100;
            3'd3 :    Blink_Speed  <= 16'd200;
            3'd4 :    Blink_Speed  <= 16'd500;
            3'd5 :    Blink_Speed  <= 16'd1000;
            3'd6 :    Blink_Speed  <= 16'd5;
            3'd7 :    Blink_Speed  <= 16'd10;
            default : Blink_Speed  <= 16'd25;
        endcase
    end
    
    
endmodule


该模块实现了按键消抖的功能,每次按键按下控制led的闪烁频率控制字输出至Pwm模块

3、PWM模块

//======================================================================
//Company            : 
//Filenam            : .v
//Author            : HX
//Created On        : 2024-03-13 11:34
//Last Modified        : 2024-03-13 11:34
//Description        :PWM module 
//                  
//                  
//======================================================================
`timescale 1ns / 1ps
module led_pwm(
    input                           clk                 ,   //  system clk 50Mhz
    input                           rst_n               ,   //  system reset 
    input       [   15:0    ]       Blink_Speed         ,   //  input blink frequency
    output      [    3:0    ]       led                     //  output led  "0" active
    );
    reg         [   15:0    ]       period_cnt          ;   //  1kHz-1ms:1000_000/20=50000
    reg         [   15:0    ]       duty_cycle          ;   //  1% increase in each cycle:50000*1%=500;
    reg                             inc_dec_flag        ;   //  the flag that from bright to dark or from dark to bright //0:from dark to bright
    reg         [   15:0    ]       r_Blink_Speed       ;   //  cache one shot
   
    assign led = (period_cnt >= duty_cycle) ? 4'b1010 : 4'b0101;
/**************************************************************************
//PWM: the cycle sets to 1ms
//compare period_cnt and duty_cycle with in this 1ms
//EX:   the duty cycle is 10% in this 1ms,the meaning is led bright 0.1ms
//      the duty cycle is 20% in next 1ms,the meaning is led bright 0.2ms
//      ...
//      the duty cycle is 100% in next 1ms,the meaning is led bright 1ms
//      Within 10ms, the light gradually changes from dark to bright
**************************************************************************/
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            r_Blink_Speed <= 16'd50;
        else 
            r_Blink_Speed <= Blink_Speed;
    end

    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            period_cnt <= 16'd0;
        else if (period_cnt == 16'd50000)
            period_cnt <= 16'd0;
        else 
            period_cnt <= period_cnt + 1'b1;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            duty_cycle <= 16'd0;
            inc_dec_flag <= 1'b0;
        end
        else begin
            if(period_cnt == 16'd50000) begin
                if(inc_dec_flag == 1'b0)begin
                    if(duty_cycle == 16'd50000) begin
                        inc_dec_flag <= 1'b1;
                    end    
                    else begin
                        duty_cycle <= duty_cycle + r_Blink_Speed;
                    end
                end
                else begin
                    if(duty_cycle == 16'd0) begin
                        inc_dec_flag <= 1'b0;
                    end    
                    else  begin
                        duty_cycle <= duty_cycle - r_Blink_Speed;
                    end
                end
            end
        end            
    end
    
endmodule


总结

很简单的有个小功能,仿真就不放了,加油

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于STM32的按键控制LED的PWM代码示例: 首先,需要在代码中定义使用的引脚以及相关的寄存器: ``` #define LED_PIN GPIO_Pin_0 #define LED_PORT GPIOA #define KEY_PIN GPIO_Pin_1 #define KEY_PORT GPIOA #define RCC_AHBPeriph_GPIOA RCC_AHBPeriph_GPIOA #define RCC_APB1Periph_TIM3 RCC_APB1Periph_TIM3 #define TIM3_CH1_PIN GPIO_Pin_6 #define TIM3_CH1_PORT GPIOA #define TIM3_CH1_PINSOURCE GPIO_PinSource6 #define TIM3_CH1_AF GPIO_AF_1 #define TIM3_PRESCALER 72 ``` 然后,需要在代码中初始化相关的GPIO和定时器: ``` void init_gpio(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_InitStruct.GPIO_Pin = LED_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(LED_PORT, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = KEY_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(KEY_PORT, &GPIO_InitStruct); GPIO_PinAFConfig(TIM3_CH1_PORT, TIM3_CH1_PINSOURCE, TIM3_CH1_AF); } void init_timer(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_TimeBaseInitStruct.TIM_Prescaler = TIM3_PRESCALER - 1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 2000 - 1; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct); TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse = 1000; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStruct); TIM_Cmd(TIM3, ENABLE); } ``` 接下来,需要实现一个函数来读取按键状态: ``` int read_key(void) { if (GPIO_ReadInputDataBit(KEY_PORT, KEY_PIN) == 0) { return 1; } else { return 0; } } ``` 最后,需要在主循环中实现按键控制LED的PWM: ``` int main(void) { init_gpio(); init_timer(); while (1) { if (read_key()) { TIM_SetCompare1(TIM3, 1000); } else { TIM_SetCompare1(TIM3, 0); } } } ``` 上述代码中,按键的状态会被不断地读取,如果按键被按下,则LED的PWM占空比为50%(即1000/2000),否则PWM占空比为0。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值