差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
呼吸灯 [2016/06/15 10:53]
anran [代码设计]
呼吸灯 [2019/12/23 10:44] (当前版本)
anran
行 24: 行 24:
  
 结合呼吸灯的原理,整个呼吸的周期为最亮→最暗→最亮的时间,即t的值的变化:0→T→0逐渐变化,这个时间应该为2s 结合呼吸灯的原理,整个呼吸的周期为最亮→最暗→最亮的时间,即t的值的变化:0→T→0逐渐变化,这个时间应该为2s
-====硬件连接====+====硬件说明====
 ------ ------
 呼吸灯的设计较为简单,我们使用25MHz的系统时钟作为高频信号做分频处理,调整占空比实现PWM,通过LED灯LD1指示输出状态。 呼吸灯的设计较为简单,我们使用25MHz的系统时钟作为高频信号做分频处理,调整占空比实现PWM,通过LED灯LD1指示输出状态。
行 30: 行 30:
 {{ :​led电路连接.jpg |LED电路连接}} {{ :​led电路连接.jpg |LED电路连接}}
  
-====代码设计==== +====Verilog代码==== 
----- +------
-===设计文件===+
  
 {{ :​呼吸灯程序设计.jpg |呼吸灯程序设计}} {{ :​呼吸灯程序设计.jpg |呼吸灯程序设计}}
  
 +呼吸灯设计要求呼吸的周期为2s,也就是说LED灯从最亮的状态开始,第一秒时间内逐渐变暗,第二秒的时间内再逐渐变亮,依次进行。
  
 +本设计中需要两个计数器cnt1和cnt2,cnt1随系统时钟同步计数(系统时钟上升沿时cnt1自加1)范围为0~T,cnt2随cnt1的周期同步计数(cnt1等于T时,cnt2自加1)范围也是0~T,这样每次cnt1在0~T的计数时,cnt2为一个固定值,相邻cnt1计数周期对应的cnt2的值逐渐增大,我们将cnt1计数0~T的时间作为脉冲周期,cnt2的值作为脉冲宽度,则占空比 = cnt2/​T,​占空比从0%到100%的时间 = cnt2*cnt1 = T^2 = 1s = 25M个系统时钟,T = 5000,我们定义CNT_NUM = 5000作为两个计数器的计数最大值。
  
-我们在硬件连接中也提到了脉冲发生器设计需要的硬件资源作为接口外设,整个设计的接口定义如下:+{{ ::​呼吸灯pwm原理.jpg |PWM呼吸灯原理}}
  
 <code verilog> <code verilog>
-input clk_in,​ +parameter CNT_NUM = 5000 //​period = (5000^2)*2 = 50000000 = 2s
-input rst_n_in,​ +
-input key_menu,​ +
-input key_up,​ +
-input key_down,​ +
-output menu_state,​ +
-output reg pulse_out+
 </​code>​ </​code>​
  
-本设中我们用到三个按键作为输入,需要对按键输入做消抖处理,消抖模块的原理及设请参考[[按键消抖]]设计,这里我们以key_menu的消抖为例调用按键消抖模块,如下+数器cnt1随系统时钟从0~(CNT_NUM-1)循环,如下
  
 <code verilog> <code verilog>
