Showing FIR filter value

Beta Testing discussion on mikroC PRO for dsPIC30/33 and PIC24.
Post Reply
Author
Message
orkidelolo
Posts: 12
Joined: 08 Nov 2016 17:22

Showing FIR filter value

#1 Post by orkidelolo » 23 Dec 2016 14:24

Hi everyone
I am using DSPIC33FJ256MC710-I/PT and I want to show the values which are filtered by FIR Filter
I use filter designer tools in MikroC pro for dspic the code is here
/// Setup of LCD////
sbit LCD_RS at LATF8_bit;
sbit LCD_EN at LATD3_bit;
sbit LCD_D4 at LATC13_bit;
sbit LCD_D5 at LATD0_bit;
sbit LCD_D6 at LATD2_bit;
sbit LCD_D7 at LATF7_bit;

sbit LCD_RS_Direction at TRISF8_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISC13_bit;
sbit LCD_D5_Direction at TRISD0_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISF7_bit;
const unsigned BUFFFER_SIZE = 32;
const unsigned FILTER_ORDER = 8;
char str[16];
unsigned int ADC_val=0;
// Device setup:
// Device name: P33FJ256MC710
// Device clock: 008.000000 MHz
// Dev. board: LV 24-33A
// Sampling Frequency: 16000 Hz
// Filter setup:
// Filter kind: FIR
// Filter type: Lowpass filter
// Filter order: 8
// Filter window: Rectangular
// Filter borders:
// Wpass:200 Hz

const unsigned COEFF_B[FILTER_ORDER+1] = {
0x064C, 0x0657, 0x0660, 0x0665, 0x0666, 0x0665,
0x0660, 0x0657, 0x064C};

sbit loadPin at LATC2_bit; // DAC load pin
sbit loadPinDir at TRISC2_bit; // DAC load pin
sbit csPin at LATC1_bit; // DAC CS pin
sbit csPinDir at TRISC1_bit; // DAC CS pin


unsigned inext; // Input buffer index
ydata unsigned input[BUFFFER_SIZE]; // Input buffer, must be in Y data space

/* This is ADC interrupt handler.
Analog 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.
*/
void ADC1Int() org IVT_ADDR_ADC1INTERRUPT { // ADC interrupt handler
unsigned CurrentValue;
input[inext] = ADCBUF0; // Fetch sample

// delay_ms(3);
CurrentValue = FIR_Radix(FILTER_ORDER+1,// Filter order
COEFF_B, // b coefficients of the filter
BUFFFER_SIZE, // Input buffer length
input, // Input buffer
inext); // Current sample

inext = (inext+1) & (BUFFFER_SIZE-1); // inext = (inext + 1) mod BUFFFER_SIZE;

csPin = 0; // CS enable for DAC
SPI2BUF = 0x3000 | CurrentValue; // Write CurrentValue to DAC (0x3 is required by DAC)

ADC_val=SPI2BUF;
intToStr(ADC_val,str) ;
// Lcd_Out(1,1,str);
UART1_Write_Text(str);
UART1_Write(',');
while (SPITBF_SPI2STAT_bit) // Wait for SPI module to finish write operation


csPin = 0;
asm nop;

loadPin = 0; // Load data in DAC

Delay_us(2);
loadPin = 1;

csPin = 1; // CS disable for DAC

AD1IF_bit = 0; // Clear AD1IF
}//~


/* This is Timer1 interrupt handler.
It is used to start ADC at periodic intervals.
*/
void Timer1Int() org IVT_ADDR_T1INTERRUPT { // Timer1 interrupt handler

if (DONE_bit){ // If ADC is not busy
SAMP_bit = 1; // Start new sample
}
LATD = PORTD ^ 0xFFFF; // You can put oscilloscope on PORTD
// to measure sampling frequency
T1IF_bit = 0;
}//~

/* The main program starts here.
Firstly, hardware peripherals are initialized and then
the program goes to an infinite loop, waiting for interrupts. */
void main() {
TRISB.F2= 1;
PORTC=0;
PORTA=0;
TRISA.F6= 1;
TRISA.F7= 1;
LATA.F6=0;
LATA.F7=0;
TRISF.F4= 0;
TRISF.F5= 0;
TRISB.F12= 0;
TRISB.F13= 0;
TRISC.F3= 1; // AN18
TRISD = 0;
// DAC setup
loadPinDir = 0; // LOAD pin
csPinDir = 0; // CS pin
csPin = 1; // Set CS to inactive
loadPin = 1; // Set LOAD to inactive

// SPI setup
SPI2_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, BUFFFER_SIZE, 0); // Clear input buffer

