Microsecond Timer for HC9S12E128, 3 problems

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Microsecond Timer for HC9S12E128, 3 problems

1,470 次查看
SunFish7
Contributor I
I need to accurately wait or measure small periods of time, say 20us +- error of 5us
 
MyTimer_Reset();
:
x = MyTimer_GetElapsed_us();
 
once  I have this,  a microsecond delay routine should be easy:
void Delay_us(long us)
  MyTimer_Reset(); 
  while (MyTimer_GetElapsed_us() < us);
}
 
processor expert creates routines very close to what I need:
 
byte TimerBean_Reset(void)
{
  /* Load content of counter register to variable CntrState */
  CntrState = TIM0_TCNT; 
  return ERR_OK; 
}
byte TimerBean_GetCounterValue(word *Value)
{
  *Value = TIM0_TCNT;                  /* Return counter value */
  *Value -= CntrState;                 /* Subtract counter state */
                                       /* ... stored during last reset */
  return ERR_OK;                      
}
but it doesn't measure in microseconds;  I think it measures in jiffies.  The MCU is running at 16MHz, so that would give 16 jiffies to each microsecond.  and of course there are some overhead; Delay_us(0) is going to take up, say d_0  processor cycles.  So Delay_us(n) is equivalent  to delaying 16*n - d_0 jiffies.
 
so I put this in and test on the oscilloscope and it doesn't work properly.   the timings are always out.
 
this is the first problem.  how to code and accurate microsecond delay timer?
 
Second Problem   
while (1) PA^ = 0xff;
this creates a square wave on port A, frequency 0.5MHz.   but the process is running at 16MHz.  surely it cannot take 32 processor cycles!   I was working on an MSP430 and that took 4!  what is happening?  why  is it so slow?
 
Third Problem
I am needing to read/write binary  asynchronously to many pins.  that is why I need the above timing routines.
 
I am considering a new approach;  to poll the pins at 5us intervals.  so I need an interrupt to trigger every 5us: if there has been some activity,  it will be  queued up for processing later.
 
again processor expert generated some code that does this.   the problem is even though I specified that the interval should be 1us, I'm getting an interval of around 33us!!  is there some limitation?  I tried setting the priority to high, but that didn't change anything.  am I trying to do something unrealistic?
 
many thanks,
 
Sam
标签 (1)
0 项奖励
1 回复

350 次查看
JimDon
Senior Contributor III
What did you set up the clocks for?

It sounds like you are not setting up things correctly as far as the clock generation.

Processor expert should let you set up the PLL to get at least a 24 Mhz bus closk.

You need to use ADVANCED mode and set High Speed mode, set PLL Clock enabled, set PLL muliplicatin factor to 3, Reference divider to 2.

This is the generated code:
(note that the divider and multipler are +1)

  /*  System clock initialization */
  /* CLKSEL: PLLSEL=0,PSTP=0,SYSWAI=0,ROAWAI=0,PLLWAI=0,CWAI=0,RTIWAI=0,COPWAI=0 */
  setReg8(CLKSEL, 0);                  /* Select clock source from XTAL and set bits in CLKSEL reg. */
  /* PLLCTL: CME=1,PLLON=0,AUTO=1,ACQ=1,??=0,PRE=0,PCE=0,SCME=1 */
  setReg8(PLLCTL, 177);                /* Disable the PLL */
  /* SYNR: ??=0,??=0,SYN5=0,SYN4=0,SYN3=0,SYN2=0,SYN1=1,SYN0=0 */
  setReg8(SYNR, 2);                    /* Set the multiplier register */
  /* REFDV: ??=0,??=0,??=0,??=0,REFDV3=0,REFDV2=0,REFDV1=0,REFDV0=1 */
  setReg8(REFDV, 1);                   /* Set the divider register */
  /* PLLCTL: CME=1,PLLON=1,AUTO=1,ACQ=1,??=0,PRE=0,PCE=0,SCME=1 */
  setReg8(PLLCTL, 241);                
  while(!CRGFLG_LOCK) {                /* Wait until the PLL is within the desired tolerance of the target frequency */
  }
  /* CLKSEL: PLLSEL=1 */
  setReg8Bits(CLKSEL, 128);            /* Select clock source from PLL */



Message Edited by JimDon on 2007-07-06 09:12 PM
0 项奖励