集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 8243|回复: 14

雾盈FPGA笔记之(一):基于FPGA的呼吸灯简单实验(Verilog)

[复制链接]
雾盈 发表于 2016-7-31 15:22:07 | 显示全部楼层 |阅读模式
本帖最后由 雾盈 于 2016-8-2 18:23 编辑

基于FPGA的呼吸灯简单实验程序(Verilog)

                                                                                                2016-07-27          雾盈

1、呼吸灯
呼吸灯最早是由苹果公司发明并应用于笔记本睡眠提示上。
呼吸灯其实是微电脑控制下,由暗渐亮,然后再由亮渐暗,模仿人呼吸方式的LED灯

2.呼吸灯原理
LED的亮度与流过的电流成正比。在一定的频率之下,如果占空比是0,则LED不亮;如果占空比是100%,则LED最亮;
如果占空比刚好是50%,则LED亮度适中。如果我们让占空比从0~100%变化,再从100%~0不断变化,就可以实现LED一呼一吸的效果。
其波形占空比示意图如图2.1所示:

3.呼吸灯程序设计思路
(1)首先确定PWM的频率为1Khz
(2)由频率算出周期 T = 1/f = 1ms
(3)根据每次呼1s,吸1s,算出计数值 1s/1ms=1000
(4)然后将1ms分成1000份,每一份是1us
(5)写三个 1us、1ms、1s的3个计数器count1、 count2、 Count3,最后count2和count3进行比较

4.程序框图
如图4.1所示


5.状态机设计
可以将呼吸灯运行过程归为两个状态:S0:由灭渐亮;S1:由亮渐灭。
这里就会有两个问题需要我们解决,
1.        状态的翻转
2.        在一个状态里如何使pwm波的占空比实现逐增或逐减。

先说第一个问题,两个状态的翻转
        由下面的时序图(图)可以看出来,两个状态的翻转只是由时间决定的,S0状态和S1状态分别持续1s,
可以将它看成周期为2s的时钟信号,每当flag_1s信号到来一次,状态就翻转一次。


  1.                                         if(flag_1s)
  2.                                                 state <= ~state;
  3.                                         else       
  4.                                                 state <= state;
复制代码


然后再来说第二个问题,在一个状态下如何实现PWM波占空比逐增逐减的过程。
以S0状态下,LED由灭渐亮,PWM波占空比由百分之百逐渐减小至零为例:
我们发现让count2与count3比较,其结果clk_out会出现这种占空比逐渐减小的结果。
此段代码如下:

  1.                         0:begin // led    from low to high                                  
  2.                                         if(count2 < count3)
  3.                                                         begin
  4.                                                            clk_out <= 1'b0;
  5.                                                         end
  6.                                         else begin
  7.                                                            clk_out <= 1'b1;
  8.                                                          end
复制代码

于是,由反逻辑可以轻易知道在S1状态下,如何使其输出的clk_out占空比由小到大的方法,这样就可以实现LED 的由亮渐灭。

        : 整个呼吸灯程序设计主要内容大致如此,末尾附上源代码及其仿真波形,以下为程序设计中我所遇到的问题,
给可能出现同样问题的童鞋提供一些参考。

我想问问,怎么在文章中间添加图片,不然好多问题无法讲清楚。

