scottlad
Newbie level 5
Hi, I have some experience with PIC programming but I'm new to using timer interrupts and Input capture. Would anyone have any idea where I'm going wrong. The values read from an input from a function generator seem to jump all over the place, any other info needed just ask and I'll provide it. Thanks in advance.
Code:
# include <p30f4011.h>
# include <math.h>
# include <stdio.h>
# include<InCap.h>
# include <xc.h>
# include <libpic30.h>
#define LED LATDbits.LATD0
// Configuration settings
_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, Fcy=30MHz
// (units are instruction cycles, Tcy=33.33ns @ 30 MIPS)
_FWDT(WDT_OFF); // Watchdog timer off
_FBORPOR(MCLR_DIS); // Master Clear Pin disabled
/*************Global Variables and Constants*************/
/*Variables used for period calculation*/
unsigned int timePeriod= 0;
unsigned int current_value=0,previous_value=0;
unsigned int new_value=0;
void __attribute__((__interrupt__)) _IC7Interrupt(void);
void __attribute__((__interrupt__, __shadow__)) _T2Interrupt(void);
/****FUNCTION PROTOTYPES****/
void IC7_SETUP(void);
void TIMER2_SETUP (void);
void setup();
/******MAIN BODY******/
int main (void)
{
TRISD=0; // Setting Port D pins as outputs
PORTD=0; // Reset The LED
PORTD=0xff; // Light The LED, to test the PIC is working
TRISB=0x003f; // Setting all PortB as inputs
ADPCFG=0xffff; // Setting the analogue pin as digital inputs
TIMER2_SETUP(); // Calling the Timer Setup Function
IC7_SETUP(); // Calling the Input Setup Function
setup(); // Calling the UART function
while(1)
{
}
return (0);
}
/***SETUP_IC****/
void IC7_SETUP (void)
{
// Register 13-1: ICxCON: Input Capture x Control Register in datasheet //
IC7CONbits.ICM= 0b011; // Input Capture Mode Select (Every rising edge)
IC7CONbits.ICBNE=0; // Input Capture Buffer Empty Status (Read Only)
IC7CONbits.ICOV=0; // Input Capture Overflow Status Flag (Read Only)
IC7CONbits.ICI= 00; // Select Number of Captures per Interrupt bits (00 = Interrupt on every capture event)
IC7CONbits.ICTMR=1; // Input Capture Timer Select bits (1=TMR2 contents are captured on captured event)
IC7CONbits.ICSIDL=0; // Input Capture Module Stop in Idle Control(0=Input capture module will continue to operate in CPU Idle mode)
// Register 6-6: IFS1: Interrupt Flag Status Register 1
IFS1bits.IC7IF = 0; // Input Capture Channel 7 Interrupt Flag Status )0=Interrupt bit is cleared
// Register 6-9: IEC1: Interrupt Enable Control Register 1
IEC1bits.IC7IE = 1; // Input Capture Channel 7 Interrupt Enable bit (1 = Interrupt request enabled)
}
/****INTERRUPT FOR IC7****/
// Capture Interrupt Service Routine
//unsigned int timePeriod= 0;
void __attribute__((__interrupt__, no_auto_psv )) _IC7Interrupt(void)
{
previous_value=current_value;
current_value=IC7BUF;
printf("Current value =%d \n, ",current_value);
printf("Previous value =%d \n, ",previous_value);
float time1 = 0;
float time2 = 0;
float time3 = 0;
float time4 = 0;
float frequency = 0;
if(current_value>previous_value)
{
timePeriod = current_value-previous_value;
printf("timePeriod =%d \n, ",timePeriod);
time1 = timePeriod*pow(33.33,-9);
time2 = pow((float)time2, -9);
frequency = 1/time2;
printf("frequency=%f Hz \n, ",time1);
}
}
/***TIMER_SETUP***/
void TIMER2_SETUP (void)
{
T2CON = 0x00; // Stops the Timer2 and reset control reg.
T2CONbits.TCS=0; // Using Internal Clock (Fosc/4)
T2CONbits.T32=0; // TMR2 and TMR3 form separate 16-bit timer
T2CONbits.TCKPS=0; // Using 1:1 prescale value
T2CONbits.TGATE=0; // Timer Gate Accumulation Disabled
T2CONbits.TSIDL=0; // Continue in Idle Mode*/
TMR2 = 0x00; // Clear contents of the timer register
PR2 = 0xFFFF; // Load the Period register with the value 0xFFFF
IPC1bits.T2IP = 0x01; // Setup Timer2 interrupt for desired priority leve
// (This example assigns level 1 priority)
IFS0bits.T2IF = 0; // Clear the Timer2 interrupt status flag
IEC0bits.T2IE = 1; // Enable Timer1 interrupts
T2CONbits.TON = 1; // Start Timer1 with prescaler settings at 1:1 and
// clock source set to the internal instruction cycle
}
/* Example code for Timer1 ISR*/
void __attribute__((__interrupt__, no_auto_psv, __shadow__)) _T2Interrupt(void)
{
/* Interrupt Service Routine code goes here */
IFS0bits.T2IF = 0; //Reset Timer1 interrupt flag and Return from ISR
}
void setup()
{
// Set up UART
// Default is 8 data bits, 1 stop bit, no parity bit
U1BRG = 48; // 38400 baud @ 30 MIPS
U1MODEbits.UARTEN = 1; // Enable UART
U1STAbits.UTXISEL = 1; // interrupt when TX buffer is empty
U1STAbits.UTXEN = 1; // Enable TX
}