差别

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

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
脉冲发生器 [2016/06/14 10:45]
anran [代码设计]
脉冲发生器 [2021/09/13 10:56]
gongyu 移除
行 24: 行 24:
 脉冲发生一般通过对一个高频的脉冲信号进行分频来生成。 脉冲发生一般通过对一个高频的脉冲信号进行分频来生成。
  
-分频比:指方波的周期和高频信号手气之间发的比例关系,通过控制分频比来生成不同频率的方波。例如,开发系统上的时钟频率是25MHz,如果要生成5MHz的方波,则分频比为5。+分频比:指方波的周期和高频信号周期之间发的比例关系,通过控制分频比来生成不同频率的方波。例如,开发系统上的时钟频率是25MHz,如果要生成5MHz的方波,则分频比为5。
  
  
行 50: 行 50:
 {{ :​脉冲发生程序设计.jpg |脉冲发生程序设计}} {{ :​脉冲发生程序设计.jpg |脉冲发生程序设计}}
  
 +我们在硬件连接中也提到了脉冲发生器设计需要的硬件资源作为接口外设,整个设计的接口定义如下:
  
 +<code verilog>
 +input clk_in,​
 +input rst_n_in,​
 +input key_menu,​
 +input key_up,​
 +input key_down,​
 +output menu_state,​
 +output reg pulse_out
 +</​code>​
  
 +本设计中我们用到三个按键作为输入,需要对按键输入做消抖处理,消抖模块的原理及设计请参考[[按键消抖]]设计,这里我们增加了按键输入信号的位宽,同时对三路按键输入做消抖处理 ​ ,如下:
  
 +<code verilog>
 +//Debounce for key
 +wire [2:0] key_state,​key_pulse;​
 +Debounce1 Debounce_uut
 +(
 +.clk(clk_in),​
 +.rst_n(rst_n_in),​
 +.key_n({key_menu,​key_up,​key_down}),​
 +.key_state(key_state),​
 +.key_pulse(key_pulse)
 +); 
  
 +wire menu_state = key_state[0];​
 +wire up_pulse = key_pulse[1];​
 +wire down_pulse = key_pulse[2];​
 +</​code>​
  
- +对三路按键做消抖后的信号可以实现周期和脉宽的控制,本设计中我们分频比范围为2~16分级可调0%<​脉宽<​100%分级可调,控制脉宽参数duty要始终小于周期参数cycle, 
- +{{ ::​脉冲发生器原理.jpg |脉冲发生器原理}} 
- +实现方法如下:
-{{ :​序列检测状态转移图.jpg |序列检测状态转移图}} +
- +
-为了得到1Hz的信号,我们设计了25位的计数器cnt进行0.5s周期的循环计数,同时clk_1hz信号进行翻转,这样就得到了序列检测的时钟信号,然后再以序列检测的时钟信号为触发条件进行状态机的控制最终实现序列检测。 +
- +
-首先是计数器的设计,计数器计数范围为0~CNT_NUM-1设计文件代码中我们定义参数CNT_NUM为12500000,但是在仿真文件用设计文件时为了方便仿真,我们会将参数CNT_NUM重新赋值为5.+
  
 <code verilog> <code verilog>
-reg [24:0] cnt = 25'd0; +//Control cycle and duty cycle 
-always@(posedge ​clk or negedge ​rst_n) begin +always @(posedge ​clk_in ​or negedge ​rst_n_in) begin  
- if(!rst_n) begin + if(!rst_n_in) begin  
- cnt <= 25'd0+ cycle<=4'd8
- clk_1hz ​<= 1'b0; + duty<=4'd4;
- end else if(cnt>​=(CNT_NUM-1)) begin +
- cnt <= 25'​d0;​ +
- clk_1hz <= ~clk_1hz;+
  end else begin  end else begin