附源代码:
  1. module  breathe_led(
  2.                           input                clk,
  3.                           input                rst_n,
  4.                           
  5.                           output  reg [3:0]         led
  6. );
  7.         parameter COUNT_MAX = 10'd999;        // 过
  8.         parameter COUNT_LIT = 6'd45;
  9. //        parameter COUNT_LIT = 6'd9;
  10. //        parameter COUNT_MAX = 10'd9;
  11. //         
  12.         reg [5:0] count1;
  13.         reg [9:0] count2;
  14.         reg [9:0] count3;
  15.        
  16.         wire flag_1ms;
  17.         wire flag_1s;
  18.         wire flag_1us;
  19.        
  20.         reg state;
  21.         reg clk_out;
  22.         //count1
  23.         always @ (posedge clk or negedge rst_n)
  24. begin
  25.      if(!rst_n)
  26.         begin
  27.                         count1 <= 1'b0;                               
  28.         end
  29.      else  begin
  30.            if(count1 < COUNT_LIT)
  31.                         begin
  32.                           count1 <= count1 + 1'b1;       
  33.                         end       
  34.                         else begin
  35.                                   count1 <= 6'd0;                               
  36.                                  end                       
  37.              end
  38. end
  39.         assign flag_1us = (count1 == COUNT_LIT)? 1'b1 : 1'b0;
  40.        
  41.         //count2
  42.         always @ (posedge clk or negedge rst_n)
  43. begin
  44.      if(!rst_n)
  45.         begin
  46.                    count2 <= 10'd0;                           
  47.         end
  48.      else  begin   
  49.                         /* if(flag_1us)
  50.                                 begin                                  
  51.                                 if(count2 == COUNT_MAX)
  52.                                         begin
  53.                                          count2 <= 10'd0;                               
  54.                                         end
  55.                                 else begin                                         
  56.                                         count2 <= count2 + 1'b1;
  57.                                          end
  58.                                 end       
  59.                         else begin
  60.                                          count2 <= 10'd0;
  61.                                  end                 */       
  62.                                  
  63.                         if(flag_1us & count2 < COUNT_MAX)
  64.                           begin
  65.                                   count2 <= count2 + 1'b1;
  66.                           end
  67.                         else if(count2 == COUNT_MAX & count1 == COUNT_LIT)
  68.                                 begin
  69.                                 count2 <= 1'b0;
  70.                                  end
  71.            end
  72. end
  73.        
  74.         assign flag_1ms = (count2 == COUNT_MAX)? (1'b1 & flag_1us):1'b0;
  75.        
  76.        
  77.        
  78.         // count3
  79.         always @ (posedge clk or negedge rst_n)
  80. begin
  81.      if(!rst_n)
  82.         begin
  83.                         count3 <= 10'd0;                       
  84.         end
  85.      else  begin
  86.                          /* if(flag_1ms)
  87.                                 begin
  88.                      if(count3 == COUNT_MAX)
  89.                                          begin
  90.                                          count3 <= 10'd0;                               
  91.                                         end
  92.                                 else begin                                          
  93.                                          count3 <= count3 + 1'b1;
  94.                                           end
  95.                                 end       
  96.                         else begin
  97.                                      count3 <= 10'd0;
  98.                                  end */
  99.                          if(flag_1ms & count3 < COUNT_MAX)
  100.                                  begin
  101.                                   count3 <= count3 + 1'b1;
  102.                                 end
  103.                         else if(count3 == COUNT_MAX & count2 == COUNT_MAX & count1 == COUNT_LIT)
  104.                                         begin
  105.                                            count3 <= 1'b0;
  106.                                          end
  107.              end
  108. end                         
  109.        
  110.         assign flag_1s = (count3 == COUNT_MAX)?(1'b1 & flag_1ms):1'b0;       
  111.        
  112.        

  113.         always @ (posedge clk or negedge rst_n)
  114. begin
  115.      if(!rst_n)
  116.         begin
  117.                         clk_out <= 1'b0;
  118.                         state <= 1'b0;
  119.         end
  120.      else  begin
  121.              case(state)
  122.                                 0:begin // led    from low to high                                  
  123.                                         if(count2 < count3)
  124.                                                         begin
  125.                                                            clk_out <= 1'b0;
  126.                                                         end
  127.                                         else begin
  128.                                                            clk_out <= 1'b1;
  129.                                                          end                                               
  130.                                  
  131.                                         if(flag_1s)
  132.                                                 state <= ~state;
  133.                                         else       
  134.                                                 state <= state;                                       
  135.                                   end
  136.                                 1:begin // led         from high to low
  137.                                                  if(count2 < count3)
  138.                                                                         begin
  139.                                                                         clk_out <= 1'b1;
  140.                                                                         end
  141.                                                   else         begin
  142.                                                                      clk_out <= 1'b0;
  143.                                                                         end                                                                           
  144.                                
  145.                                   end
  146.                                                         default: state <= 1'b0;
  147.                         endcase
  148.                          
  149.           end
  150. end       
  151.                
  152.                 
  153.         always @ (posedge clk or negedge rst_n)
  154. begin
  155.      if(!rst_n)
  156.         begin
  157.                   led <= 4'b1111;
  158.         end
  159.      else  begin
  160.           led <= {4{clk_out}};  
  161.              end
  162. end
  163. //        assign  led = (!rst_n)?1'b0:{4{clk_out}};
  164.        

  165.                
  166.                
  167.                






  168.                
  169.                          
  170. endmodule
复制代码





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
fpga_wuhan 发表于 2016-8-1 09:52:43 | 显示全部楼层
赞一个,顶一个!
回复 支持 1 反对 0

使用道具 举报

 楼主| 雾盈 发表于 2016-7-31 15:26:20 | 显示全部楼层
我就想知道怎么在文章中间添加图片,谁能告诉我?
zhiweiqiang33 发表于 2016-8-2 10:14:36 | 显示全部楼层
谢谢分享,正在学习中;坚持关注;
 楼主| 雾盈 发表于 2016-8-2 10:46:04 | 显示全部楼层
zhiweiqiang33 发表于 2016-8-2 10:14
谢谢分享,正在学习中;坚持关注;

支老师还亲自顶贴啊
zhiweiqiang33 发表于 2016-8-2 19:21:38 | 显示全部楼层
必须力挺你,
Adamancy 发表于 2016-8-10 15:59:13 | 显示全部楼层
                 为什么中间少了几个
zhiweiqiang33 发表于 2016-8-10 17:47:30 | 显示全部楼层
学习了 资料写的很基础很全面 基础入门资料 谢谢
芙蓉王 发表于 2016-8-12 16:32:19 | 显示全部楼层
                   感谢分享
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-11-23 11:28 , Processed in 0.068136 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表