/*
This is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation.
This software is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License
1 tab == 4 spaces!
*/
/* Standard includes. */
#define USE_AND_OR /* To enable AND_OR mask setting */
#include <adc.h>
#include <libq.h>
#include <outcompare.h>
#include <timer.h>
#include <dsp.h>
/************************ Enable AND_OR mask setting *************************/
#define USE_AND_OR
/******************** Select the filter to be implemented. *******************
********** NOTE: Only one filter must be active at the same time **********/
#define FILTER 4
/*****************************************************************************/
/******************************************************************************
Setting the configuration bits for this project. The next lines are the
fuses definitions Reefer to Section: "Macros for setting device configuration
registers" in p33FJ16MC304.h dsPIC33FJ16MC304 device datasheet for more details
******************************************************************************/
//Boot Segment Program Memory
_FBS( BSS_NO_BOOT_CODE & BWRP_WRPROTECT_OFF )
//Code protection
_FGS( GSS_OFF & GCP_OFF & GWRP_OFF )
//Oscillator selection
_FOSCSEL( FNOSC_PRIPLL & IESO_OFF )
//Oscillator configuration
_FOSC( FCKSM_CSDCMD & IOL1WAY_ON & OSCIOFNC_OFF & POSCMD_HS )
//Watch Dog configuration
_FWDT( FWDTEN_OFF & WINDIS_OFF & WDTPRE_PR128 & WDTPOST_PS32768)
//PWM motor control module, I2c Alternate pins and Power on reset
_FPOR( PWMPIN_ON & HPOL_OFF & LPOL_OFF & ALTI2C_OFF & FPWRT_PWR128)
//Background Debugging and JTAG
_FICD( BKBUG_OFF & COE_OFF & JTAGEN_OFF & ICS_PGD1 )
/******************************************************************************
*********************** Global declaration for FILTERS **********************
******************************************************************************/
/*---------------------------------- FILTER 3 -------------------------------*/
#if (FILTER==4)
/*
const float a_n[] = { 2.79000, 4.63740, 5.019600, 3.9199000, 2.23010000,
0.93236, 0.27913, 0.057080, 0.0071498, 0.00041555};
const float b_n[] = {0.00021598, 0.0021598, 0.00971930, 0.0259180, 0.04535700, 0.054428,
0.04535700, 0.0259180, 0.00971930, 0.0021598, 0.00021598};
#define ELEMENTS_IN_a_n sizeof(a_n)/sizeof(float)
#define ELEMENTS_IN_b_n sizeof(b_n)/sizeof(float)
_Q16 f_a_n[ELEMENTS_IN_a_n];
_Q16 f_b_n[ELEMENTS_IN_b_n];
static _Q16 x[11];
static _Q16 y[11];
#endif
/*---------------------------------------------------------------------------*/
/******************************************************************************
************************ Setting up the hardware. ***************************
*****************************************************************************/
static void prvSetupHardware( void );
/******************************************************************************
-Main function:
*Initialize code for your application
*Execute an endless loop
******************************************************************************/
int main( void )
{
/* Configure any hardware required for this project. */
prvSetupHardware();
for(i=0; i<ELEMENTS_IN_a_n;i++)
f_a_n[i]=_Q16ftoi(a_n[i]);
for(i=0; i<ELEMENTS_IN_b_n;i++)
f_b_n[i]=_Q16ftoi(b_n[i]);
while(1)
{
}
/* Will only reach here if there is insufficient heap available during.
setup of hardware modules */
return 0;
}
/*---------------------------------------------------------------------------*/
/******************* prvSetup Hardware *************************************/
static void prvSetupHardware( void )
{
/*-------------------- Remappable PIN0 tied to OC1 ------------------------*/
RPOR0 = 0x12;
/*----------------------- Config PWM1 an its TIMER --------------------------*/
ConfigIntOC1(OC_INT_OFF ); //PWM without interrupt
ConfigIntTimer2(T2_INT_OFF); //TIMER2 without interrupt
//TIMER2 is the timer source for PWM1
OpenTimer2(T2_ON & T2_SOURCE_INT & T2_GATE_OFF & T2_32BIT_MODE_OFF & T2_PS_1_1,1025);
//PWM1 without fault check
OpenOC1(OC_IDLE_CON & OC_TIMER2_SRC & OC_PWM_FAULT_PIN_DISABLE, 1, 0);
/*----------------- Configuring the ADC channel 0 with ADC No.1 -------------*/
CloseADC1();
OpenADC1(ADC_MODULE_OFF & ADC_IDLE_STOP & ADC_AD12B_10BIT & ADC_FORMAT_INTG &
ADC_CLK_TMR,
ADC_VREF_AVDD_AVSS & ADC_SCAN_OFF & ADC_SELECT_CHAN_0 & ADC_SAMPLES_PER_INT_1,
ADC_SAMPLE_TIME_1 & ADC_CONV_CLK_1Tcy,
ADC_DMA_BUF_LOC_1,
ENABLE_ALL_DIG_16_31,
ENABLE_AN4_ANA,
SCAN_NONE_0_15,
SCAN_NONE_16_31);
SetChanADC1( ADC_CH123_POS_SAMPLEA_0_1_2, ADC_CH0_POS_SAMPLEA_AN4 & ADC_CH0_NEG_SAMPLEA_VREFN);
ConfigIntADC1(ADC_INT_ENABLE & ADC_INT_PRI_1);
ConfigIntTimer3(T3_INT_OFF);
T2CONbits.T32 = 0;
OpenTimer3(T3_ON & T3_SOURCE_INT & T3_GATE_OFF & T3_PS_1_1,12500);
}
/*---------------------------------------------------------------------------*/
/******************************* ADC INTERRUPT ******************************/
void __attribute__((__interrupt__, auto_psv)) _ADC1Interrupt( void )
{
static int DutyCycle=0;
/******************************************************************************
********************** Local Filter data definitions ************************
******************************************************************************/
/******************************************************************************
******************************** Filter implementations *********************
******************************************************************************/
/*---------------------------------- FILTER 4 -----------------------------*/
y[10] = y[9];
y[9] = y[8];
y[8] = y[7];
y[7] = y[6];
y[6] = y[5];
y[5] = y[4];
y[4] = y[3];
y[3] = y[2];
y[2] = y[1];
y[1] = y[0];
x[10] = x[9];
x[9] = x[8];
x[8] = x[7];
x[7] = x[6];
x[6] = x[5];
x[5] = x[4];
x[4] = x[3];
x[3] = x[2];
x[2] = x[1];
x[1] = x[0];
x[0] = ReadADC1(0);
y[0] = _Q16mac(f_b_n[0], x[0], y[0]);
y[0] = _Q16mac(f_b_n[1], x[1], y[0]);
y[0] = _Q16mac(f_b_n[2], x[2], y[0]);
y[0] = _Q16mac(f_b_n[3], x[3], y[0]);
y[0] = _Q16mac(f_b_n[4], x[4], y[0]);
y[0] = _Q16mac(f_b_n[5], x[5], y[0]);
y[0] = _Q16mac(f_b_n[6], x[6], y[0]);
y[0] = _Q16mac(f_b_n[7], x[7], y[0]);
y[0] = _Q16mac(f_b_n[8], x[8], y[0]);
y[0] = _Q16mac(f_b_n[9], x[9], y[0]);
y[0] = _Q16mac(f_b_n[10], x[10], y[0]);
y[0] = _Q16mac(f_a_n[0], y[1], y[0]);
y[0] = _Q16mac(f_a_n[2], y[3], y[0]);
y[0] = _Q16mac(f_a_n[4], y[5], y[0]);
y[0] = _Q16mac(f_a_n[6], y[7], y[0]);
y[0] = _Q16mac(f_a_n[8], y[9], y[0]);
y[0] = y[0] - _Q16mac(f_a_n[1], y[2], 0);
y[0] = y[0] - _Q16mac(f_a_n[3], y[4], 0);
y[0] = y[0] - _Q16mac(f_a_n[5], y[6], 0);
y[0] = y[0] - _Q16mac(f_a_n[7], y[8], 0);
y[0] = y[0] - _Q16mac(f_a_n[9], y[10], 0);
if(y[0]<0)
y[0] = _Q16neg(y[0]);
y[0]= _Q16shrNoSat(y[0], 1);
DutyCycle = y[0];
/*---------------------------------------------------------------------------*/
if (DutyCycle <= 0 ) DutyCycle = 1;
if (DutyCycle >= 1023) DutyCycle = 1023;
IFS0bits.AD1IF = 0;
SetDCOC1PWM(DutyCycle);
}
/*****************************************************************************/