John Larkin wrote:
It is certainly possible to do digital filters which work like a Spice
simulation of analog filters. It is nothing wrong about this approach
although it is very inefficient and prone to the specific numeric problems.
If the coefficients are done by shifts, most likely it is a dull fulter
with very loose requirements.
Well, this just works, and seems fairly efficient to me:
.SBTTL . ANALOG LOWPASS FILTERS
; INPUT SAMPLES ARE TAKEN AT THE 139-HZ RATE AND SOFTWARE LOWPASS
; FILTERED. THE FILTER IS A 4-POLE, STATE-VARIABLE (INTEGRATOR-BASED)
; GADGET WITH A 'TRANSITIONAL' (EG, HOMEBREW) TRANSFER FUNCTION.
NODE 1 NODE 2 NODE 3
| | |
IN
-->--(+)--[K1:INT]---(+)--[K2:INT]-->--(+)--[K3:INT]---(+)--[K4:INT]-->--OUT
| | | | | |
| | | | | |
| ^---(-1)--- | | ^---(-1)--- |
| | | |
| | | |
'------<----(-1)------------' '-------<------(-1)---------'
; THE FOUR LOWPASS FILTER INTEGRATION COEFFICIENTS ARE ALL EXPRESSED
; AS RIGHT-SHIFT COUNTS, AVOIDING POKEY MULTIPLIES.
; CAUTIONS: EVEN IF ALL INPUTS ARE POSITIVE NUMBERS, OCCASIONAL
; SLIGHTLY-NEGATIVE OUTPUT GLITCHES ARE POSSIBLE.
; BIG SAMPLE-TO-SAMPLE EXCURSIONS CAN CAUSE WILD END-AROUNDS, SO
; IT'S PRUDENT TO KEEP INPUT RANGE BELOW +- 0.25 FRACTIONAL.
; OK, HERE'S THE FILTER. WE USE REGISTERS D0-D6, AND ASSUME
; THAT A0 AIMS INTO A 4-NODE FILTER BLOCK.
; ON ENTRY, D0.L SHOULD HOLD THE FRESH FILTER INPUT.
; FOR SLOW ITEMS, WE USE A FILTER WITH RISETIME OF ABOUT 2 SECONDS,
; CORRESPONDING TO BANDWIDTH OF ABOUT 0.17 HZ. CONSTANTS ARE...
K1 = 7 ; 0.0078125
K2 = 5 ; 0.03125
K3 = 6 ; 0.015625
K4 = 5 ; 0.03125
LOWPAS: MOVEM.L (A0)+, D1 D2 D3 D4 ; SCOOP UP ALL TABLE NODES
; DO THE FIRST 2-POLE LOWPASS...
SUB.L D2, D0 ; MAKE INTEGRATOR K1 INPUT
MOVE.L D1, D6 ; NOW COMPUTE INTEGRATOR K2'S
SUB.L D2, D6 ; INPUT
ASR.L # K1, D0 ; SCALE AND
ADD.L D0, D1 ; INTEGRATE K1
MOVE.L D2, D5 ; SNAP 2ND STAGE INPUT = OUR OUTPUT
ASR.L # K2, D6 ; SCALE AND INTEGRATE
ADD.L D6, D2 ; K2
; NOW DO THE SECOND 2-POLE LOWPASS...
SUB.L D4, D5 ; AND MAKE THE K3 INTEGRATOR INPUT
MOVE.L D3, D6 ; COPY K3 OUTPUT TO MAKE
SUB.L D4, D6 ; K4'S INPUT
ASR.L # K3, D5 ; SCALE AND
ADD.L D5, D3 ; INTEGRATE K3
ASR.L # K4, D6 ; SCALE AND
ADD.L D6, D4 ; INTEGRATE K4
MOVEM.L D4 D3 D2 D1, -(A0) ; REPLACE ALTERED TABLE NODES
RTS
This is fine for lowpass filtering thermocouple data. In situations
where transient response has to be more precise, like high-speed
weighing, some of the shifts can be replaced by fractional multiplies,
which has a minimal penalty on this CPU, a 68332.