- cnt <= cnt 25'd1; + if(menu_state) begin 
- end+ if(up_pulse && (cycle<​4'​d15)) cycle <= cycle 4'd1; 
 + else if(down_pulse && (cycle>​(duty+4'​d1))) cycle <= cycle - 4'​d1;​ 
 + else cycle <= cycle; 
 + end else begin 
 + if(up_pulse && (cycle>​(duty+4'​d1))) duty <= duty + 4'​d1;​ 
 + else if(down_pulse && (duty>​4'​d0)) duty <= duty - 4'​d1;​ 
 + else duty <= duty; 
 + end 
 + end 
 end end
 </​code>​ </​code>​
  
-按照状态机状态转移图实现状态机的设计。+根据周期参数cycle控制计数器的计数范围,根据脉宽参数duty控制正电压脉冲的宽度,产生脉冲信号
  
 <code verilog> <code verilog>
-reg[1:0]state+reg [3:0] cnt; 
-always @(posedge ​clk_1hz ​or negedge ​rst_n) begin  +//counter for cycle 
- if(!rst_n) begin  +always @(posedge ​clk_in ​or negedge ​rst_n_in) begin  
- state<=s0; + if(!rst_n_in) begin  
- vout<​=0;  + cnt<=4'd0
- end else case(state) + end else begin 
- s0: begin + if(cnt>=cyclecnt<=4'd0
- if(vin==0) begin state<​=s0;​vout<​=0;​ end  + else ​cnt <= cnt + 4'd1
- else begin state<​=s1;​vout<​=0;​ end  + end  
- end  ​ +end 
- s1: begin +
- if(vin==0begin state<=s2;vout<=0; end  +
- else begin state<​=s1;​vout<​=0;​ end  +
- end  ​ +
- s2: begin +
- if(vin==0) begin state<​=s0;​vout<​=0;​ end  +
- else begin state<=s1;vout<=1; end  +
- end   +
- default:​state<​=s0;​ +
- endcase ​ +
-end +
-</​code>​+
  
-我们在设计中将序列检测的时钟信号设计为1Hz,并且使用LED指示序列检测的时钟信号的变化,方便在板子上按键及观察输出的情况。 +//pulse generate with duty 
- +always ​@(posedge clk_in or negedge rst_n_in) begin  
-===测试文件=== + if(!rst_n_inbegin  
- + pulse_out<​=1'​b1;​ 
-测试文件中我们需要对设计文件中的参数CNT_NUM进行重新赋值,同时对vin信号每400ns(序列检测时钟 = 系统时钟周期*分配系数*2 = 40*5*2 = 400ns)间隔取随机值。 + end else begin 
- + if(cnt<​=dutypulse_out<​=1'​b1;​ 
-<code verilog> + else pulse_out<​=1'​b0;​ 
-always ​vin = # 400 $random; + end  
- +end 
-wire clk_1hz,​vout;​ +
-Serial_Detect # +
-+
-.CNT_NUM(CNT_NUM+
-) +
-Serial_Detect_uut +
-( +
-.clk(sys_clk), +
-.rst_n(sys_rst_n),​ +
-.vin(vin), +
-.clk_1hz(clk_1hz),​ +
-.vout(vout) +
-);+
 </​code>​ </​code>​
  
 引脚分配如下: 引脚分配如下:
  
-^ 管脚名称 | clkrst_n vin  ​|clk_1hz  ​|vout +^ 管脚名称 | clk_inrst_n_inkey_menu|key_up|key_down|menu_state|pulse_out
-^ FPGA管脚 | C1 | A2 |B7  ​|A3  |A7  +^ FPGA管脚 | C1    | A2      | A12     ​|B8 ​   ​|A10     |A3        |A7       ​
-====仿真结果====+====运行结果====
  
-{{:序列检测仿真.jpg|序列检仿真}}+{{:img20160614134850.jpg?​500 |LED灯亮度}} 
 + 
 +{{:​img20160614135014.jpg?500|示波器量结果}}
 ====资源报告==== ====资源报告====
  
 ^ 资源 | 数量 ​ | 比例 ​ | 说明 ​ | ^ 资源 | 数量 ​ | 比例 ​ | 说明 ​ |
-^ LUTs | 39   | 3  ​|   |  +^ LUTs | 65   | 5   |   |  
-^ 寄存器 | 28    ​| ​2% |   |+^ 寄存器 | 42    ​| ​3% |   |
 ^ 存储器 | 0  | 0%   ​| ​   | ^ 存储器 | 0  | 0%   ​| ​   |
-^ IO管脚 ​  ​| ​|   ​| ​   |+^ IO管脚 ​  ​| ​|   ​| ​   |
 ^ 时钟频率 | 25MHz |   ​| ​   | ^ 时钟频率 | 25MHz |   ​| ​   |
  
 ====知识点==== ====知识点====
  
-  * 分频设计 +  * 按键消抖 
-  * 时序控制 +  * PWM脉宽调节 
-  * 简单状态机+  * 脉冲发生原理
  
  
 ====参考文档==== ====参考文档====
 +  * [[按键消抖]]
   * {{:​machxo2familydatasheet.pdf|Lattice MachXO2数据手册}}   * {{:​machxo2familydatasheet.pdf|Lattice MachXO2数据手册}}
 +
    
  
行 159: 行 164:
  
 ^ **文件名称** ​ | **功能** | ^ **文件名称** ​ | **功能** |
-^ **[[Serial_Detect.v]]** | **流水灯** | +^ **[[Pulse_gen.v]]** | **脉冲发生器TOP文件** | 
-^ **[[Serial_Detect_test.v]]** | **测试文件** |+^ **[[Debounce1.v]]** | **按键消抖** |