PWM的全称为Pulse-Width Modulation(脉冲宽度调制),即调节脉冲的占空比。当输出的脉冲频率一定时,输出的脉冲占空比越大,相当于输出的有效电平越大,这样也就简单实现了由FPGA来控制模拟量。

设计原理框图:

按键消抖,首先采用状态机实现,用状态机做键盘消抖,很好用,不必等待延时,当检测到有按键按下或弹起时能发出相应的键盘消息。设置状态机有 4中状态,A0,A1,A2,A3状态转换图如下:

检测这几个管脚是否为低电平,来判断按键是否被按下

AO: 初始时位于A0状态,当扫描发现有按键按下时,转入到A1状态。当处于A1状态时,当扫描有按键按下并且键值等于A1状态下的键值时,转入到A2状态,否则转入A0状态。当处于A2状态时,当扫描发现有按键按下并且键值等于A3状态下的键值时,转入到A3状态,否则转入A0状态,当处于A3状态时,当扫描发现无键按下时,转入A0状态,同时发出键弹起消息或弹起键的键值入队。

always @(posedge clk)
begin
case (state)
s0:
begin
key_out<=1'b1;
if(key==1'b0)
state<=s1;
else
state<=s0;
end
s1:
begin
if(key==1'b0)
state<=s2;
else
state<=s0;
end
s2:
begin
if(key==1'b0)
state<=s3;
else
state<=s0;
end
s3:
begin
if(key==1'b0)
begin
key_out<=1'b0;
state<=s3;
end
else
begin
key_out<=1'b1;
state<=s0;
end
end
default:
state<=s0;
endcase
end

计数器按键消抖:1.检测管教电平是否拉低;2.若检测到低电平,启动计数器,延时20ms左右的时间;3.再次检测管脚是否低电平;4.若还是低电平,确定按键被按下,输出控制信号。在此例程中,最终LED控制实现的功能:按键 Key2 连接到 rst_n 信号,key1 连接到 key1 信号。最终的结果是:当按下 key2 键的时候,系统复位,只有一个 LED 点亮。松开 key2,没有键按下的时候, 四个 LED 交替两灭, 流水灯操作。 当按下 key1 键时, 执行下面语句 else if(key_low) led_r <= 4'b0;四个灯全亮。

module led (
clk,rst_n,key1,
led
);
input clk; //时钟信号输入
input rst_n; //复位信号输入
input key1; //按键按下
output[3:0] led; //LED灯点亮
//------------------------键盘消抖程序---------------------------------------------------
reg reg0_key;
reg reg1_key;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
reg0_key <= 1'b1; //将1‘b1赋值给reg0_key寄存器
reg1_key <= 1'b1; //将1’b1赋值给reg1_key寄存器
end
else begin
reg0_key <= key1; //将按键输入赋值给reg0_key
reg1_key <= reg0_key; //根据非阻塞赋值的原理,reg1_key 存储的值是
reg0_key 上一个时钟的值
end
end
//当寄存器 key1 由 1 变为 0 时,led_an 的值变为高,维持一个时钟周期
wire key_an;
assign key_an = reg1_key & ( ~reg0_key); //用来检测下降沿的典型程序
//---------------------------------------------------------------------------
reg[19:0] cnt_key; //计数寄存器 //检测完下降沿,启动计时器,延时20ms
always @ (posedge clk or negedge rst_n)
begin
if (!rst_n)
cnt_key <= 20'd0; //异步复位
else if(key_an)
cnt_key <=20'd0;
else
cnt_key <= cnt_key + 1'b1;
end
reg reg_low;
reg reg1_low;
always @(posedge clk or negedge rst_n)
begin
if (!rst_n)
begin
reg_low <= 1'b1;
end
else if(cnt_key == 20'hfffff)
begin
reg_low <= key1; //cnt == 20'hfffff,20ms
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
reg1_low <= 1'b1;
else
reg1_low <= reg_low;
end
//---------------------------------------------------------------------------
//当寄存器 reg_low 由 1 变为 0 时,key_low 的值变为高,维持一个时钟周期
wire key_low = reg1_low & ( ~reg_low);
//===============LED 控制==================================
reg[21:0] cnt; //
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt <= 22'b0;
else
cnt <= cnt + 1'b1;
end
reg enable_r;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
enable_r <= 1'b0;
else
if (cnt == 22'h3fffff) enable_r <= 1'b1;
else
enable_r <= 1'b0;
end
wire enable;
assign enable = enable_r;
reg[3:0] led_r;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
led_r <= 4'b0111;
else if(key_low)
led_r <= 4'b0;
else if(enable && !key_low)
led_r <= {led_r[0],led_r[3:1]};
else ;
end
wire[3:0] led;
assign led = led_r;
endmodule

回到PWM控制灯光亮暗,通过时钟计时器的计数与脉宽的计数比较大小,去定义灯光的亮暗。当时钟计数器到达设定的数值时,如果脉宽加满则溢出清0,并在此时判断按键有无按下,若按下,则调节脉宽的宽度,来进行下一轮的占空比比较,若脉宽未满,亦将其加满。对应的程序为:

module pwm(clk,reset,key,led);
input clk,reset,key;
output led; reg pwm_out; reg key_out;
parameter s0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11;
reg [1:0] state; reg [31:0] clk_counter;
reg [9:0] pwm_counter;
reg flag;
/******************按键消抖**************************/
always @(posedge clk)
begin
case (state)
s0:
begin
key_out<=1'b1;
if(key==1'b0)
state<=s1;
else
state<=s0;
end
s1:
begin
if(key==1'b0)
state<=s2;
else
state<=s0;
end
s2:
begin
if(key==1'b0)
state<=s3;
else
state<=s0;
end
s3:
begin
if(key==1'b0)
begin
key_out<=1'b0;
state<=s3;
end
else
begin
key_out<=1'b1;
state<=s0;
end
end
default:
state<=s0;
endcase
end
always @(posedge clk)
begin
clk_counter<=clk_counter+1'b1;
if (clk_counter[13:4]<pwm_counter)
pwm_out=1;
else
pwm_out=0; if (clk_counter[15]==1'b1)
begin
if (flag==1'b1)
begin
flag<=1'b0;
if (key_out==1'b0)
pwm_counter<=(pwm_counter+10'b0000000011);
else
pwm_counter<=pwm_counter;
end
end
else
flag<=1'b1;
end
assign led=pwm_out;
endmodule

最后板子亮灯,显示平均电压。

PWM控制灯亮暗的verilog实现的更多相关文章

  1. 单片机与android手机通信(控制LED小灯亮灭)

    1.单片机实验板功能设计 为验证数据通信内容,让单片机板上的四个按键与android手机客户端上的四个LED灯相互控制:为达到上述基本实验要求,采用单字符传输数据即可,硬件需设计两块相同的单片机电路板 ...

  2. K1 K2作为中断源控制红色LED灯,实现任意键按一下LED灯亮或者灭

    #include "stm32f10x.h" // 相当于51单片机中的 #include <reg51.h> #include "stm32f10x_gpi ...

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

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

  4. 单片机pwm控制基本原理详解

    前言 PWM是Pulse Width Modulation的缩写,它的中文名字是脉冲宽度调制,一种说法是它利用微处理器的数字输出来对模拟电路进行控制的一种有效的技术,其实就是使用数字信号达到一个模拟信 ...

  5. 树莓派 温度监控 PWM 控制风扇 shell python c 语言

    Mine: 图中圈出来的是三极管 和滤波电容 依赖库: wiringPi sudo apt-get install wiringpi Shell脚本 本文介绍使用Shell脚本在树莓派上启用软件PWM ...

  6. 【单片机入门】(四)应用层软件开发的单片机学习之路-----ESP32开发板PWM控制电机以及中断的使用

    引言 各位大佬,晚上好啊,在上一篇博客中,我们讲了什么是UART串口通讯,以及使用USB转TTL使得单片机可以和c#上位机做一个串口通讯,接下来,为大家带来PWM的概念原理,以及实际案例,使用PWM对 ...

  7. <<你的灯亮着吗?>>读书笔记

    本书是美国计算机传奇人物杰拉尔德.温伯格和唐纳德.高斯所著,我在网上买到的2003年版的本书,发现本书用20则幽默的现代寓言故事,60幅精美插图,以及一系列的适当提问和建议,让我们的思考方式慢慢得以扩 ...

  8. RocEDU.阅读.写作《你的灯亮着吗?》

    <你的灯亮着吗?> 一.对本书的认识 这本书的作者就如何训练思维能力指点迷津.书中提及的观点包括"问题是理想状态和现实状态之间的差别",以及"无论表面上表现的 ...

  9. PWM控制led渐变

    PWM,中文释义:脉冲宽度调制.它是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术. PWM 是一种对模拟信号电平进行数字编码的方法.通过高分辨率计数器的使用,方波的占空比被调制用来对 ...

随机推荐

  1. open_vPGPv

    加密 // create an instance of the library PGPLib pgp = new PGPLib(); // Import the main company public ...

  2. node.js开发 npm包管理工具 npm 和 cnpm区别

    npm 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用. 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用 np ...

  3. 6:Partial Update 内部原理 和 乐观锁并发控制

    Partial Update 内部执行过程: 首先,ES文档是不可变的,它们只能被修改,不能被替换.Update Api 也不例外. Update API 简单使用与之前描述相同的 检索-修改-重建索 ...

  4. String字符串常用方法

    1.  charAt(int index)-->返回 char指定索引处的值(注意索引从0开始) String str1="abc"; char c=str1.charAt( ...

  5. Jmeter获取数据库数据

    1)添加需要的数据库驱动jar包,使用不同的数据库,需要引入的jar包是不一样的: mysql:无需引入其他数据库驱动jar包 sql server:下载sqljdbc.jar包 oracle:ora ...

  6. UnicodeDecodeError: 'utf-8' codec can't decode byte..问题

    解决UnicodeDecodeError: 'utf-8' codec can't decode byte..问题 问题描述: 问题分析: 该情况是由于出现了无法进行转换的 二进制数据 造成的,可以写 ...

  7. Fortify漏洞之Portability Flaw: Locale Dependent Comparison

    继续对Fortify的漏洞进行总结,本篇主要针对 Portability Flaw: Locale Dependent Comparison 漏洞进行总结,如下: 1.Portability Flaw ...

  8. 数据库操作语句类型(DQL、DML、DDL、DCL)

    数据库操作语句类型(DQL.DML.DDL.DCL)简介 SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL. 1. 数据查询语言DQL 数据查询语 ...

  9. 【转】基于TMS320C6455的千兆以太网设计

    基于TI公司最新DSP芯片TMS320C6455.设计并实现了以太网通信软硬件接口.采用TMS320C6455片内以太网接口模块EMAC/MDIO,结合片外AR8031 PHY芯片,在嵌入式操作系统D ...

  10. Flink原理(五)——容错机制

    本文是博主阅读Flink官方文档以及<Flink基础教程>后结合自己理解所写,若有表达有误的地方欢迎大伙留言指出. 1.  前言 流式计算分为有状态和无状态两种情况,所谓状态就是计算过程中 ...