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脉宽调制实现呼吸灯的更多相关文章

  1. PWM输出,呼吸灯

    一.初始化GPIO 使用PB1,查芯片手册对应TIM3_CH4 GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2 ...

  2. PWM(脉宽调制)——LED特效呼吸灯设计

    简述PWM PWM--脉宽调制信号(Pulse Width Modulation),它利用微处理器的数字输出来实现,是对模拟电路控制的一种非常有效的技术,广泛应用于测量.通信.功率控制与变化等许多领域 ...

  3. [FPGA]Verilog利用PWM调制巧妙完成RGB三色彩虹呼吸灯(给简约的题目以美妙的解答)

    概述 实现彩虹呼吸灯 题目就是这么简短,但这是目前我碰到的最有意思的一道题目,因为他有无数种解决方法,并且每一种都是那么高级或者巧妙,比如 可以利用3路不同初相的PWM调制信号驱动三颗RGB灯重叠呼吸 ...

  4. 浅浅的分析LED呼吸灯的实现和PWM的关系

    前言 在本周,我们在python课上做了一个实验,用ARDUINO使小LED灯模仿出呼吸灯的效果,实验进行的很成功,但是机器当仅输出高/低电平的时候是怎么样才能做到渐亮渐暗(输出电压)的变化呢?在这里 ...

  5. 【iCore4 双核心板_ARM】例程八:定时器PWM实验——呼吸灯

    实验原理: STM32的定时器有PWM功能,iCore4的蓝色LED连接在定时器的输出接口上, 可以通过定时器的PWM输出控制LED的亮度,从而实验呼吸灯的功能. 核心代码: int main(voi ...

  6. STM8S003F3通过PWM波实现三基色呼吸灯(转)

    源: STM8S003F3通过PWM波实现三基色呼吸灯

  7. STM8S PWM 应用 呼吸灯

    //主功能接受:使用MCU STM8S105C6 的PWM通道2 PC2 来做呼吸灯 已经验证OK,呵 //呵,这个PWM设置刚開始用还是有点麻烦,由于是自己摸索.花点时间.还是解决了 . //所用子 ...

  8. 12-ESP8266 SDK开发基础入门篇--PWM,呼吸灯

    https://www.cnblogs.com/yangfengwu/p/11094085.html PWM其实没有什么,就是看着官方给的API,,,然后就是用呗 对了,其实对于RTOS SDK版本的 ...

  9. Arduino系列之pwm控制LED灯(呼吸灯)

    下面我将写出最简单控制呼吸灯的方法 void setup()                                 // { pinMode(12,OUTPUT);             ...

随机推荐

  1. Elasticsearch节点下线(退役)and unassigned shards

    一.节点退役当集群中个别节点出现故障预警等情况,需要进行退役工作,即让所有位于该退役节点上的分片的数据分配到其他节点上后,再将此节点关闭并从集群中移除. 1.ES提供了让某个节点上所有数据都移走的功能 ...

  2. 用python做youtube自动化下载器 思路

    目录 0. 思路 1.准备 i.savfrom.net 2. 探索并规划获取方式 i.总览 ii. 获取该网页取到下载url的请求 iii. 在本地获取请求 iv.解析请求结果 v.解析解密后的结果 ...

  3. 【函数分享】每日PHP函数分享(2021-1-8)

    explode() 使用一个字符串分割另一个字符串. array explode( string $delimiter , string $string [, int $limit ]) 参数描述de ...

  4. 【对线面试官】Java 反射&&动态代理

    // 抽象类,定义泛型<T> public abstract class BaseDao<T> { public BaseDao(){ Class clazz = this.g ...

  5. 一网打尽,一文讲通虚拟机VirtualBox及Linux使用

    本文将从虚拟机的选择.安装.Linux系统安装.SSH客户端工具使用四个方面来详细介绍Linux系统在虚拟机下的安装及使用方法,为你在虚拟机下正常使用Linux保驾护航. 1.虚拟机的选择 在讲虚拟机 ...

  6. 爬虫-urllib模块的使用

    urllib是Python中请求url连接的官方标准库,在Python3中将Python2中的urllib和urllib2整合成了urllib.urllib中一共有四个模块,分别如下: request ...

  7. Flutter 布局类组件:线性布局(Row和Column)

    前言 所谓线性布局,即指沿水平或垂直方向排布子组件.Flutter中通过Row和Column来实现线性布局,并且它们都继承自弹性布局(Flex). 接口描述 Row({ Key key, // 表示子 ...

  8. Python 中的面向接口编程

    前言 "面向接口编程"写 Java 的朋友耳朵已经可以听出干茧了吧,当然这个思想在 Java 中非常重要,甚至几乎所有的编程语言都需要,毕竟程序具有良好的扩展性.维护性谁都不能拒绝 ...

  9. Linux 防火墙基于 CentOS7 的防火墙操作命令

    防火墙服务操作命令 重启防火墙 systemctl restart firewalld 查看防火墙状态 systemctl status firewalld 开启.关闭.重启防火墙 # 开启 serv ...

  10. show engine innodb status

    TRANSACTIONS------------Trx id counter 2003909(当前事务号)Purge done for trx's n:o < 2003905 (清理线程完成到了 ...