2 Timerinterrupts with HC908QY4A; Wrong Time?? Beginner-Problem?

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2 Timerinterrupts with HC908QY4A; Wrong Time?? Beginner-Problem?

3,492件の閲覧回数
mojo
Contributor I
Hi all
(:smileyhappy: my first post)
 
I tried to program two timer interrupts.
Busclock 3.2MHz
Timer 0 : 16us (15.938us)
Timer 1 : 4096us (4095.958us)
 
I use Codewarrior / Processor Expert.
 
If I only program Timer0 with 16us (Timer1 unused), the InterruptTimer0 comes every 16us, which is ok.
BUT if I use Timer0 with 16us AND Timer1 with 4096us the InterruptTimer0 comes every 20'480us??? (Timer Interrupt 1 comes every 40196us as I wish)
 
Why 20480us, not the wanted 16us??  BTW: 20480us is 5 * 4096us!
 
Please Help me! 
I am new to 8Bit-Programming/Codewarrior.
 
With Regards
Sebastian
 
ラベル(1)
0 件の賞賛
返信
4 返答(返信)

881件の閲覧回数
bigmac
Specialist III
Hello Sebastian,
 
It is not entirely clear what you are trying to do with the timer channels.  Are you trying to generate an output pulses using output compare, or perhaps a software time delay?  You will need to post the code you are using to set up the TIM module, and also the ISR code for each timer channel and the timer overflow interrupt.
 
Your problem might be because the channel 1 ISR takes longer than 16 microseconds (51 bus cycles) to complete, so the channel 0 interrupt does not get serviced quickly enough.  It may not be feasible to have such a short period between interrupts for channel 0 when other ISRs need to execute.
 
With a prescale value of 1, the timer overflow period will be 20.48 milliseconds, so the interrupt probably occurs after the timer starts a new cycle.
 
Regards,
Mac
 
0 件の賞賛
返信

881件の閲覧回数
mojo
Contributor I
Thanks a lot for your reply. :smileyvery-happy:
You have right. The ISRs takes too long. Smiley Sad
 
What I want to do:
I try to get TIM based PWMs:
- 2 PWM-Outputs
- 1 Timer for a systemclocktick, which my SW uses
- the frequency MUST be at least 200Hz -> cycle duration < 5ms
- and the resolution at least 1/250
- some inputs to control the PWMs, an ADC-Input, ext.IRQ,... (each pin is used)
 
This was my Solution:
- Channel 0 :  4096us (256 * 16us)
Each 4096us-Timerinterrupt increments my systemclocktick, starts my period (Signal High) and sets an PulseTime-counter(,which is between 0-255)
 ... of both PWMs
 
- Channel 1 : 16us
 Each 16us-Timerinterrupt decrements the PulseTime-counter and if zero the the pulse time is reached-> (Signal Low)
 ... of both PWMs
 
My idea was to have a high frequency and a resolution of 256.

BUT now I have to resign, because 16us seems impossible. I implemented my idea, but the fastest 2nd Timer I can use is 90us. (without my TimerInterrupt-Code : 50us)
I tried to quicken my 2 Timer ISRs, but the changes were marginal.
 
Please tell me, if you know a better solution for this problem!
I suspect that I am doing something wrong (design error), because my understanding of the HC08 and its compare-logic is small.
 
Sebastian
 (excuse my English)
 
 
__________________________________
Code:
ISR(tim1_Interrupt)
{
  TWREG var;                           /* Union used for correct access to the 16-bit IO register */
 var.b.high = TCH1H;                  /* Load of actual value of the compare register */
 var.b.low = TCH1L;
 var.w += CmpVal;                     /* Add value corresponding with periode */
 TCH1H = var.b.high;                  /* Store it to compare register */
 TCH1L = var.b.low;
 /* TSC1: CH1F=0 */
 clrReg8Bits(TSC1, 0x80);             /* Reset interrupt request flag */
 tim1_OnInterrupt();                  /* Invoke user event */  //...where my code is
}
 
