开关量在检测过程中可能会产生抖动,程序需要进行必要的滤波处理。
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. 是否产生一个中断要与开关量屏蔽位相比较。 |