首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

“同频异宽”脉冲的选择

“同频异宽”脉冲的选择

1. 讲废话

     
标题解释:“同频异宽”脉冲即两个频率相同但各自占空比随时变化的脉冲,此贴目的就是从这两个脉冲中实时选择出占空比较大的那个脉冲,然后将其输出。

      项目背景:记得以前是在一个服务器项目中,机柜上安装了很多风扇,它们的转速都依靠PWM进行控制,PWM脉冲是由控制器发出来的,当然了,如果只有一个控制器去作PWM控制,也就没有写这篇帖子的必要了,关键是项目中有两个控制器都同时发出了这样的PWM脉冲(同频异宽),要求用CPLD/FPGA对这两个脉冲进行实时比较,然后随时将占空比较大的那个脉冲输出给风扇。至于为什么用两个控制器,请原谅我有点健忘,记不太清了。

ps. 这两个同频脉冲的占空比在某一时刻可能存在相同的情况,但这完全不影响我们的输出。


2. 晒干货


例化时,仅需要按您的需求修改代码中带★号的参数   ps. 这里只有一处需要修改
  • /***************************************** Declaration ****************************************
  • File Name: duty_cycle.v
  • Author:  Bob Liu
  • E-mail:  <a target="_blank" href="mailto:shuangfeiyanworld@163.com">shuangfeiyanworld@163.com</a>
  • Function:  在两个频率相同占空比不同的脉冲中,实时选择出当前占空比较大的那个脉冲并输出
  • Version: V1.0
  • Update:  2012-10-17
  • ********************************************************************************************/
  • module duty_cycle
  • (
  • input clk,   //系统时钟
  • input pulse0,pulse1, //输入脉冲,频率相同。按理论和实测情况,这两个被测脉冲的频率最好低于系统时钟的1/10,以便于计数和比较两者占空比
  • output pulse_max  //输出pulse0和pulse1中占空比大的那一个脉冲
  • );
  • //--------------------------------------------------------------------------
  • // 计算一个周期内pulse0和pulse1高电平持续的长度
  • //--------------------------------------------------------------------------
  • reg   state;
  • reg [31:0] cnt;      //此计数器作用是为了得到被测脉冲的周期长度
  • reg [31:0] cnt_pulse0,cnt_pulse1;  //这两个计数器,在pulse0和pulse1的单个周期内的高电平期间,不断加1,以得到一个周期内各自高电平持续的长度
  • reg [31:0] cnt_pulse0_r,cnt_pulse1_r; //当pulse0和pulse1两个脉冲在一个周期内高电平结束后,寄存cnt_pulse0和cnt_pulse1的结果
  • always @ (posedge clk)
  • begin
  • case(state)
  • 0: begin //初始化
  •    cnt_pulse0<=0;
  •    cnt_pulse1<=0;
  •    state<=1;
  •   end
  • 1: begin
  •    if(cnt==500-1)  //★得到被测脉冲的周期长度 (计算方法是,系统时钟频率值除以被测脉冲频率值,然后取整减一;这里以50MHZ系统时钟和100KHZ被测脉冲为例取值)
  •     begin
  •      cnt_pulse0_r<=cnt_pulse0;
  •      cnt_pulse1_r<=cnt_pulse1;
  •      cnt<=0;
  •      state<=0;
  •     end
  •    else
  •     begin
  •      cnt<=cnt+1; //在被测脉冲一个周期时间内,不断加1
  •      if(pulse0==1) //在被测脉冲pulse0的一个周期时间内,当脉冲处于高电平,计数器cnt_pulse0不断计数
  •       cnt_pulse0<=cnt_pulse0+1;
  •      else
  •       cnt_pulse0<=cnt_pulse0;
  •      if(pulse1==1) //在被测脉冲pulse1的一个周期时间内,当脉冲处于高电平,计数器cnt_pulse1不断计数
  •       cnt_pulse1<=cnt_pulse1+1;
  •      else
  •       cnt_pulse1<=cnt_pulse1;
  •     end
  •   end
  • default: begin
  •      cnt_pulse0<=0;
  •      cnt_pulse1<=0;
  •      cnt<=0;
  •      state<=0;
  •     end
  • endcase
  • end
  • //--------------------------------------------------------------------------
  • // 选择占空比较大的那个脉冲作为最终输出
  • //--------------------------------------------------------------------------
  • assign pulse_max=(cnt_pulse0_r>cnt_pulse1_r)?pulse0:pulse1;
  • endmodule

复制代码

3. 扯犊子



上面实现的结果是选择占空比较大的作为了输出,如果想要输出占空比较小的那个脉冲,可以直接把最后的赋值语句改成 assign pulse_max=(cnt_pulse0_r<cnt_pulse1_r)?pulse0:pulse1;  即可。
返回列表