【FPGA】PWM控制呼吸灯

【FPGA】PWM控制呼吸灯


PWM控制呼吸灯

  • 【FPGA】PWM控制呼吸灯
  • 一、PWM
    • 1、PWM基本概念
    • 2、占空比
    • 3、PWM信号
    • 4、呼吸灯实现方法
  • 二、呼吸灯实现思路
  • 三、PWM实现
    • 1.PWM模块
    • 2.计数器实现PWM
    • 3、状态机实现呼吸灯
  • 四、结果
    • 1、PWM仿真程序编写
    • 2、PWM仿真结果


一、PWM

1、PWM基本概念

利用微处理器FPGA的数字输出对模拟电路进行控制的一种有效技术,数字信号从微处理器到被控系统都为数字形式(控制占空比),为一种连续的具有一定占空比的脉冲信号(方波)。

2、占空比

占空比的概念:

占空比是指在一个脉冲循环内,通电时间相对于总时间所占的比例。占空比(Duty Ratio)在电信领域中有如下含义:例如:脉冲宽度1μs,信号周期4μs的脉冲序列占空比为0.25。

【FPGA】PWM控制呼吸灯_第1张图片
如图所示,该图片中脉冲的占空比为Ton/T。

3、PWM信号

【FPGA】PWM控制呼吸灯_第2张图片
如图所示,上述图片为占空比为25%的信号,则该信号的对应电压为高电平电压的25%。
【FPGA】PWM控制呼吸灯_第3张图片

4、呼吸灯实现方法

通过PWM可以进行数模转换的特性,控制每一个时间段的LED灯的亮度,实现LED灯的亮度变换来实现呼吸灯。


二、呼吸灯实现思路

呼吸灯PWM实现:

由于LED灯先逐渐变亮后逐渐熄灭,可知其波形图为占空比先增大后占空比逐渐减小。
【FPGA】PWM控制呼吸灯_第4张图片
由图可知,占空比由1us逐渐增加到1000us再由1000us逐渐减小到1us。

三、PWM实现

1.PWM模块

代码如下:

module PWM(
    input           sysclk          ,
    input           rst_n           ,
    output   reg    led             
    );
parameter           TIME_ms = 50_000;
parameter           TIME_us = 50;
parameter           T = 2000;
reg         [15:0]   cnt_ms;
reg         [5:0]    cnt_us;
reg         [17:0]   ms;
reg         [17:0]   us;

2.计数器实现PWM

代码如下:

//——————————COUNT_1us————————//
always@(posedge sysclk)
    if(!rst_n)
        cnt_us <= 0;
     else if(cnt_us == TIME_us - 1)//每50个时钟周期清零
        cnt_us <= 0;
     else
        cnt_us <= cnt_us + 1;
//————————COUNT_us————————//
always@(posedge sysclk)
    if(!rst_n)
        us <= 0;
    else if(cnt_us == TIME_us - 1)
        begin
            if(us == T)//2ms
                us <= 0;
            else
                us <= us + 1;
        end 
//-———————COUNT_1ms——————//
always@(posedge sysclk)
    if(!rst_n)
        cnt_ms <= 0;
    else if(cnt_ms == TIME_ms - 1)
        cnt_ms <= 0;
    else
        cnt_ms <= cnt_ms + 1;
//———————COUNT_ms————————//
always@(posedge sysclk)
    if(!rst_n)
        ms <= 0;        
    else if(cnt_ms == TIME_ms - 1)
        begin
            if(ms == T )//2s
                ms <= 0;
            else
                ms <= ms + 1;
        end

3、状态机实现呼吸灯

代码如下:

parameter           IDLE = 3'b001,
                     UP   = 3'b010,
                     DOWN = 3'b100;
reg         [2:0]    cur_state;
reg         [2:0]    next_state;
//——————————FIRST————————//
always@(posedge sysclk)
    if(!rst_n)
        cur_state <= IDLE;
     else
        cur_state <= next_state;
//——————————SECOND————————//
always@(*)
    case(cur_state)
        IDLE    :begin
            next_state = UP;
        end
         UP     :begin
                if(ms == T && cnt_ms == TIME_ms - 1)//当时间到达2s以后进入占空比逐渐减小的状态
                    next_state = DOWN;
                 else
                    next_state = UP;
         end
         DOWN   :begin
                if(ms == T && cnt_ms == TIME_ms - 1)//当时间到达2s以后回到空闲状态
                    next_state = IDLE;
                 else
                    next_state = DOWN;
         end
         default :begin
            next_state = IDLE;
         end
    endcase   
//——————————THIRD——————————//
always@(posedge sysclk)
    if(!rst_n)begin
        led <= 0;  
    end
    else
        case(cur_state)
            IDLE :begin
               led <= 0;//初始化LED
            end
             UP  :begin
                led <= ( ms >= us ) ? 1 : 0 ;//占空比逐渐增大
             end
             DOWN:begin
                led <= ( ms >= us ) ? 0 : 1 ;//占空比逐渐减小
             end
             default:begin
                led <= 0;
             end
        endcase
//——————————————————————//

四、结果

1、PWM仿真程序编写

仿真程序编写:

`timescale 1ns / 1ps
module TEST();
reg sysclk;
reg rst_n;
wire led;
PWM pwm(
    .sysclk          (sysclk),
    .rst_n           (rst_n ),
    .led             (led   )
    );
initial
begin
    sysclk = 1;
    rst_n =0;
    #10
    rst_n = 1;
end
always #1 sysclk = ~sysclk;
endmodule

2、PWM仿真结果

仿真结果:

【FPGA】PWM控制呼吸灯_第5张图片
由图可以看出led的占空比之间有细微的变化,证明PWM编写成功。

你可能感兴趣的:(fpga开发)