CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Timer problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

Timer problem
PostPosted: Mon Mar 14, 2011 3:10 pm     Reply with quote

Hi There,

I've been having a problem with my timers and several people have told me i should sumarize my problem in a sample app. That's what I've done now but even my sample app has 182 lines and I'm hesitant to post that here. A summary, I have three frequency timers that will kick in every xms, e.g. 50Hz . When that kicks in, it sets a port and starts a "pulse timer" that will kick in after "pulse length" (~200-500uS) to reset the pin again.
And because i need the possibility to offset them to each other, I defined one freq timer as the master timer and the two thers can be offset to that. The offset can be +/- XuS. I would start the 3 frequency timers with delays in between each other to satisfy the offsets and then use the same count variable for all to satisfy the frequency (which is for now for all the same but will be able to be different in the next version of the product).
So far so good in my head but something doesn't work correctly.
There's always an offset between the timers. I don't get them lined up properly. My offset theory doesn't seem to work... :(

Instead of jamming up this forum, the source code can be downloaded from:here - Would be awesome if someone had a little time and could help me!
Thank you in advance!
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Wed Mar 16, 2011 10:10 am     Reply with quote

No ideas? Or no time looking at it at all, maybe? Confused
ALPL



Joined: 29 Mar 2009
Posts: 30

View user's profile Send private message

PostPosted: Thu Mar 17, 2011 7:51 am     Reply with quote

I donĀ“t know your code but did you consider the time your function calls within the ISR(s) take when they are executed? You need to adjust for this time-delay.
Geps



Joined: 05 Jul 2010
Posts: 129

View user's profile Send private message

PostPosted: Thu Mar 17, 2011 7:57 am     Reply with quote

cerr wrote:
No ideas? Or no time looking at it at all, maybe? Confused


I don't think anyone will take the risk downloading from that site. Quote it here....the forum is here to get clogged up with code Wink
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Fri Mar 18, 2011 10:03 am     Reply with quote

Uh okay, if you think so, here it is:
Code:
#include <18F87K22.h>
#device ICD=TRUE
#device adc=16

#FUSES NOWDT                      //No Watch Dog Timer
#FUSES WDT128                     //Watch Dog Timer uses 1:128 Postscale
#FUSES HSM                         //Hi-Speed crystal oscillator
#FUSES NOBROWNOUT                 //No brownout reset
#FUSES NOPLLEN            //No PLL enabled
#FUSES BBSIZ1K                    //1K words Boot Block size
#FUSES NOXINST                    //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(clock=10000000)

#define CALC 625000         //calculation constant for timer calculations ((10000000/4)/4)
#define FREQMHZ 10
#define SET_LPRTMR set_Timer1
#define SET_OVRTMR set_timer3
#define SET_SYNCTMR set_timer5
#define MCU1_SYNC PIN_D1
#define LL_LPR PIN_D2
#define LL_OVR PIN_D3

