dspic30f2010 problem

Thread Starter

compuKidd

Joined Feb 5, 2009
2
hi guys I'm programming a dspic30f2010 to do "clock following" I have an external clock inputted at pin RE8 which is the INT0 (interrupt 0) bit I enable interrupt zero and set RE8 to input write a ISR for it that reads then resetes 32bit timer2/3 and estimate the period of the input clock interms of conter tics I then enable timer1 to count to a prespecified delay and in timer1 interrupt service routine I raise RB0 and set the timer to a period and then lower RB1 and disables timer1 and so on now this procedure occures every 2nd or more rising edge of the clock at INT0 (RE8).

the problem is that the output is zero and stays zero and it seems that the ICObits.T1IE is not being set in the INT0 ISR while I'm clearly setting it why???

is it because I have 3 interrupts working one for INT0 (priority 7) one for timer2/3 (priority 6) one for timer1 (priority 5)??? or not and if not why????

please help, any help will be appriciated
thx

Rich (BB code):
#include <stdio.h>
#include <p30f2010.h>
#include <math.h>

double maxDutyCycle=0.5;
double dutyCycle=0.5;
long int period=10000;
short int delay=100,minDelay=30;

int Next,High;
unsigned short mode=2;
unsigned short count=2;

inline void T1InterruptHelp()
{
	PORTBbits.RB0=Next;
	Next=!Next;
	IFS0bits.T1IF = 0; // clear interrupt flag

	if(Next==0) PR1=High;
	else IEC0bits.T1IE = 0;	// disable interrupt
}

#define _InterruptServiceRoutine __attribute__((interrupt,shadow))
void _InterruptServiceRoutine _T1Interrupt(void)
{
	T1InterruptHelp();
}

void _InterruptServiceRoutine _T3Interrupt(void)
{
	IFS0bits.T3IF=0;	// clear interrupt flag
}

double T=-1.0;
double LR=0.1;

inline long int myRound(double d)
{
	if(d-floor(d)>=0.5) return (long int)ceil(d);
	return (long int)floor(d);
}

void setLH();

void _InterruptServiceRoutine _INT0Interrupt(void)
{
	unsigned short LSB=TMR2;
	unsigned short MSB=TMR3HLD;

	unsigned long Val=MSB;
	Val=(Val<<16);
	Val=Val|LSB;

	TMR3HLD=0;			// clear timer3 register
	TMR2=0;				// clear timer2 register

	if(count==mode)
	{
		if(Next!=0)
		{
			// ERROR!!!!!
		}
		if(delay>minDelay)
		{
			// ???? //IFS0bits.T1IF = 0;	// clear interrupt flag
			TMR1=0;				// clear timer1 register
			PR1=delay;			// set timer
		}
		else
		{
			T1InterruptHelp();	
		}
		IEC0bits.T1IE = 1;	// enable interrupts
		count=(count%mode)+1;
	}
	else count=(count%mode)+1;
	
	IFS0bits.T3IF=0;	// clear interrupt flag
	if(T>0)
	{
		if(T/Val<2.0 && T/Val>0.5)
		{
			T=T*(1.0-LR)+Val*LR;
		}// else is an outlier
	}
	else T=Val;
	period=myRound(T);
	setLH();
}

void setLH()
{
	maxDutyCycle=1.0/mode;
	High=floor(period*dutyCycle);
	if(dutyCycle>maxDutyCycle) dutyCycle=maxDutyCycle;
}

