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

设计原理框图:

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

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

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

  1. always @(posedge clk)
  2. begin
  3. case (state)
  4. s0:
  5. begin
  6. key_out<=1'b1;
  7. if(key==1'b0)
  8. state<=s1;
  9. else
  10. state<=s0;
  11. end
  12. s1:
  13. begin
  14. if(key==1'b0)
  15. state<=s2;
  16. else
  17. state<=s0;
  18. end
  19. s2:
  20. begin
  21. if(key==1'b0)
  22. state<=s3;
  23. else
  24. state<=s0;
  25. end
  26. s3:
  27. begin
  28. if(key==1'b0)
  29. begin
  30. key_out<=1'b0;
  31. state<=s3;
  32. end
  33. else
  34. begin
  35. key_out<=1'b1;
  36. state<=s0;
  37. end
  38. end
  39. default:
  40. state<=s0;
  41. endcase
  42. 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;四个灯全亮。

  1. module led (
  2. clk,rst_n,key1,
  3. led
  4. );
  5. input clk; //时钟信号输入
  6. input rst_n; //复位信号输入
  7. input key1; //按键按下
  8. output[3:0] led; //LED灯点亮
  9. //------------------------键盘消抖程序---------------------------------------------------
  10. reg reg0_key;
  11. reg reg1_key;
  12. always @(posedge clk or negedge rst_n)
  13. begin
  14. if(!rst_n) begin
  15. reg0_key <= 1'b1; //将1‘b1赋值给reg0_key寄存器
  16. reg1_key <= 1'b1; //将1’b1赋值给reg1_key寄存器
  17. end
  18. else begin
  19. reg0_key <= key1; //将按键输入赋值给reg0_key
  20. reg1_key <= reg0_key; //根据非阻塞赋值的原理,reg1_key 存储的值是
  21. reg0_key 上一个时钟的值
  22. end
  23. end
  24. //当寄存器 key1 由 1 变为 0 时,led_an 的值变为高,维持一个时钟周期
  25. wire key_an;
  26. assign key_an = reg1_key & ( ~reg0_key); //用来检测下降沿的典型程序
  27. //---------------------------------------------------------------------------
  28. reg[19:0] cnt_key; //计数寄存器 //检测完下降沿,启动计时器,延时20ms
  29. always @ (posedge clk or negedge rst_n)
  30. begin
  31. if (!rst_n)
  32. cnt_key <= 20'd0; //异步复位
  33. else if(key_an)
  34. cnt_key <=20'd0;
  35. else
  36. cnt_key <= cnt_key + 1'b1;
  37. end
  38. reg reg_low;
  39. reg reg1_low;
  40. always @(posedge clk or negedge rst_n)
  41. begin
  42. if (!rst_n)
  43. begin
  44. reg_low <= 1'b1;
  45. end
  46. else if(cnt_key == 20'hfffff)
  47. begin
  48. reg_low <= key1; //cnt == 20'hfffff20ms
  49. end
  50. end
  51. always @(posedge clk or negedge rst_n) begin
  52. if (!rst_n)
  53. reg1_low <= 1'b1;
  54. else
  55. reg1_low <= reg_low;
  56. end
  57. //---------------------------------------------------------------------------
  58. //当寄存器 reg_low 由 1 变为 0 时,key_low 的值变为高,维持一个时钟周期
  59. wire key_low = reg1_low & ( ~reg_low);
  60. //===============LED 控制==================================
  61. reg[21:0] cnt; //
  62. always @(posedge clk or negedge rst_n)
  63. begin
  64. if(!rst_n)
  65. cnt <= 22'b0;
  66. else
  67. cnt <= cnt + 1'b1;
  68. end
  69. reg enable_r;
  70. always @(posedge clk or negedge rst_n)
  71. begin
  72. if(!rst_n)
  73. enable_r <= 1'b0;
  74. else
  75. if (cnt == 22'h3fffff) enable_r <= 1'b1;
  76. else
  77. enable_r <= 1'b0;
  78. end
  79. wire enable;
  80. assign enable = enable_r;
  81. reg[3:0] led_r;
  82. always @(posedge clk or negedge rst_n)
  83. begin
  84. if(!rst_n)
  85. led_r <= 4'b0111;
  86. else if(key_low)
  87. led_r <= 4'b0;
  88. else if(enable && !key_low)
  89. led_r <= {led_r[0],led_r[3:1]};
  90. else ;
  91. end
  92. wire[3:0] led;
  93. assign led = led_r;
  94. endmodule

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

  1. module pwm(clk,reset,key,led);
  2. input clk,reset,key;
  3. output led;
  4.  
  5. reg pwm_out;
  6.  
  7. reg key_out;
  8. parameter s0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11;
  9. reg [1:0] state;
  10.  
  11. reg [31:0] clk_counter;
  12. reg [9:0] pwm_counter;
  13. reg flag;
  14. /******************按键消抖**************************/
  15. always @(posedge clk)
  16. begin
  17. case (state)
  18. s0:
  19. begin
  20. key_out<=1'b1;
  21. if(key==1'b0)
  22. state<=s1;
  23. else
  24. state<=s0;
  25. end
  26. s1:
  27. begin
  28. if(key==1'b0)
  29. state<=s2;
  30. else
  31. state<=s0;
  32. end
  33. s2:
  34. begin
  35. if(key==1'b0)
  36. state<=s3;
  37. else
  38. state<=s0;
  39. end
  40. s3:
  41. begin
  42. if(key==1'b0)
  43. begin
  44. key_out<=1'b0;
  45. state<=s3;
  46. end
  47. else
  48. begin
  49. key_out<=1'b1;
  50. state<=s0;
  51. end
  52. end
  53. default:
  54. state<=s0;
  55. endcase
  56. end
  57. always @(posedge clk)
  58. begin
  59. clk_counter<=clk_counter+1'b1;
  60. if (clk_counter[13:4]<pwm_counter)
  61. pwm_out=1;
  62. else
  63. pwm_out=0;
  64.  
  65. if (clk_counter[15]==1'b1)
  66. begin
  67. if (flag==1'b1)
  68. begin
  69. flag<=1'b0;
  70. if (key_out==1'b0)
  71. pwm_counter<=(pwm_counter+10'b0000000011);
  72. else
  73. pwm_counter<=pwm_counter;
  74. end
  75. end
  76. else
  77. flag<=1'b1;
  78. end
  79. assign led=pwm_out;
  80. 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. 作业调度框架Quartz.NET-现学现用-01-快速入门

    原文:作业调度框架Quartz.NET-现学现用-01-快速入门 前言 你需要应用执行一个任务吗?这个任务每天或每周星期二晚上11:30,或许仅仅每个月的最后一天执行.一个自动执行而无须干预的任务在执 ...

  2. [jsp学习笔记] jsp基础知识 数据初始化、同步

  3. 一个 Vim 重度用户总结的 vim 超全指南

    我本人是 Vim 的重度使用者,就因为喜欢上这种双手不离键盘就可以操控一切的feel,Vim 可以让我对文本的操作更加精准.高效. 对于未使用过 Vim 的朋友来说,可能还无法体会到这种感觉.由于使用 ...

  4. iOS - 适配iOS 11

    http://www.10tiao.com/html/330/201707/2653579210/1.html 存档 导语:iOS 11 为整个生态系统的 UI 元素带来了一种更加大胆.动态的新风格. ...

  5. 删除注册在Eureka的服务(无效,多余)

    例子:http://140.143.67.146:8000/eureka/eureka/apps/ZKR-PRODUCT/172.21.0.10:zkr-product:6868 Request Me ...

  6. js 的七大原则--单一原则、开闭原则、替换原则(一)

    一.前言: js 的七大设计原则: 1.单一原则 2.开闭原则 3.里氏替换原则 4.依赖倒转原则 5.接口隔离原则 6.合成复用原则 7.迪米尔法则 二.单一原则 1.定义:单一原则就是一个对象或者 ...

  7. Typescript项目注意点和基本类型介绍

    从typescript源文件到执行的过程 执行者 步骤 说明 TSC 1. TypeScript Source -> TypeScript AST TSC将ts文件转为TS AST(abstra ...

  8. MySQL Partition Table--分区表优缺点

    分区表历史 1.MySQL 5.1版本开始支持基于整数列的分区表, 2.MySQL 5.5版本开始支持RANGE和LIST分区,支持TRUNCATE分区,新增COLUMNS关键词简化分区定义. 3.M ...

  9. TLS 1.3 中Pre_shared_key和key_share对应的两种密钥交换模式

    1.TLS1.3的整个协议的文档规范 请参照 RFC 8846,协议规范中指出,TLS1.3提供三方面的安全属性,分别是身份认证.通信加密.完整性验证. 2.TLS1.3协议主要包括两个组成部分,分别 ...

  10. egg.js 完整实例2后台管理系统

    项目地址 github.com/richard1015… 技术栈 Vue.js.iview.websocket.Amap 演示地址: 后台管理 schoolmgr.zhuzhida.vip 前台展示 ...