| ??? 05/18/03 21:05 Read: times |
#45897 - RE: software filtering advice needed Responding to: ???'s previous message |
Waquar:
The idea for pulse detecting is NOT to do it at all the way you have it. The software delays like you have do not prove a darned thing about how wide the pulse is. Here is how to write it so you validate for example if a pulse coming in P2.0 is between two milliseconds value limits. This code only checks the first high pulse at P2.0 but should give you the idea to see why yours does not work.
;
;
;Check routine to use software loops and see if a high pulse on P2.0 is
;between two width limits.
;
;This code presumes that the input signal does not need de-bouncing
;or filtering. The nature of the edge detection will actually filter
;out a bouncing time that is shorter than 1 millisecond
;
;setup the legal limits of the pulse high time.
;
PULSE_HI_MIN EQU 35 ;minimum valid high time
PULSE_HI_MAX EQU 45 ;maximum valid high time
PULSE_TIMEOUT EQU 2000 ;pulse wait timeout value (2 seconds)
;
;
CSEG AT 0000H
RESET_VEC:
JMP INITIAL
;
BSEG AT 020H
PREV_BIT:
DBIT 1 ;previous state of bit
WORK_BIT:
DBIT 1 ;work bit
DSEG AT 040H
WIDTH_CNT:
DS 2 ;16-bit width counter variable
STACK:
DS 1 ;starting place for the stack
;
;
CSEG AT 0100H
INITIAL:
MOV SP,#STACK ;put the stack out of the way
SETB P2.0 ;make sure p2.0 is an input
MOV A,#1
CALL DELAY_MS
MOV C,P2.0 ;initialize the previous bit
MOV PREV_BIT,C
MOV A,#0 ;clear the width counter
MOV WIDTH_COUNT+0,A
M0V WIDTH_COUNT+1,A
;
;
;wait here for pulse to go from low to high. If we have waited
;more than the timeout periof then something is wrong do branch to handle
;the timeout.
;
WAIT_FIRST:
MOV A,#1
CALL DELAY_MS ;wait another millisecond
MOV A,WIDTH_COUNT+1 ;increment the width counter
ADD A,#1
MOV WIDTH_COUNT+1,A
MOV A,WIDTH_COUNT+0
ADC A,#0
MOV WIDTH_COUNT+0,A ;save the incremented width
;
MOV A,WIDTH_COUNT+0 ;check if timeout has come
CJNE A,#HIGH(PULSE_TIMEOUT),WF_1
MOV A,WIDTH_COUNT+1
CJNE A,#LOW(PULSE_TIMEOUT),WF_1
WF_1:
JNC TMO_FIRST ;go deal with the timeout
;
MOV C,P2.0 ;check for change of input bit
MOV WORK_BIT,C ;save a copy of the port bit
ANL C,/PREV_BIT ;curr & /prev = change from o to 1
JC GOT_FIRST ;got the leading edge of pulse
MOV C,WORK_BIT ;save current value as now previous value
MOV PREV_BIT,C
JMP WAIT_FIRST ;loop to wait more
;
;get here when the first edge has happened @ P2.0. Setup to measure the
;high period of the pulse and then wait for it to go back off. will deal
;with a timeout if it occurs
;
GOT_FIRST:
MOV A,#0 ;clear the width counter
MOV WIDTH_COUNT+0,A
M0V WIDTH_COUNT+1,A
WAIT_END:
MOV A,#1
CALL DELAY_MS ;wait another millisecond
MOV A,WIDTH_COUNT+1 ;increment the width counter
ADD A,#1
MOV WIDTH_COUNT+1,A
MOV A,WIDTH_COUNT+0
ADC A,#0
MOV WIDTH_COUNT+0,A ;save the incremented width
;
MOV A,WIDTH_COUNT+0 ;check if timeout has come
CJNE A,#HIGH(PULSE_TIMEOUT),WE_1
MOV A,WIDTH_COUNT+1
CJNE A,#LOW(PULSE_TIMEOUT),WE_1
WE_1:
JNC TMO_PULSE ;go deal with timeout
;
MOV C,P2.0 ;check for change of input bit
MOV WORK_BIT,C ;save a copy of the port bit
MOV C,PREV_BIT
ANL C,/WORK_BIT ;/curr & prev = change from 1 to 0
JC END_FIRST ;got the first pulse trailing edge
MOV C,WORK_BIT ;save current value as now previous value
MOV PREV_BIT,C
JMP WAIT_END ;loop to wait more
;
;get here when the pulse has ended and we check its width within legal limits
;
END_FIRST:
MOV A,WIDTH_COUNT+0 ;check if above the minimum width
CJNE A,#HIGH(PULSE_HI_MIN),EF_1
MOV A,WIDTH_COUNT+1
CJNE A,#LOW(PULSE_HI_MIN),EF_1
EF_1:
JC ILLEGAL_PULSE ;go to show pulse was illegal
;
MOV A,WIDTH_COUNT+0 ;check if over the maximum width
CJNE A,#HIGH(PULSE_HI_MAX),EF_2
MOV A,WIDTH_COUNT+1
CJNE A,#LOW(PULSE_HI_MAX),EF_2
EF_2:
JNC ILLEGAL_PULSE ;go to show pulse was illegal
;
;
;got here when the pulse is seen as a good width
;
GOOD_FIRST:
NOP ;junk code here now
JMP GOOD_FIRST ;replace
;
;
;get here when there was a timeout waiting for first rising edge
;
TMO_FIRST:
;code here to deal with legal high time of pulse.
NOP ;junk code here now
JMP TMO_FIRST ;replace
;
;
;get here when there was a timeout waiting for the pulse to complete
;
TMO_PULSE:
;code here to deal with timeout condition
NOP ;junk code here now
JMP TMO_PULSE ;replace
;
;
;get here when the width of the pulse was too short or too long
;
BAD_PULSE:
;code here to deal with situation
NOP ;junk code here now
JMP BAD_PULSE ;replace
;
;
;subroutine to delay count od A milliseconds (this was designed with
;a standard type 80C51 in mind that has /12 clocking and is equipped
;with an 11.0592 mHz crystal.
;
;entry A is the number of milliseconds to wait.
;
DELAY_MS:
PUSH ACC
MOV A,#228
DELAY_LP:
NOP
NOP
DJNZ ACC,DELAY_LP ;wait out the millisecond
POP ACC
DJNZ ACC,DELAY_MS ;need to do another millisecond?
RET
;
;
END
Michael Karas |