unsigned int32 timval=0;
int main (void){
setup_timer_1(T1_DISABLED ); // Setup timer for LPR LL pulse
setup_timer_3(T3_DISABLED ); // Setup timer for OVR LL pulse
setup_timer_5(T5_DISABLED ); // Setup timer for SYNC pulse 
float period=0;
float fixval=0; 
int1 config=0;
unsigned int8 LPRval=0;
unsigned int8 OVRval=0;
unsigned int8 SYNCval=0;
int16 LPRwdt=500;
int16 OVRwdt=500;
int16 SYNCwdt=500;
SIGNED int16 LPRoff=0;
SIGNED int16 OVRoff=0;
  while (true){
    if (!config){
      int8 Freq=50;
        period=1/(float)Freq;       
        timval=65560-(CALC*(1/(float)Freq));
        /*** calculate timer values for pulse widths ***/
      fixval=1/((float)FREQMHZ/4/16);
      LPRval=LPRwdt/fixval;
      OVRval=OVRwdt/fixval;
      SYNCval=SYNCwdt/fixval;
        setup_timer_2(T2_DIV_BY_16, LPRval, 1); // Setup timer for LPR LL pulse
        setup_timer_4(T4_DIV_BY_16, OVRval, 1); // Setup timer for OVR LL pulse
        setup_timer_6(T6_DIV_BY_16, SYNCval, 1); // Setup timer for SYNC pulse   
        /*** start "frequency timers" in correct order ***/
    if((LPRoff<OVRoff)){
    if (LPRoff<0){
      if (OVRoff<0){
      // LPR, OVR, SYNC
      SET_LPRTMR(timval);
      delay_us((LPRoff-OVRoff)*-1);
      SET_OVRTMR(timval);
      delay_us(OVRoff*-1);
      SET_SYNCTMR(timval);
      } else {
      // LPR, SYNC, OVR
      SET_LPRTMR(timval);
      delay_us(LPRoff*-1);
      SET_SYNCTMR(timval);
      delay_us(OVRoff);
      SET_OVRTMR(timval);
      }
    } else {
      // SYNC, LPR, OVR
      SET_SYNCTMR(timval);
      delay_us(LPRoff);
      SET_LPRTMR(timval);
      delay_us(OVRoff-LPRoff);
      SET_OVRTMR(timval);
    }
    } else if (OVRoff<LPRoff) {
    if (OVRoff<0){
      if (LPRoff<0){
      // OVR, LPR, SYNC
      SET_OVRTMR(timval);
      delay_us((OVRoff-LPRoff)*-1);
      SET_LPRTMR(timval);
      delay_us(LPRoff*-1);
      SET_SYNCTMR(timval);
      } else {
      // OVR, SYNC, LPR
      SET_OVRTMR(timval);
      delay_us(OVRoff*-1);
      SET_SYNCTMR(timval);
      delay_us(LPRoff);
      SET_LPRTMR(timval);
      }
    } else {
    // SYNC, OVR, LPR
      SET_SYNCTMR(timval);
      delay_us(OVRoff);
      SET_OVRTMR(timval);
      delay_us(LPRoff-OVRoff);
      SET_LPRTMR(timval);
    }
    } else if (OVRoff == LPRoff) {
    if (LPRoff<0){
    // LPRoff && OVRoff, SYNC
      SET_LPRTMR(timval);
      SET_OVRTMR(timval);
      delay_us(LPRoff*-1);
      SET_SYNCTMR(timval);
    } else {
      SET_SYNCTMR(timval);
      delay_us(LPRoff);
      SET_LPRTMR(timval);
      SET_OVRTMR(timval);
    }
    }
    // enable interrupts
      setup_timer_1(T1_INTERNAL | T1_DIV_BY_4 ); // Setup timer for LPR LL pulse
      setup_timer_3(T3_INTERNAL | T3_DIV_BY_4 ); // Setup timer for OVR LL pulse
      setup_timer_5(T5_INTERNAL | T5_DIV_BY_4 ); // Setup timer for SYNC pulse

      enable_interrupts(INT_TIMER1);  //enabel timer1 (16bit) interrupt to set LPR LL
      enable_interrupts(INT_TIMER2);  //enable timer2 (8bit) interrupt to reset LPR LL
      enable_interrupts(INT_TIMER3);  //enable timer3 (16bit) interrupt to set OVR LL
      enable_interrupts(INT_TIMER4);  //enable timer4 (8bit) interrupt to reset OVR LL
      enable_interrupts(INT_TIMER5);  //enable timer4 (8bit) interrupt to reset OVR LL
      enable_interrupts(INT_TIMER6);  //enable timer6 (8bit) interrupt to reset sync
      enable_interrupts(INT_SSP);    //enable i2c interrupt
      enable_interrupts(GLOBAL);
      config=1;
   }   
  }     
}
//------------------------------------------------------------------------------

#INT_TIMER1
void TIMER1_isr() {
  set_timer1(timval);
  output_high(LL_LPR);
  set_timer2(0);           // set timer2 to reset the LPR linelock

}
//------------------------------------------------------------------------------