int tmp=9;
int main (void)
{
	int inc=1;

	unsigned char RB1=PORTBbits.RB1;
	unsigned char RB2=PORTBbits.RB2;
	unsigned char RB3=PORTBbits.RB3;
	unsigned char RB4=PORTBbits.RB4;
	unsigned char RB5=PORTBbits.RB5;

	// timer 1 settings
	TMR1=0;				// clear timer1 register
	PR1=0XFF;			// set timer
	T1CONbits.TCS = 0;	// set internal clock source
	IPC0bits.T1IP = 6;	// set priority level
	IFS0bits.T1IF = 0;	// clear interrupt flag
	IEC0bits.T1IE = 0;	// no interrupts yet
	T1CONbits.TON = 1;	// start the timer
	
	// timer 2/3 settings
	TMR2=0;				// clear timer2 register
	TMR3=0;				// clear timer3 register
	T2CONbits.T32=1;	// set to timer2/3 32 bit timer
	PR2=0xFFFF;			// set timer
	PR3=0xFFFF;			// set timer
	IPC1bits.T2IP = 5;	// set priority level
	IPC1bits.T3IP = 5;	// set priority level
	IFS0bits.T3IF=0;	// clear interrupt flag
	IEC0bits.T3IE=1;	// enable interrupt
	T2CONbits.TCS = 0;	// set internal clock source	
	T2CONbits.TON = 1;	// start the timer

	// external interrupt 0 settings
	TRISEbits.TRISE8 = 1;// set port to input
	IFS0bits.INT0IF=0;	// clear interrupt flag
	IPC0bits.INT0IP=7;	// highest priority
	IEC0bits.INT0IE=1;	// enable external interrupt 0

	setLH();

	TRISBbits.TRISB0 = 0;	// set pin 0 on port b to output
	PORTBbits.RB0=0;		// initialise pin 0 of port b to 0 (this pin will be used to output the clock)
	Next=1;

	// pins 1-5 of port b are set to inputs each with special job
	TRISBbits.TRISB1 = 1;	// increment delay
	TRISBbits.TRISB2 = 1;	// decrement delay
	TRISBbits.TRISB3 = 1;	// increment duty cycle	by 0.0078125 (since this number is a decimal power of 2 i.e. can be represented exactly with no round off error)
	TRISBbits.TRISB4 = 1;	// decrement duty cycle	by 0.0078125
	TRISBbits.TRISB5 = 1;	// increment mode modulo 5

	TRISEbits.TRISE0 = 1;	// LSB for increment
	TRISEbits.TRISE1 = 1;	// MSB for increment

	while(1==1)
	{
		tmp=0;
		setLH();
		for(;tmp<100;tmp++);	// small delay

		if(PORTEbits.RE1==0 && PORTEbits.RE0==0) inc=1;
		else if(PORTEbits.RE1==0 && PORTEbits.RE0==1) inc=20;
		else if(PORTEbits.RE1==1 && PORTEbits.RE0==0) inc=400;
		else if(PORTEbits.RE1==1 && PORTEbits.RE0==1) inc=8000;

		//increment delay by inc at rising edge of portb pin 1
		if(RB1==0 && PORTBbits.RB1==1)
		{
			RB1=1;
			delay=delay+inc;
			if(delay>period) delay=period;
			setLH();
		}
		if(RB1==1 && PORTBbits.RB1==0)
		{
			RB1=0;
		}

		//decrement delay by inc at rising edge of portb pin 2
		if(RB2==0 && PORTBbits.RB2==1)
		{
			RB2=1;
			delay=delay-inc;
			if(delay<0) delay=0;
			setLH();
		}
		if(RB2==1 && PORTBbits.RB2==0)
		{
			RB2=0;
		}

		//increment dutycycle by 0.0078125 at rising edge of portb pin 3
		if(RB3==0 && PORTBbits.RB3==1)
		{
			RB3=1;
			dutyCycle=dutyCycle+0.00390625;
			if(dutyCycle>maxDutyCycle) dutyCycle=maxDutyCycle; // max dutyCycle=0.9375 (again no round off error)
			setLH();
		}
		if(RB3==1 && PORTBbits.RB3==0)
		{
			RB3=0;
		}

		tmp=1;

		//decrement dutycycle by 0.0078125 at rising edge of portb pin 4
		if(RB4==0 && PORTBbits.RB4==1)
		{
			RB4=1;
			dutyCycle=dutyCycle-0.00390625;
			if(dutyCycle<0.00390625) dutyCycle=0.00390625;	// min dutyCycle=0.00390625 (you guess)
			setLH();
		}
		if(RB4==1 && PORTBbits.RB4==0)
		{
			RB4=0;
		}

		//increment mode at rising edge of portb pin 5 modulo 5
		if(RB5==0 && PORTBbits.RB5==1)
		{
			RB5=1;
			mode=mode+1;
			if(mode>5) mode=2;		// min dutyCycle=0.00390625 (you guess)
			setLH();
		}
		if(RB5==1 && PORTBbits.RB5==0)
		{
			RB5=0;
		}
	}

	while(1)
	{
		tmp=0;
	}
	return 0;
}
 

Thread Starter

compuKidd

Joined Feb 5, 2009
2
Hi guys I'll make it a lot easier, check this one out:

Rich (BB code):
#include <stdio.h>
#include <p30f2010.h>
#include <math.h>

#define _InterruptServiceRoutine __attribute__((interrupt,shadow))

void _InterruptServiceRoutine _INT0Interrupt(void)
{
	PORTBbits.RB0=!PORTBbits.RB0;
}


int main (void)
{
	// external interrupt 0 settings
	TRISEbits.TRISE8 = 1;// set port to input
	IFS0bits.INT0IF=0;	// clear interrupt flag
	IPC0bits.INT0IP=6;	// highest priority
	IEC0bits.INT0IE=1;	// enable external interrupt 0

	TRISBbits.TRISB0 = 0;	// set pin 0 on port b to output
	PORTBbits.RB0=0;		// initialise pin 0 of port b to 0 (this pin will be used to output the clock)

	while(1);

	return 0;
}
i'm using the C30 compiler
now here I'm just flipping RB0 on every rising edge of RE8 (INT0/external interrupt 0) so you'd expect the output at RB0 to be a square with half the frequency, but what I'm getting is a square wave independent of RE0
my input is a ~70Hz signal and the output at RB0 is a square signal with 16.67KHz (notice the kilo) that is seemless of the input at RE0, why???

can any one please help me I'm down to my last hair (pulled all out) :)

any help will be apriciated
thanks
 
Top