利用PWM脉宽调制实现呼吸灯
1.设计目标
完成一个呼吸灯,从亮到灭的时间为2秒,从灭到亮的时间为2秒,以此不断往复。
2.设计步骤
2.1设计分析
利用PWM(脉冲宽度调制)实现led灯亮度的变化,只需要改变占空比就可以实现,具体操作是将2秒分为1000份,每份即2/1000(2ms),也就是说一个pwm周期为2ms。在这样一个2ms周期内,改变占空比,且随着周期数变化,占空比也在变化,就可以显示出亮度变化的过程。
比如在第一个2s内,这个2秒内led灯的亮度是越来越暗的,所以具体操作为:把每个周期(2ms)再分成1000份,即一份为2us(这个2us称之为pwm的最小分辨率),在第一个2ms内高电平为1000个2us;在第二个2ms内低电平的个数为1个2us,高电平的个数为999个2us;第三个2ms内低电平的个数为2个2us,高电平的个数为998个2us;以此类推,最后一个2ms,低电平的个数为1000个2us。从而实现,每2ms亮度变化一次,一个2s内亮度变化了一千次,在肉眼看来,这个亮度的变化过程是非常平滑的。
反过来,亮度增加过程也是一样的,只要按2ms增大占空比即可实现。
2.2设计波形图