#INT_TIMER3
void TIMER3_isr() {
  set_timer3(timval);
  output_high(LL_OVR);
  set_timer4(0);          // set timer4 to reset the OVR linelock

}
//------------------------------------------------------------------------------

#INT_TIMER5
void TIMER5_isr() {
  set_timer5(timval);
  output_high(MCU1_SYNC);
  set_timer6(0);          // set timer6 to reset sync pulse
}
//------------------------------------------------------------------------------

#int_TIMER2
void TIMER2_isr()
{
  output_low(LL_LPR);
}
//------------------------------------------------------------------------------

#int_TIMER4
void TIMER4_isr()
{
  output_low(LL_OVR);
}
//------------------------------------------------------------------------------

#INT_TIMER6
void TIMER6_isr()
{
  output_low(MCU1_SYNC);
}
//------------------------------------------------------------------------------
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Fri Mar 18, 2011 4:36 pm     Reply with quote

Okay, I fiddled around a litte today and got my code to improve minorly until I replaced timer1 with timer7. That made a "huge" difference, and it works better now, not perfect but way better! Why does a replace make such a huge difference? Confused
Timer7 & 3 are offset by about -50uS now and 7 & 5 about +150 so 5 & 3 are still 200uS apart - which is way out of tolerance :(
Thanks for help. I have pasted my updated code below:
Code:
#include <18F87K22.h>
#device ICD=TRUE, HIGH_INTS=TRUE, adc=16

#FUSES NOWDT                      //No Watch Dog Timer
#FUSES WDT128                     //Watch Dog Timer uses 1:128 Postscale
#FUSES HSM                        //Hi-Speed crystal oscillator
#FUSES NOBROWNOUT                 //No brownout reset
#FUSES NOPLLEN                    //No PLL enabled
#FUSES BBSIZ1K                    //1K words Boot Block size
#FUSES NOXINST                    //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(clock=10000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=DEBUG, ERRORS)

#define CALC 625000         //calculation constant for timer calculations ((10000000/4)/4)
#define FREQMHZ 10
#define SET_LPRTMR set_Timer7
#define SET_OVRTMR set_timer3
#define SET_SYNCTMR set_timer5
#define MCU1_SYNC PIN_D1
#define LL_LPR PIN_D2
#define LL_OVR PIN_D3
#define OFFSET_ARR_SZ 3

unsigned int32 timval=0;
unsigned int8 LPRval=0;
unsigned int8 OVRval=0;
unsigned int8 SYNCval=0;

void long_delay_us(long count)
{
 char i;

 i = (char)(count >> 8);

 while(i >= 1)
    {
     i--;
     delay_us(253);
     restart_wdt();
    }
 
 delay_us((char)count);
}

void main (void){
float period=0;
float fixval=0; 
int1 config=0;
int16 LPRwdt=500;
int16 OVRwdt=500;
int16 SYNCwdt=500;
int16 delay[OFFSET_ARR_SZ]={0};
int8 order[OFFSET_ARR_SZ]={0};
int8 ctr=0;
int32 temp;
int32 iarray[OFFSET_ARR_SZ]={0};
  while (true){
    if (!config){
 
       iarray[0]=0; //SYNC
       iarray[1]=0; //LPR
       iarray[2]=0; //OVR
      
       iarray[0]|=0x10000000; // set SYNC ID bit
       iarray[1]|=0x20000000; // set LPR ID bit
      iarray[2]|=0x40000000; // set OVR ID bit
     
      // Bubble sort offset times
       for (ctr=0;ctr<OFFSET_ARR_SZ;ctr++) {
        if ((iarray[ctr]&0x00FFFFFF) > (iarray[ctr+1]&0x00FFFFFF)) {
            //Here a swap is needed
            temp=iarray[ctr+1];
            iarray[ctr+1]=iarray[ctr];
            iarray[ctr]=temp;
        }
      }      
      
      int8 Freq=50;
      period=1/(float)Freq;       
      timval=65560-(CALC*(1/(float)Freq));
        /*** calculate timer values for pulse widths ***/
      fixval=1/((float)FREQMHZ/4/16);
      LPRval=LPRwdt/fixval;
      OVRval=OVRwdt/fixval;
      SYNCval=SYNCwdt/fixval;
      fprintf(DEBUG, "LPRval %d\r\n",LPRval);
      fprintf(DEBUG, "OVRval %d\r\n",OVRval);     
      fprintf(DEBUG, "SYNCval %d\r\n",SYNCval);
      // extract delay time
      delay[0]=iarray[0]&0x0FFFFFFF;
      delay[1]=(iarray[1]&0x0FFFFFFF)-delay[0];
      delay[2]=(iarray[2]&0x0FFFFFFF)-delay[1];
      // extract the ID
      order[0]=((iarray[0]&0xf0000000)>>28);
      order[1]=((iarray[1]&0xf0000000)>>28);
      order[2]=((iarray[2]&0xf0000000)>>28);
      /*** start "frequency timers" in correct order ***/
      if (order[0]==0x1){
        long_delay_us(delay[0]);
        SET_SYNCTMR(timval);
      } else if (order[0]==0x2){
        long_delay_us(delay[0]);
        SET_LPRTMR(timval);
      } else if (order[0]==0x4){
        long_delay_us(delay[0]);
        SET_OVRTMR(timval);
      } else
        fprintf(DEBUG"ERROR starting first timer0x%8x\r\n",(iarray[0]&0xf0000000));
      if (order[1]==0x1){
        long_delay_us(delay[1]);
        SET_SYNCTMR(timval);
      } else if (order[1]==0x2){
        long_delay_us(delay[1]);
        SET_LPRTMR(timval);
      } else if (order[1]==0x4){
        long_delay_us(delay[1]);
        SET_OVRTMR(timval);
      } else
        fprintf(DEBUG"ERROR starting second timer0x%8x\r\n",(iarray[1]&0xf0000000));
      if (order[2]==0x1){
        long_delay_us(delay[2]);
        SET_SYNCTMR(timval);
      } else if (order[2]==0x2){
        long_delay_us(delay[2]);
        SET_LPRTMR(timval);
      } else if (order[2]==0x4){
        long_delay_us(delay[2]);
        SET_OVRTMR(timval);
      }else
        fprintf(DEBUG"ERROR starting third timer0x%8x\r\n",(iarray[2]&0xf0000000));
    // enable interrupts
      setup_timer_7(T7_INTERNAL | T7_DIV_BY_4 ); // Setup timer for LPR LL pulse
      setup_timer_3(T3_INTERNAL | T3_DIV_BY_4 ); // Setup timer for OVR LL pulse
      setup_timer_5(T5_INTERNAL | T5_DIV_BY_4 ); // Setup timer for SYNC pulse
      setup_timer_2(T2_DIV_BY_16, LPRval, 1); // Setup timer for LPR LL pulse
      setup_timer_4(T4_DIV_BY_16, OVRval, 1); // Setup timer for OVR LL pulse
      setup_timer_6(T6_DIV_BY_16, SYNCval, 1); // Setup timer for SYNC pulse
      enable_interrupts(INT_TIMER7);     //enabel timer1 (16bit) interrupt to set LPR LL
     enable_interrupts(INT_TIMER2);     //enable timer2 (8bit) interrupt to reset LPR LL
     enable_interrupts(INT_TIMER3);     //enable timer3 (16bit) interrupt to set OVR LL
     enable_interrupts(INT_TIMER4);     //enable timer4 (8bit) interrupt to reset OVR LL
     enable_interrupts(INT_TIMER5);     //enable timer5 (16bit) interrupt to reset OVR LL
     enable_interrupts(INT_TIMER6);     //enable timer6 (8bit) interrupt to reset sync
     enable_interrupts(GLOBAL);
      config=1;
   }   
  }     
}
//------------------------------------------------------------------------------

#INT_TIMER7 HIGH
void TIMER7_isr() {
  set_timer7(timval);
  output_high(LL_LPR);
  set_timer2(0);           // set timer2 to reset the LPR linelock
}
//------------------------------------------------------------------------------

#INT_TIMER3 HIGH
void TIMER3_isr() {
  set_timer3(timval);
  output_high(LL_OVR);
  set_timer4(0);          // set timer4 to reset the OVR linelock

}
//------------------------------------------------------------------------------

#INT_TIMER5 HIGH
void TIMER5_isr() {
  set_timer5(timval);
  output_high(MCU1_SYNC);
  set_timer6(0);          // set timer6 to reset sync pulse
}
//------------------------------------------------------------------------------

#int_TIMER2 HIGH
void TIMER2_isr()
{
  output_low(LL_LPR);
}
//------------------------------------------------------------------------------

#int_TIMER4 HIGH
void TIMER4_isr()
{
  output_low(LL_OVR);
}
//------------------------------------------------------------------------------

#INT_TIMER6 HIGH
void TIMER6_isr()
{
  output_low(MCU1_SYNC);
}
//------------------------------------------------------------------------------
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Fri Mar 18, 2011 8:38 pm     Reply with quote

If I were doing this, I'd use only one timer. What worries me here is that you can get all the timers clamoring for interrupts at the same time, and given the PIC's rather leisurely entry and exit to interrupts, you'll get significant inaccuracies.

If you just had the one timer, you'd want to calculate when the 6 events that make up a cycle need to occur (i.e. outputs A, B and C each going on and then off again). You'd calculate the intervals between each successive pair of events, and reset the timer appropriately every time it triggers.

But what if two events are very close, or simultaneous? Well, then you don't use the interrupt at all, but instead you execute a short delay while you're still in the interrupt, then perform the second operation. The program has to calculate when to use a new interrupt, versus when to stay in the interrupt and use a delay. It's not totally trivial, but that's what they pay you the big bucks to do.

Now, thinking ahead to the next product where there'll be different frequencies--you'll have to recalculate the intervals periodically. More fun! But I think it can still be done.
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Mon Mar 21, 2011 10:01 am     Reply with quote

John P wrote:
If I were doing this, I'd use only one timer. What worries me here is that you can get all the timers clamoring for interrupts at the same time, and given the PIC's rather leisurely entry and exit to interrupts, you'll get significant inaccuracies.

If you just had the one timer, you'd want to calculate when the 6 events that make up a cycle need to occur (i.e. outputs A, B and C each going on and then off again). You'd calculate the intervals between each successive pair of events, and reset the timer appropriately every time it triggers.

But what if two events are very close, or simultaneous? Well, then you don't use the interrupt at all, but instead you execute a short delay while you're still in the interrupt, then perform the second operation. The program has to calculate when to use a new interrupt, versus when to stay in the interrupt and use a delay. It's not totally trivial, but that's what they pay you the big bucks to do.

Now, thinking ahead to the next product where there'll be different frequencies--you'll have to recalculate the intervals periodically. More fun! But I think it can still be done.


What about if i just use one interrupt to set the outputs (and timers) and then use 3 ISRs to reset the outputs appropriately - seems easier and more straight forward to me than calculating when which event (on & off) needs to occur...
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Mon Mar 21, 2011 10:52 am     Reply with quote

I tried it that way round now:
Have one timer to kick in a frequency, calculate the offset times and start the "reset timers" after the offset times to correctly reset the pulses after "width" time but I still seem to get somewhat inacurrate readings with my oscilloscope. Timer8 that's to reset the LPR_LL is jumping between ~200 and ~100 uSec back and forth... :( Why would that be? Any ideas?
The code now looks like this:
Code:
#include <18F87K22.h>
#device ICD=TRUE, HIGH_INTS=TRUE, adc=16

#FUSES NOWDT                      //No Watch Dog Timer
#FUSES WDT128                     //Watch Dog Timer uses 1:128 Postscale
#FUSES HSM                        //Hi-Speed crystal oscillator
#FUSES NOBROWNOUT                 //No brownout reset
#FUSES NOPLLEN                    //No PLL enabled
#FUSES BBSIZ1K                    //1K words Boot Block size
#FUSES NOXINST                    //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(clock=10000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=DEBUG, ERRORS)

#define CALC 625000         //calculation constant for timer calculations ((10000000/4)/4)
#define FREQMHZ 10
#define SET_LPRTMR set_Timer7
#define SET_OVRTMR set_timer3
#define SET_SYNCTMR set_timer5
#define MCU1_SYNC PIN_D1
#define LL_LPR PIN_D2
#define LL_OVR PIN_D3
#define OFFSET_ARR_SZ 2

unsigned int32 timval=0;
unsigned int8 LPRval=0;
unsigned int8 OVRval=0;
unsigned int8 SYNCval=0;
int16 delay[OFFSET_ARR_SZ+1]={0};
int8 order[OFFSET_ARR_SZ+1]={0};
int32 iarray[OFFSET_ARR_SZ+1]={0};

void long_delay_us(long count)
{
 char i;

 i = (char)(count >> 8);

  while(i >= 1){
    i--;
    delay_us(253);
    restart_wdt();
  }
 
 delay_us((char)count);
}

void bubblesort(int8 arr_cnt, int32 *comb_arr)
{
int8 ctr;
int32 temp;   
  for (ctr=0;ctr<arr_cnt;ctr++) {
    if (((*comb_arr)[ctr]&0x00FFFFFF) > ((*comb_arr)[ctr+1]&0x00FFFFFF)) {
      //Here a swap is needed
      temp=comb_arr[ctr+1];
      (*comb_arr)[ctr+1]=(*comb_arr)[ctr];
      (*comb_arr)[ctr]=temp;
    }
  }      
}   

void main (void){
float period=0;
float fixval=0; 
int1 config=0;
int16 LPRwdt=200;
int16 OVRwdt=200;
int16 SYNCwdt=200;
int8 Freq=50;
int8 ctr=0;
int32 temp;
  while (true){
    if (!config){
 
       iarray[0]=0; //SYNC
       iarray[1]=500; //LPR
       iarray[2]=200; //OVR
      
       iarray[0]|=0x10000000; // set SYNC ID bit
       iarray[1]|=0x20000000; // set LPR ID bit
      iarray[2]|=0x40000000; // set OVR ID bit
     
      // Bubble sort offset times
      bubblesort(OFFSET_ARR_SZ, iarray);
     /** calculate timer value for frequency **/
      period=1/(float)Freq;       
      timval=65560-(CALC*(1/(float)Freq));
      /** calculate timer values for pulse widths **/
      fixval=1/((float)FREQMHZ/4/16);
      LPRval=LPRwdt/fixval;
      OVRval=OVRwdt/fixval;
      SYNCval=SYNCwdt/fixval;
      fprintf(DEBUG, "LPRval %d\r\n",LPRval);
      fprintf(DEBUG, "OVRval %d\r\n",OVRval);     
      fprintf(DEBUG, "SYNCval %d\r\n",SYNCval);
     
      // extract offset delays
      delay[0]=iarray[0]&0x0FFFFFFF;
      delay[1]=(iarray[1]&0x0FFFFFFF)-delay[0];
      delay[2]=(iarray[2]&0x0FFFFFFF)-delay[1];
      // extract offset ID
      order[0]=((iarray[0]&0xf0000000)>>28);
      order[1]=((iarray[1]&0xf0000000)>>28);
      order[2]=((iarray[2]&0xf0000000)>>28);
     
      //setup timers
      setup_timer_3(T3_INTERNAL | T3_DIV_BY_4 ); // Setup timer for OVR LL pulse
      setup_timer_4(T4_DIV_BY_16, OVRval, 1); // Setup timer for OVR LL pulse
      setup_timer_6(T6_DIV_BY_16, SYNCval, 1); // Setup timer for SYNC pulse
      setup_timer_8(T8_DIV_BY_16, LPRval, 1); // Setup timer for LPR LL pulse
      // enable interrupts
     enable_interrupts(INT_TIMER3);     //enable timer3 (16bit) interrupt to set OVR LL
     enable_interrupts(INT_TIMER4);     //enable timer4 (8bit) interrupt to reset OVR LL
     enable_interrupts(INT_TIMER6);     //enable timer6 (8bit) interrupt to reset sync
     enable_interrupts(INT_TIMER8);     //enable timer8 (8bit) interrupt to reset LPR LL
     enable_interrupts(GLOBAL);
      config=1;
   }   
  }     
}
//------------------------------------------------------------------------------

#INT_TIMER3 HIGH
void TIMER3_isr() {
      set_timer3(timval); 
      /** start "reset timers" in correct order **/
      if (order[0]==0x1){
        long_delay_us(delay[0]);
        output_high(MCU1_SYNC);
        setup_timer_6(T6_DIV_BY_16, SYNCval, 1);
      } else if (order[0]==0x2){
        long_delay_us(delay[0]);
        output_high(LL_LPR);
        setup_timer_8(T8_DIV_BY_16, LPRval, 1);
      } else if (order[0]==0x4){
        long_delay_us(delay[0]);
        output_high(LL_OVR);
        setup_timer_4(T4_DIV_BY_16, OVRval, 1);
      } else
        fprintf(DEBUG"ERROR starting first timer0x%8x\r\n",(iarray[0]&0xf0000000));
      if (order[1]==0x1){
        long_delay_us(delay[1]);
        output_high(MCU1_SYNC);
        setup_timer_6(T6_DIV_BY_16, SYNCval, 1);
      } else if (order[1]==0x2){
        long_delay_us(delay[1]);
        output_high(LL_LPR);
        setup_timer_8(T8_DIV_BY_16, LPRval, 1);
      } else if (order[1]==0x4){
        long_delay_us(delay[1]);
        output_high(LL_OVR);
        setup_timer_4(T4_DIV_BY_16, OVRval, 1);
      } else
        fprintf(DEBUG"ERROR starting second timer0x%8x\r\n",(iarray[1]&0xf0000000));
      if (order[2]==0x1){
        long_delay_us(delay[2]);
        output_high(MCU1_SYNC);
        setup_timer_6(T6_DIV_BY_16, SYNCval, 1);
      } else if (order[2]==0x2){
        long_delay_us(delay[2]);
        output_high(LL_LPR);
        setup_timer_8(T8_DIV_BY_16, LPRval, 1);
      } else if (order[2]==0x4){
        long_delay_us(delay[2]);
        output_high(LL_OVR);
        setup_timer_4(T4_DIV_BY_16, OVRval, 1);
      }else
        fprintf(DEBUG"ERROR starting third timer0x%8x\r\n",(iarray[2]&0xf0000000)); 
 

}
//------------------------------------------------------------------------------

#int_TIMER4 HIGH
void TIMER4_isr()
{
  output_low(LL_OVR);
}
//------------------------------------------------------------------------------

#INT_TIMER6 HIGH
void TIMER6_isr()
{
  output_low(MCU1_SYNC);
}
//------------------------------------------------------------------------------

#int_TIMER8 HIGH
void TIMER8_isr()
{
  output_low(LL_LPR);
}
//------------------------------------------------------------------------------

Thanks for your continued support...
If this isn't the way to go and you would stick to using one timer only, how would you recommend to resolve the "reset problem" meaning,
I can bubble sort the offsets to know when to start but how would i bubble sort the width in there to properly reset the pins?
Thanks!
cerr



Joined: 10 Feb 2011
Posts: 241
Location: Vancouver, BC

View user's profile Send private message

PostPosted: Mon Mar 21, 2011 12:19 pm     Reply with quote

Okay,

I got somewhat accurate readings now, I was reguired to reset the timers to 0 whenever i call setup_timerX() and I set the ISRs 4,6 & 8 as high priority but timer3 is still low.
But still I don't get very accurate timings. I'm wondering if it's because my MCU is clocked with 10MHz "only".
If I set the pulse to be 200uS - my oscilloscope measures about 235uS which is 17.5% off... if I could achieve more accuracy, that would be awesome - i of course could put a correction factor in there (when calculating the timer values)but I don't know if that's really what i want... Also this is just a "dev project" and the final hardware will have a 20MHz oscillator...

Any hints or suggestions?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group