【FPGA】PWM控制呼吸灯
PWM控制呼吸灯
一、PWM
1、PWM基本概念
利用微处理器FPGA的数字输出对模拟电路进行控制的一种有效技术,数字信号从微处理器到被控系统都为数字形式(控制占空比),为一种连续的具有一定占空比的脉冲信号(方波)。
2、占空比
占空比的概念:
占空比是指在一个脉冲循环内,通电时间相对于总时间所占的比例。占空比(Duty Ratio)在电信领域中有如下含义:例如:脉冲宽度1μs,信号周期4μs的脉冲序列占空比为0.25。
如图所示,该图片中脉冲的占空比为Ton/T。
3、PWM信号
如图所示,上述图片为占空比为25%的信号,则该信号的对应电压为高电平电压的25%。
4、呼吸灯实现方法
通过PWM可以进行数模转换的特性,控制每一个时间段的LED灯的亮度,实现LED灯的亮度变换来实现呼吸灯。
二、呼吸灯实现思路
呼吸灯PWM实现:
由于LED灯先逐渐变亮后逐渐熄灭,可知其波形图为占空比先增大后占空比逐渐减小。
由图可知,占空比由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仿真结果
仿真结果:
由图可以看出led的占空比之间有细微的变化,证明PWM编写成功。