In the meantime looking at dsPIC capabilities and designed a first filter. 400Hz to 2.8KHz band width, using a P30F4013 (as have one!). This might go nowhere...
' Author M1KTA, dombaines@yahoo.com
' Date/Time: 25/08/2009 13:36:28
' Device setup:
' Device name: P30F4013
' Device clock: 080.000000 MHz
' Sampling Frequency: 20000 Hz
' Filter setup:
' Filter kind: FIR
' Filter type: Bandpass filter
' Filter order: 20
' Filter window: Rectangular
' Filter borders:
' Wp1: 400 Hz
' Wp2: 2800 Hz
const
BUFFER_SIZE = 32
FILTER_ORDER = 20
COEFF_B as Word[FILTER_ORDER+1] = (
0xFD0A, 0x00D8, 0xFE5F, 0xF592, 0xEB3C, 0xE6EC,
0xEEB0, 0x0316, 0x1DE4, 0x3493, 0x3D71, 0x3493,
0x1DE4, 0x0316, 0xEEB0, 0xE6EC, 0xEB3C, 0xF592,
0xFE5F, 0x00D8, 0xFD0A)
LOAD_PIN = 4 ' DAC load pin
CS_PIN = 5 ' DAC CS pin
dim
inext as Word ' Input buffer index
input_ as Word[BUFFER_SIZE] ' Input buffer
' This is ADC interrupt handler.
' Analogue input is sampled and the value is stored into input buffer.
' Input buffer is then passed through filter.
' Finally, the resulting output sample is sent to DAC.
sub procedure ADC1Int org $2A ' ADC interrupt handler
dim CurrentValue as word
input_[inext] = ADCBUF0 ' Fetch sample
CurrentValue = FIR_Radix(FILTER_ORDER+1,' Filter order
@COEFF_B, ' b coefficients of the filter
BUFFER_SIZE, ' Input buffer length
@input_, ' Input buffer
inext) ' Current sample
inext = (inext+1) and (BUFFER_SIZE-1) ' inext := (inext + 1) mod BUFFFER_SIZE;
while SPI1STAT.1 = 1 'wait for SPI module to finish, if doing something
nop
wend
LATF.CS_PIN = 0 ' CS enable for DAC
SPI1BUF = $3000 or CurrentValue ' Write CurrentValue to DAC ($3 is required by DAC)
while SPI1STAT.1 = 1 ' Wait for SPI module to finish write
nop
wend
LATF.LOAD_PIN = 0 ' Load data in DAC
LATF.LOAD_PIN = 1 '
LATF.CS_PIN = 1 ' CS disable for DAC
IFS0.11 = 0 ' Clear AD1IF
end sub
' This is Timer1 interrupt handler.
' It is used to start ADC at
' periodic intervals.
sub procedure Timer1Int org $1A ' Timer1 interrupt handler
ADCON1.1 = 1 ' Start sampling
ADCON1.15 = 1 ' Start conversion
IFS0.3 = 0 ' Clear TMR1IF
end sub
' Main program starts here.
' Firstly, hardware peripherals are initialized and then
' the program goes to an infinite loop, waiting for interrupts.
main:
' DAC setup
TRISF.LOAD_PIN = 0 ' LOAD pin
TRISF.CS_PIN = 0 ' CS pin
LATF.CS_PIN = 1 ' Set CS to inactive
LATF.LOAD_PIN = 1 ' Set LOAD to inactive
' SPI setup
SPI1_Init_Advanced(_SPI_MASTER, _SPI_16_BIT, _SPI_PRESCALE_SEC_1, _SPI_PRESCALE_PRI_1,
_SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH,
_SPI_ACTIVE_2_IDLE)
inext = 0 ' Initialize buffer index
Vector_Set(input_, BUFFER_SIZE, 0) ' Clear input buffer
' ADC setup
TRISB = $FFFF ' Use PORTB for input signal
ADCON1 = $00E2 ' Auto-stop sampling, unsigned integer out
ADCON2 = $0000
ADCON3 = $021A ' Sampling time= 3*Tad, minimum Tad selected
ADPCFG = $0000 ' Configure PORTB as ADC input port
ADCHS = $000A ' Sample input on RB10
ADCSSL = 0 ' No input scan
' Interrupts setup
IFS0 = 0
IFS1 = 0
IFS2 = 0
INTCON1 = $8000 ' Nested interrupts DISABLED
INTCON2 = 0
IEC0 = $0808 ' Timer1 and ADC interrupts ENABLED
IPC0.12 = 1 ' Timer1 interrupt priority level = 1
IPC2.13 = 1 ' ADC interrupt priority level = 2
' Timer2 setup
PR1 = $03E8 ' Sampling = 20000 Hz. Value of PR1 is dependent on clock.
T1CON = $8000 ' Timer1 ON, internal clock FCY, prescaler 1:1
while true ' Infinite loop,
nop ' wait for interrupts
wend
end.
No comments:
Post a Comment