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
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;
}