----- Ursprüngliche Nachricht -----
Von: Mark Rages
Gesendet am: 17 Nov 2009 22:32:59

> Before I implement my own routine, is there a standard busyloop delay
> routine for mspgcc?

Besides simple busy-loop functions (there is one in the mspgcc library), I have 
implemented a fairly accurate delay function which can delay up to 65536 
microseconds with high accuracy.
I use the Timer A (on the 54xx Timer1_A1) for a 1ms interrupt, running the 
timer at 1MHz.
So my delay function is using the CC1 (CC0 is used for the 1ms tick).
Note:
- Calling overhead is additional 4-5...@16mhz MCLK, more on slower processors.
- GIE will be enabled while waiting
- any other IRQ happening immediately after or shortly before the timer has run 
out will add to the delay.
- any other IRQ happening while waiting will NOT add to the delay.

volatile char usdelay;
void TimerDelay1us(unsigned int time){
  __asm__ __volatile__ ( "push r2"::);                                          
// save interrupt state
  _DINT();                                                                      
// disable interrupt (to allow proper setup)
  usdelay=1;
  TA1CCR2=TA1R+time+2;
  TA1CCTL2=CCIE;
  _EINT();                                                                      
// enable interrupt (to allow CCI take place)
  while(usdelay);
  TA1CCTL2=0;
  __asm__ __volatile__ ( "pop  r2"::);                                          
// restore original interrupt state
}

interrupt(TIMER1_A1_VECTOR) timera1x_handler(void){
  __asm__ __volatile__("add       %[src]       ,r0       ":: [src] "m" (TA1IV));
  __asm__ __volatile__("reti                         "::); // NO INT
  __asm__ __volatile__("jmp   timera1_cc1_handler    "::); // CC1
  __asm__ __volatile__("jmp   timera1_cc2_handler    "::); // CC2
  __asm__ __volatile__("reti                         "::); // RESERVED
  __asm__ __volatile__("reti                         "::); // RESERVED
  __asm__ __volatile__("reti                         "::); // RESERVED
  __asm__ __volatile__("reti                         "::); // RESERVED
  __asm__ __volatile__("jmp   timera1_ifg_handler    "::); // IFG
}
interrupt(NOVECTOR) timera1_cc1_handler(void){} // currently unused
interrupt(NOVECTOR) timera1_cc2_handler(void){  // TACC2 used for µs timer delay
    usdelay=0;
}
interrupt(NOVECTOR) timera1_ifg_handler(void){}



Of course this is a LOT of effort if you don't need any precision. But if you 
do, it's far better than any variable-decrementing busy-loop and has a wide 
operating range of up to 65 milliseconds.

JMGross

Reply via email to