由图可知,一共需要三个计数器:T20us_count、T2us_count、T2ms_count。分别用于计算20ns,2us,2ms的个数。当T20us_count等于99时,代表计时2us(20ns*100)已到;当T2us_count等于999、T20us_count等于99时,代表2ms(2us*1000)已到;同理,当T2ms_count等于999、T2us_count等于999、T20us_count等于99时,代表2s(2ms*1000)已到。
观察波形图,在第一个2ms内,led_pwm都为高电平。在第二个2ms内,led_pwm在T2us_count为0时为低电平,大于等于0时为高电平。在第三个2ms,T2ms_count等于2,则在T2us_count等于0、1时,led_pwm为低电平,大于1时为高电平。因此可以得到一般规律,T2ms_count是用于计算2ms的个数,从0逐渐增长到999,代表第1个2ms到第1000个2ms,所以在任意一个2ms内,T2us_count小于T2ms_count,led_pwm为低电平,大于则为高电平。
第2个2s,亮度是慢慢增加的,过程与亮度减少是相逆的,T2us_count小于T2ms_count,led_pwm为高电平,大于则为低电平,从而实现占空比越来越大,从而实现亮度慢慢增加。
3.Verilog 代码
module pwm_led(
input wire Clk,
input wire Rst_n,
output wire led_pwm
); wire Rst;
assign Rst=~Rst_n; //定时2us,即pwm脉冲的最小分辨率
parameter T2us=8'd99;
reg [7:0]T20ns_count; //计算20ns的个数
always@(posedge Clk or posedge Rst)
if(Rst)
begin
T20ns_count<='d0;
end
else if(T20ns_count==T2us) //20ns*100=2us定时时间到
begin
T20ns_count<='d0;
end
else
T20ns_count<=T20ns_count+1'b1; //20us时间到,计数器加一 //定时2ms,即pwm的一个周期
parameter T2ms=12'd999;
reg [11:0]T2us_count;
always@(posedge Clk or posedge Rst)
if(Rst)
begin
T2us_count<='b0;
end
else if((T2us_count==T2ms)&&(T20ns_count==T2us)) //2us*1000=2ms定时时间到
begin
T2us_count<='b0;
end
else if(T20ns_count==T2us) //2us时间到,计数器加一
T2us_count<=T2us_count+1'b1; //定时2s
reg H_L_flag;//亮到灭,灭到亮的标志位
parameter T2s=12'd999;
reg [11:0]T2ms_count;
always@(posedge Clk or posedge Rst)
if(Rst)
begin
T2ms_count<='b0;
H_L_flag<='b0;
end
else if((T2ms_count==T2s)&&(T2us_count==T2ms)&&(T20ns_count==T2us)) //2ms*1000=2s定时时间到
begin
T2ms_count<='b0;
H_L_flag<=~H_L_flag;
end
else if((T2us_count==T2ms)&&(T20ns_count==T2us)) //2ms时间到,计数器加一
T2ms_count<=T2ms_count+1'b1; //PWM控制模块
assign led_pwm=(T2us_count<T2ms_count)?H_L_flag:~H_L_flag; endmodule
4.testbench代码
`timescale 1ns/1ns
`define clock_period 20
module pwm_led_tb; reg Clk;
reg Rst_n;
wire led_pwm_out;
pwm_led U0(
.Clk (Clk),
.Rst_n (Rst_n),
.led_pwm (led_pwm)
); initial Clk=1'b0;
always #(`clock_period/2) Clk=~Clk; initial
begin
Rst_n<=1'b0;
#(`clock_period*2);
Rst_n<=1'b1;
end endmodule
5.结语
以上程序经过ModelSim仿真,仿真通过后,也经过了上板验证,开始2s,led灯的亮度能够很平滑的下降,后一个2s,亮度能够慢慢提高,如此往复操作,实现4s为周期的呼吸灯。
利用PWM脉宽调制实现呼吸灯的更多相关文章
- PWM输出,呼吸灯
一.初始化GPIO 使用PB1,查芯片手册对应TIM3_CH4 GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2 ...
- PWM(脉宽调制)——LED特效呼吸灯设计
简述PWM PWM--脉宽调制信号(Pulse Width Modulation),它利用微处理器的数字输出来实现,是对模拟电路控制的一种非常有效的技术,广泛应用于测量.通信.功率控制与变化等许多领域 ...
- [FPGA]Verilog利用PWM调制巧妙完成RGB三色彩虹呼吸灯(给简约的题目以美妙的解答)
概述 实现彩虹呼吸灯 题目就是这么简短,但这是目前我碰到的最有意思的一道题目,因为他有无数种解决方法,并且每一种都是那么高级或者巧妙,比如 可以利用3路不同初相的PWM调制信号驱动三颗RGB灯重叠呼吸 ...
- 浅浅的分析LED呼吸灯的实现和PWM的关系
前言 在本周,我们在python课上做了一个实验,用ARDUINO使小LED灯模仿出呼吸灯的效果,实验进行的很成功,但是机器当仅输出高/低电平的时候是怎么样才能做到渐亮渐暗(输出电压)的变化呢?在这里 ...
- 【iCore4 双核心板_ARM】例程八:定时器PWM实验——呼吸灯
实验原理: STM32的定时器有PWM功能,iCore4的蓝色LED连接在定时器的输出接口上, 可以通过定时器的PWM输出控制LED的亮度,从而实验呼吸灯的功能. 核心代码: int main(voi ...
- STM8S003F3通过PWM波实现三基色呼吸灯(转)
源: STM8S003F3通过PWM波实现三基色呼吸灯
- STM8S PWM 应用 呼吸灯
//主功能接受:使用MCU STM8S105C6 的PWM通道2 PC2 来做呼吸灯 已经验证OK,呵 //呵,这个PWM设置刚開始用还是有点麻烦,由于是自己摸索.花点时间.还是解决了 . //所用子 ...
- 12-ESP8266 SDK开发基础入门篇--PWM,呼吸灯
https://www.cnblogs.com/yangfengwu/p/11094085.html PWM其实没有什么,就是看着官方给的API,,,然后就是用呗 对了,其实对于RTOS SDK版本的 ...
- Arduino系列之pwm控制LED灯(呼吸灯)
下面我将写出最简单控制呼吸灯的方法 void setup() // { pinMode(12,OUTPUT); ...
随机推荐
- Solon rpc 之 SocketD 协议 - 单链接双向RPC模式
Solon rpc 之 SocketD 协议系列 Solon rpc 之 SocketD 协议 - 概述 Solon rpc 之 SocketD 协议 - 消息上报模式 Solon rpc 之 Soc ...
- 记一次Goroutine与wg导致的问题
前言 今天发现了一个问题是之前一直没有注意到的,这里记一下 正文 Send Closed Chan 问题概述 代码逻辑是启动时启动多个 channel, channel1 获取数据监听数据处理后发送给 ...
- 【SpringBoot1.x】SpringBoot1.x 启动配置原理 和 自定义starter
SpringBoot1.x 启动配置原理 和 自定义starter 启动配置原理 本节源码 启动过程主要为: new SpringApplication(sources) 创建 SpringAppli ...
- LeetCode561 数组拆分 I
给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大. 示例 ...
- 【Linux】find查找空文件夹
linux下批量删除空文件(大小等于0的文件)的方法 find . -name "*" -type f -size 0c | xargs -n 1 rm -f 就是删除1k大小的文 ...
- 【ORA】ORA-00030: User session ID does not exist.
今天巡检,查询锁相关的情况的时候,确认业务后,准备将锁干掉,但是干掉的时候报了一个错误,ORA-00030 发现回话不存在,我以为pmon进程已经将锁进程kill掉了,就再次查看,发现,还是存在 这个 ...
- kubernets之Deployment资源
一 声明式的升级应用 1.1 回顾一下kubernets集群里面部署一个应用的形态应该是什么样子的,通过一副简单的图来描述一下 通过RC或者RS里面的模板创建了三个pod,之后通过一个servci ...
- 一句话木马拿下webshell
1.我们先建立一个简单的一句话木马文件,我们这里就命名为shell2吧. 2.因为提交的文件可能是有过滤的,我们这个靶场的这个题目就是禁止上传危险的文件类型,如jsp jar war等,所以就需要绕过 ...
- salesforce零基础学习(一百)Mobile Device Tracking
本篇参考: Mobile Device Tracking (salesforce.com) UserDevice | SOAP API Developer Guide | Salesforce Dev ...
- SQLHelper ------ python实现
SQLHelper ------ python实现 1.第一种: import pymysql import threading from DBUtils.PooledDB import Pooled ...