-//Debounce for key_menu +//generate cnt1 signal 
-Debounce Debounce_menu(.clk(clk_in),.rst_n(rst_n_in),.key_n(key_menu),​.key_state(menu_state)); +always@(posedge ​clk_in ​or negedge rst_n_inbegin  
 + if(!rst_n_in) ​begin 
 + cnt1<​=13'​d0;​ 
 + end else begin 
 + if(cnt1>​=CNT_NUM-1cnt1<​=1'​b0; 
 + else cnt1<​=cnt1+1'​b1;​ 
 + end 
 +end
 </​code>​ </​code>​
  
-对三路按键做消抖后信号可以实现周期和脉宽的控制,本设中我们的分频比范围为2~16分级可调,0%<​脉宽<​100%分级可调,控制脉宽参数duty要始终小于周期参cycle实现方法如下+计数器cnt2随cnt1的周期从0~(CNT_NUM-1)循环计数,如下
  
 <code verilog> <code verilog>
-//Control cycle and duty cycle +//generate cnt2 signal 
-always @(posedge clk_in or negedge rst_n_in) begin  +always@(posedge clk_in or negedge rst_n_in) begin  
- if(!rst_n_in) begin  + if(!rst_n_in) begin 
- cycle<=4'd8+ cnt2<=13'd0
- duty<=4'd4;+ flag<=1'b0;
  end else begin  end else begin
- if(menu_state) begin + if(cnt1==CNT_NUM-1) begin 
- if(up_pulse && (cycle<​4'​d15)) cycle <= cycle + 4'd1; + if(!flagbegin 
- else ​if(down_pulse && (cycle>(duty+4'​d1))) cycle <= cycle - 4'd1+ if(cnt2>=CNT_NUM-1flag<=1'b1
- else cycle <= cycle+ else cnt2<=cnt2+1'​b1
- end else begin + end else begin 
- if(up_pulse && (cycle>​(duty+4'​d1))) duty <= duty + 4'd1+ if(cnt2<=0flag<=1'b0
- else if(down_pulse && (duty>​4'​d0)) duty <= duty 4'd1+ else cnt2<=cnt2-1'b1
- else ​duty <= duty; + end 
- end + end else cnt2<=cnt2
- end + end
 end end
 </​code>​ </​code>​
  
-最后根据周期参数cycle控制计数器的计数范围根据脉宽参数duty控制正电压脉冲的宽度,产生脉冲信号+最后将两个计数器cnt1和cnt2比较输出呼吸灯控制信号
  
 <code verilog> <code verilog>
-reg [3:​0] cnt;​ +//Compare cnt1 and cnt2, generate PWM-Breath-led 
-//counter for cycle +assign Breath_led ​= (cnt1<cnt2)?1'b0:1'b1;
-always @(posedge clk_in or negedge rst_n_in) begin  +
- if(!rst_n_in) begin  +
- cnt<=4'​d0;​ +
- end else begin +
- if(cnt>​=cycle) cnt<=4'​d0;​ +
- else cnt <= cnt + 4'​d1;​ +
- end  +
-end  +
- +
-//pulse generate with duty +
-always @(posedge clk_in or negedge rst_n_inbegin  +
- if(!rst_n_in) begin  +
- pulse_out<​=1'b1; +
- end else begin +
- if(cnt<​=duty) pulse_out<​=1'b1; +
- else pulse_out<​=1'​b0;​ +
- end  +
-end +
 </​code>​ </​code>​
  
 引脚分配如下: 引脚分配如下:
  
-^ 管脚名称 | clk_in| rst_n_in| ​key_menu|key_up|key_down|menu_state|pulse_out+^ 管脚名称 | clk_in| rst_n_in| ​Breath_led
-^ FPGA管脚 | C1    | A2      | A12     ​|B8 ​   |A10     |A3        |A7       +^ FPGA管脚 | C1    | L14     | N13        | 
-====运行结果==== +====仿真结果====
- +
-{{:​img20160614134850.jpg?​500 |LED灯亮度}}+
  
-{{:img20160614135014.jpg?500|示波器测量结果}}+{{:呼吸灯仿真.jpg|呼吸灯仿真}}
 ====资源报告==== ====资源报告====
  
 ^ 资源 | 数量 ​ | 比例 ​ | 说明 ​ | ^ 资源 | 数量 ​ | 比例 ​ | 说明 ​ |
-^ LUTs | 61   | 10%   ​| ​  |  +^ LUTs | 40   | 6%   ​| ​  |  
-^ 寄存器 | 80    ​| ​5% |   |+^ 寄存器 | 27    ​| ​2% |   |
 ^ 存储器 | 0  | 0%   ​| ​   | ^ 存储器 | 0  | 0%   ​| ​   |
-^ IO管脚 ​  ​| ​|   ​| ​   |+^ IO管脚 ​  ​| ​|   ​| ​   |
 ^ 时钟频率 | 25MHz |   ​| ​   | ^ 时钟频率 | 25MHz |   ​| ​   |
  
 ====知识点==== ====知识点====
  
-  * 按键消抖+  * 呼吸灯原理
   * PWM脉宽调节   * PWM脉宽调节
   * 脉冲发生原理   * 脉冲发生原理
行 130: 行 112:
  
 ====参考文档==== ====参考文档====
-  * [[按键消抖]]+  * [[脉冲发生器]]
   * {{:​machxo2familydatasheet.pdf|Lattice MachXO2数据手册}}   * {{:​machxo2familydatasheet.pdf|Lattice MachXO2数据手册}}
  
行 138: 行 120:
  
 ^ **文件名称** ​ | **功能** | ^ **文件名称** ​ | **功能** |
-^ **[[Pulse_gen.v]]** | **脉冲发生器TOP文件** | +^ **[[Breath_led.v]]** | **呼吸灯** | 
-^ **[[Debounce.v]]** | **按键消抖** |+^ **[[Breath_led_test.v]]** | **测试文件** |