1 ISR with a 40us Timerinterrupt (generated by Freescale Codewarrior):
void tim0_Init(void)
{
 /* TMODH: BIT15=1,BIT14=1,BIT13=1,BIT12=1,BIT11=1,BIT10=1,BIT9=1,BIT8=1 */
 setReg8(TMODH, 0xFF);                /* Set modulo register to maximal value */
 /* TMODL: BIT7=1,BIT6=1,BIT5=1,BIT4=1,BIT3=1,BIT2=1,BIT1=1,BIT0=1 */
 setReg8(TMODL, 0xFF);                
 /* TSC: TOF=0,TOIE=0,TSTOP=1,TRST=1,??=0,PS2=0,PS1=0,PS0=0 */
 setReg8(TSC, 0x30);                  /* Set up (output) compare mode */
 /* TSC0: CH0F=0,CH0IE=0,MS0B=0,MS0A=1,ELS0B=0,ELS0A=0,TOV0=0,CH0MAX=0 */
 setReg8(TSC0, 0x10);                 
 SetCV((word)0x007F );                 /* Store appropriate value to the compare register according to the selected high speed CPU mode */
      //(0x007F = 128d-1 => 128* (1/3,2MHz) = 40us
 
 /* TSC: TRST=1 */
 setReg8Bits(TSC, 0x10);              /* Reset counter */
 /* TSC0: CH0F=0 */
 clrReg8Bits(TSC0, 0x80);             /* Reset request flag and */
 /* TSC0: CH0IE=1 */
 setReg8Bits(TSC0, 0x40);             /* enable Compare interrupt */
}

ISR(tim0_Interrupt)
{
 TWREG var;                           /* Union used for correct access to the 16-bit IO register */
 var.b.high = TCH0H;                  /* Load of actual value of the compare register */
 var.b.low = TCH0L;
 var.w += CmpVal;                     /* Add value corresponding with periode */
 TCH0H = var.b.high;                  /* Store it to compare register */
 TCH0L = var.b.low;
 /* TSC0: CH0F=0 */
 clrReg8Bits(TSC0, 0x80);             /* Reset interrupt request flag */
 tim0_OnInterrupt();                  /* Invoke user event */
}

 Code:
My try for a quicker Timer-ISR  :ISR(tim1_Interrupt){  if (TCH0L==0){    TCH0L = 0x80;     //(=128d => 128 * (1/3,2MHz) = 40us  }else {    TCH0L = 0x00;    TCH0H++;    }  /* TSC1: CH1F=0 */  clrReg8Bits(TSC1, 0x80);             /* Reset interrupt request flag */   tim1_OnInterrupt();                  /* Invoke user event */}

Message Edited by mojo on 2006-08-28 01:11 PM

0 件の賞賛
返信

881件の閲覧回数
bigmac
Specialist III
Hello Sebastian,
 
Does your system tick have to be every 4.096 milliseconds - the idea would be to match this to the PWM cycle period of 5 milliseconds.  In this case it would seem feasible to use unbuffered PWM on each of the two TIM channels, and modify TMOD for a value of 15999 (0x3E7F), assuming a prescale value of 1, to provide the 200 Hz PWM frequency.  You could then use the TIM overflow interrupt for your tick processing.  Of course you would need to suitably scale your PWM setting for the range 0-15999.
 
Alternatively, you could increase the PWM frequency to give a period of 4.096 milliseconds, with a suitable TMOD value.
 
For unbuffered PWM you would set the TIM channel to toggle on overflow, and clear the output on each output compare.  You would need to enable the OC interrupt only when the PWM value needed to alter, to change the TIM channel register value during the ISR.  Otherwise you wouldn't need TIM channel interrupts to be enabled.
 
Would this scenario meet your requirements?
 
Regards,
Mac
 
0 件の賞賛
返信

881件の閲覧回数
mojo
Contributor I
Hi Mac

You gave me the needed hint! Thank you very much.

I had to read through the PWM-part of de manual a lot of times before I really understand how to implement my problem with the several interrupts.

But now it works satisfactorily. Thanks to you.

Greetings from Switzerland.
0 件の賞賛
返信