TRISB = 0xFFFF; // Use PORTB for input signal
// AD1CON1 = 0x00E2; // Auto-stop sampling, unsigned integer out
AD1CON1bits.FORM = 0; // Data Output Format: UnSigned Integer (Q15 format) Figure 16-14: ADC Output Format 70183D.pdf//
AD1CON1bits.SSRC = 7; // Internal counter ends sampling and starts conversion (auto-convert)
// AD1CON1bits.ASAM = 0; // Sampling begins when SAMP bit is set (for now)
AD1CON1bits.ASAM = 0;
AD1CON1bits.AD12B = 1; // 12-bit ADC operation
AD1CON1bits.ADDMABM = 1; // DMA buffers are built in conversion order mode ??
// AD1CON2 = 0x0000;
AD1CON2bits.VCFG=0; //Vref+=AVDD Vref-=AVSS//
AD1CON2bits.SMPI = 0; // SMPI must be 0
/*For devices without DMA, the SMPI<3:0> bits are referred to as the Number of Samples Per Interrupt Select bits. For devices with DMA, the SMPI<3:0> bits are referred to as the Increment
Rate for DMA Address Select bit.
*/
AD1CON2bits.CHPS = 0; // Converts CH0/CH1 When AD12B = 1, CHPS<1:0> is: U-0, Unimplemented, Read as ‘0’
// AD1CON2bits.CSCNA=1; //Scan Input Selections for CH0+ during Sample A bit
AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock
AD1CON3bits.SAMC = 2; // Auto Sample Time = 2*Tad
AD1CON3bits.ADCS = 1; // ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/40M)*5 = 125ns (0.08Mhz)
// ADC Conversion Time for 12-bit Tc=14*Tad = 1750ns (541.428571Khz)
// AD1CON3 = 0x0202; // Sampling time= 3*Tad, minimum Tad selected
ADPCFG = 0x0000; // Configure PORTB as ADC input port
AD1CHS0bits.CH0SA = 0b10010; // Sample input on RB10
AD1CSSL = 0; // No input scan
ADPCFG = 0x0000; // Configure PORTB as analog ADC input port
Lcd_init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // CLEAR display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,1,"Hello");
delay_ms(500);
/////////UART Connection/////
UART1_Init(19200);
UART1_Write_Text("test");

/////////////////////
// Interrupts setup
IFS0 = 0; // Clear interrupt flags
IFS1 = 0; // Clear interrupt flags
IFS2 = 0; // Clear interrupt flags
NSTDIS_bit = 1; // Nested interrupts DISABLED
INTCON2 = 0; // Other interrupt settings
T1IE_bit = 1; // Timer1 and
AD1IE_bit = 1; // ADC interrupts ENABLED
IPC0bits.T1IP = 1; // Timer1 interrupt priority level = 1
IPC3bits.AD1IP = 1; // ADC interrupt priority level = 1

PR1 = 0x00AD; // Sampling ~= 80 kHz. The value of 250 is calculated for 80MHz clock.
TON_bit = 1; // Start Timer1, internal clock FCY, prescaler 1:1

ADON_bit = 1; // ADC On
SAMP_bit = 1; // Start Sampling
while (1); // Infinite loop,
// wait for interrupts
}//~!



as the filter designer said "/* This is ADC interrupt handler.
Analog 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.
*/"
when I read the SPI2BUF I can see just '0'
what is my fault?
as matter of fact, I have to read what register to see the Filtered values of ADC?
it should be noted that when I read ADC value, I can read the real value without any problem and I cannot read filtered value

thank you so much in Advance
best regards

User avatar
uros.cvetinovic
mikroElektronika team
Posts: 803
Joined: 14 Dec 2015 09:24

Re: Showing FIR filter value

#2 Post by uros.cvetinovic » 26 Dec 2016 15:03

Hi,

Can you please tell me if you checked example for FIR filter that we provided?
It is located where your compiler is installed:
...\Mikroelektronika\mikroC PRO for dsPIC\Examples\Digital Signal Processing\FIR

Best regards,

Uros

Post Reply

Return to “mikroC PRO for dsPIC30/33 and PIC24 Beta Testing”