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

开关量检测

开关量检测

开关量在检测过程中可能会产生抖动,程序需要进行必要的滤波处理。
CLK: 时钟,这里接入25M的时钟,WOBBLE_DELAY参数是抖动时间,它的值根据时钟的不同改变。
EN:检测开关。
LOGIC_IN: 开关量的输入引脚。
LOGIC_IN_MASK:开关量的屏蔽位。
LOGIC_IN_INT:开关量中断。
LOGIC_IN_STATE: 开关量的状态,仅在打开检测开关(EN)时读入的值有效。
CLEAR_INT:中断来临后,主机读取中断后写入1清中断。

  • module LogicInMan  
  • #(parameter WOBBLE_DELAY = 10 * 25000)  
  • (  
  •     CLK, EN, LOGIC_IN, LOGIC_IN_MASK, LOGIC_IN_INT, LOGIC_IN_STATE, CLEAR_INT  
  • );  
  • input CLK, EN;  
  • input[7:0] LOGIC_IN;  
  • input[7:0] LOGIC_IN_MASK;  
  • output LOGIC_IN_INT;  
  • output[7:0] LOGIC_IN_STATE;  
  • inout CLEAR_INT;  


  • reg LOGIC_IN_INT;  
  • reg clear_int_reg;  


  • reg[7:0] validLogicInStu;  
  • reg[7:0] orginLogicInStu;  
  • reg[7:0] lastLogicIn, curLogicIn;  
  • wire[7:0] logic_in_state;  

  • assign logic_in_state = validLogicInStu ^ orginLogicInStu;  
  • assign LOGIC_IN_STATE = logic_in_state;  

  • always @(posedge CLK)  
  • begin  
  •   if(!EN)  
  •     orginLogicInStu <= validLogicInStu;   

  •   lastLogicIn <= curLogicIn;  
  •   curLogicIn <= LOGIC_IN;  
  • end  

  • wire time_dly;  
  • wire start_dly;  

  • assign start_dly = (curLogicIn == lastLogicIn)?1'b1:1'b0;  

  • reg time_dly1, time_dly2;  
  • wire time_dly_tig;  
  • assign time_dly_tig = time_dly1 & ~time_dly2;  
  • always @(posedge CLK)  
  • begin  
  •   time_dly1 <= time_dly;  
  •   time_dly2 <= time_dly1;  
  • end  

  • always @(posedge CLK)  
  • begin  
  •     if(time_dly_tig)  
  •     begin  
  •         validLogicInStu <= LOGIC_IN;  
  •     end  

  • end  

  • reg[31:0] count;  
  • assign time_dly = (count == WOBBLE_DELAY)? 1'b1:1'b0;  
  • always @(posedge CLK)  
  • begin  
  •     if(!start_dly)  
  •         count <= 32'd0;  
  •     else  
  •     begin  
  •         if(count < WOBBLE_DELAY)  
  •             count <= count + 32'd1;  
  •     end  

  • end  


  • reg stu1, stu2;  
  • wire int_tig;  
  • assign int_tig = (stu1 != stu2 && (logic_in_state & LOGIC_IN_MASK))?1'b1:1'b0;  
  • always @(posedge CLK)  
  • begin  
  •   stu1 <= logic_in_state;  
  •   stu2 <= stu1;  
  • end  

  • always @(posedge CLK)  
  • begin  
  •     if(!EN || clear_int_reg)  
  •         LOGIC_IN_INT <= 1'b0;  
  •     else  
  •     begin  
  •         if(int_tig)  
  •             LOGIC_IN_INT <= 1'b1;  
  •     end  
  • end  

  • always @(posedge CLK)  
  • begin  
  •     if(CLEAR_INT)  
  •         clear_int_reg <= 1'b1;  
  •     else  
  •         clear_int_reg <= 1'b0;  
  • end  

  • assign CLEAR_INT = (!EN || clear_int_reg)?1'b0:1'bz;  

  • endmodule  


1. 程序中一直检测开关量的状态(无论是否打开检测开关),当开关量信号改变时开始记时,当信号稳定10ms后将它看作一个稳定信号。

2. 当打开检测开关时,记录下开关量的原始状态,这样做是考虑开关量常开、常闭或开关量不接的情况,以后的开关量状态与原始的开关量状态相比较(异或关系)。
3. 是否产生一个中断要与开关量屏蔽位相比较。
返回列表