MC9S08QG8 : Problem with a timer.

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

MC9S08QG8 : Problem with a timer.

跳至解决方案
3,826 次查看
marmor
Contributor III

I'm trying to make a program that after a minute turn off or turn on an LED.
With an 8-bit timer I want to produce a delay of one second. As I want to make a 1 minute delay , I introduce this function within a for loop,to count  60 seconds.

The system clock configuration is:

internal clock frequency: 31.25 kHz
bus frequency: 1MHz

The timer setting (MTIM)
Clock source: fixed clock frecuency, is supposed to be 15625 Hz (I don't choose bus frequency because it is too large)
Prescaler: 128
Module: 123

With this configuration, the program did not work well. The delay1s () function do not produces a delay of one second, in fact, much less time and I do not understand that, because if:
fixed clock frecuency, is supposed to 15625Hz
T = 1/15625 = 64us
64us * 128 = 8,192 ms
9,192 ms * 123 = 1.007616


MC9S08QG8 :http://www.freescale.com/files/microcontrollers/doc/data_sheet/MC9S08QG8.pdf
 

Perhaps fixed clock frequency ( clock frecuency fixed ) is not what I thought ? Then what would ?

Does anyone know why the program did not work well?


The code is as follows :


#include <hidef.h> /* for EnableInterrupts macro */

#include "derivative.h" /* include peripheral declarations */

 

 

void MCU_init(void){ /* Device initialization function declaration */

 

  SOPT1=0x00;

  SOPT2=0x00;

  ICSC1=0x04; //SETTINGS INTERNAL CLOCK SOURCE  INTERNAL REFERENCE FRECUENCY=31.25kHz

  ICSC2=0xC0;  //SETTINGS INTERNAL CLOCK SOURCE BDIV=11 0x08

  ICSTRM = *(unsigned char*)0xFFAF;    /* Initialize ICSTRM register from a non volatile memory */

  ICSSC = *(unsigned char*)0xFFAE;     /* Initialize ICSSC register from a non volatile memory */   //frec bus =1MHz

 

}

 

 

void MTIM_init(){

 

    MTIMSC=0x10;

    MTIMCLK=0x17;    // CLKS= Fixed frecuency clock  PS=128

    MTIMSC_TRST=0;   //Fixed frecuency clock suposes to be (INTERNAL REFERENCE FRECUENCY/2)=15,625kHz

}

 

void  end1s(){       // function to clear overflow flag

 

  char aux= MTIMSC;

  MTIMSC_TOF=0;

  MTIMSC_TSTP=1;

}

 

 

void delay1s(){

 

   

  MTIMMOD=122;

  MTIMSC_TSTP=0;

  while(MTIMSC_TOF==0);

  end1s();

}

 

 

void main(void) {

    int i=0;

    PTBDD_PTBDD7=1;   // lED

    PTBD_PTBD7=0;     // TURN OFF LED

 

   MCU_init();

   MTIM_init();

  EnableInterrupts; /* enable interrupts */

 

 

 

  for(i=0;i<60;i++) 

  {

  

      delay1s();

    

   

  }

   PTBD_PTBD7=1;    // TURN ON LED

 

   for(i=0;i<60;i++) 

  {

  

      delay1s();

   

  }

 

  PTBD_PTBD7=0;    // TURN OFF LED

 

  for(i=0;i<60;i++) 

  {

  

      delay1s();

        

  }

 

  PTBD_PTBD7=1;    // TURN ON LED

 

 

}


标签 (1)
标记 (2)
1 解答
3,200 次查看
Robinwithu
Senior Contributor I

Hi Maria,

I simulated your code and the following result i found on Simulation :After Initialization of your Micro controller function & Timer Module  setting when your code reach the following  function

void delay1s()

{

int k =MTIMCNT;

  MTIMMOD=122;

  MTIMSC_TSTP=0;

  while(MTIMSC_TOF==0);

  end1s();

}

at this line  while(MTIMSC_TOF==0);


I read total cycles counter ( in PEmicro Simulator tool) and it is 1007580 cycles , So as in your code we have 1Mhz clock which means 1µsec for each cycle .


1007580  X 1 = 1007580 µsec / 1000000 = 1.007580 sec which means 1 sec after first overflow and 60 x 1= 60 sec.


After 60 times in for loop  ,  i am getting 60456925 cycles After simulation.


My point is i am getting the expected result in simulation.


one more point :


for(i=0;i<60;i++) { delay1s();   }

   PTBD_PTBD7=1;    // TURN ON LED

   for(i=0;i<60;i++)  {  delay1s(); }

  PTBD_PTBD7=0;    // TURN OFF LED

  for(i=0;i<60;i++) { delay1s();}

  PTBD_PTBD7=1;    // TURN ON LED

here you can also write

for(;;)                         // it's  a forever loop

{

for(i=0;i<60;i++) { delay1s();   }

   PTBD_PTBD7=1;    // TURN ON LED

   for(i=0;i<60;i++)  {  delay1s(); }

  PTBD_PTBD7=0;    // TURN OFF LED

}

so you don't need to write ON and OFF again and again.

one more thing , in Simulation i am not able to read  MTIMCNT register it is always at 0x0000 ; do not know why it's not updating after every count, may be Simulator problem or update function not available.

I hope this answer will help you.

Thanks and Regards,

Robin

在原帖中查看解决方案

15 回复数
3,200 次查看
marmor
Contributor III

Hello.
I have been measuring with an oscilloscope , the frequency that timer uses, setting this with  the bus frequency  and the fixed frecuency .
When I configured clock timer with the clock bus I obtained about 1Mhz .
When I configured the timer clock to be the fixed frequency clock I obtained about 15KHz .

I do not know why, whenI simulated the code I did not obtain  the same results as when I tested it in the microcontroller. When I run the program in the micro, it worked right.

Conclusions I have obtained from practice:
With the FEI mode the  fixed frequency clock ( ICSFFCLK) is approximately 15625Hz .
If you select the fixed frequency clock as the timer clock, frequency will be about 15625Hz .
Selecting the bus clock as the timer clock, frequency will be about 1 MHz ( in this case) .

I wanted to thank you all for your comments and help .

0 项奖励
回复
3,200 次查看
Robinwithu
Senior Contributor I

Hi Maria,

You are welcome and Happy Programming :smileyhappy:

Best Regards,

Robin

0 项奖励
回复
3,200 次查看
iansmusical
Contributor V

Hi Maria,

Just looking at your code and I wonder if the following line:

     MTIMSC_TRST=0;  //Fixed frecuency clock suposes to be (INTERNAL REFERENCE FRECUENCY/2)=15,625kHz


Should be:


     MTIMSC_TRST=1;  //Fixed frecuency clock suposes to be (INTERNAL REFERENCE FRECUENCY/2)=15,625kHz


Also should there be a NOP in the following line to give the MCU chance to successfully update the TOF flag?


     while(MTIMSC_TOF==0);


I also wonder if it's worth stepping back a little and firstly verifying that the BUS clock is running at 1MHz before even considering what the MTIM is doing. You could toggle a pin and use an oscilloscope to measure the time etc. Once this has been ascertained the MTIM could be set to use the verified BUS clock. From this point you can build up until eventually obtaining your 1 second timeout.


Perhaps instead or starting and stopping the MTIM is it better to use the interrupt attached to the module and keep a count of the timeouts?


Hope this helps :-)


Thanks,


Ian

0 项奖励
回复
3,200 次查看
marmor
Contributor III

Hi Ian!!

Thanks for your comment.

About what you mentioned of the TRST bit , should be 1 to reset the account and put the TOF flag to 0, but neither is very important because when writing MTIMMOD (the module) the previous account is reset and the flag is cleared TOF.


About the while loop, what it does is cause a pause until the TOF flag is set to 1, then pass to the function end1s to clean TOF (which could inserting this code in the interrupt that corresponds to the timer). I I think that's fine.

Anyway, you're right, I'll try with the oscilloscope to get rid of the doubts.

0 项奖励
回复
3,201 次查看
Robinwithu
Senior Contributor I

Hi Maria,

I simulated your code and the following result i found on Simulation :After Initialization of your Micro controller function & Timer Module  setting when your code reach the following  function

void delay1s()

{

int k =MTIMCNT;

  MTIMMOD=122;

  MTIMSC_TSTP=0;

  while(MTIMSC_TOF==0);

  end1s();

}

at this line  while(MTIMSC_TOF==0);


I read total cycles counter ( in PEmicro Simulator tool) and it is 1007580 cycles , So as in your code we have 1Mhz clock which means 1µsec for each cycle .


1007580  X 1 = 1007580 µsec / 1000000 = 1.007580 sec which means 1 sec after first overflow and 60 x 1= 60 sec.


After 60 times in for loop  ,  i am getting 60456925 cycles After simulation.


My point is i am getting the expected result in simulation.


one more point :


for(i=0;i<60;i++) { delay1s();   }

   PTBD_PTBD7=1;    // TURN ON LED

   for(i=0;i<60;i++)  {  delay1s(); }

  PTBD_PTBD7=0;    // TURN OFF LED

  for(i=0;i<60;i++) { delay1s();}

  PTBD_PTBD7=1;    // TURN ON LED

here you can also write

for(;;)                         // it's  a forever loop

{

for(i=0;i<60;i++) { delay1s();   }

   PTBD_PTBD7=1;    // TURN ON LED

   for(i=0;i<60;i++)  {  delay1s(); }

  PTBD_PTBD7=0;    // TURN OFF LED

}

so you don't need to write ON and OFF again and again.

one more thing , in Simulation i am not able to read  MTIMCNT register it is always at 0x0000 ; do not know why it's not updating after every count, may be Simulator problem or update function not available.

I hope this answer will help you.

Thanks and Regards,

Robin

3,200 次查看
marmor
Contributor III

Hello

Thank you for taking the time to simulate the code.
You're right, it works as expected,I don't  know why the simulation was not working me right.

0 项奖励
回复
3,200 次查看
marmor
Contributor III

Thank you very much for your comments.

Now I understand how microcontroller clocks work.
But when I put it into practice, the counter still not working correctly.

With the code I wrote, the clock timer I selected was the fixed frequency clock(MTIM_CLKS=01b)   and the fixed frequency clock would be 1Mhz, so the for loop should produce a delay of (1/1Mhz) * 128 * 122 * 60 = 0.93696 s


for(i=0;i<60;i++) 

  {

      delay1s();

  }


128 is the timer prescaler  (MTIM_PS=111b)
122 is the timer module      (MTIMMOD=122)    
60 is i, the number of cycles of the for loop.

Knowing this, why do I get a delay of about 6s?


Furthermore, if selected as clock timer clock bus ( MTIM_CLKS = 00) and the bus frequency is 1 MHz , the loop produces a delay of less than 1s ,perhaps ms or us, do not know . What I mean is that both should produce the same delay , since its frequency is the same, and they do not.


I also try to change the bus frequency to 15625Hz :

fbus = 31.25k * 512 / (2 * BDIV *Rdiv * ) = 15625Hz .

RDIV = 64 ( ICSC1_RDIV = 110b )   ICSC1 = 0x34
BDIV = 8 ( ICSC2_BDIV = 11b )      ICSC2 = 0xC0


With this configuration , if selected as clock timer the  clock bus ( MTIM_CLKS = 00 ) and the prescaler of the timer is 128 and module 122 ,  the for loop should give a delay of (1/15625) * 128 * 122 * 60 = 59.96544s


60 is i , the number of cycles of the loop.

With this configuration I get a delay of less than 1 second.

 

What's going on ? Do not understand what I'm doing wrong.  :smileysad:

0 项奖励
回复
3,200 次查看
Robinwithu
Senior Contributor I

Hi Maria,

Again here i am sending you one Application Note based on "Clock Options on the HC9S08 Family" in which they are saying that  "The RDIV bits have no bearing if the internal reference clock is used." on Page number 3 and section 2.1.1under  "ICS FLL" first paragraph last line.

it means that RDIV is only for external reference clock in case of ICSFFCLK.

So if i will do the calculation for delay which you haven mentioned is as follows :ICSFFCLK Timing is 1µsec (cause freq. is 1Mhz)

1µsec * 128 * 122 * 60 =0.93696 sec


so it's less than 1 sec as you mentioned in your comment.is this the value you are getting ?


I hope this will help you.


With Best Regards,

Robin S

0 项奖励
回复
3,200 次查看
marmor
Contributor III

Thank you very much.

Yes, that is the value I was getting, so another question resolved!!

0 项奖励
回复
3,200 次查看
marmor
Contributor III

Can anyone help me?

0 项奖励
回复
3,200 次查看
Robinwithu
Senior Contributor I

Hello Maria,

Here is my Understanding of ICS  Fixed  Frequency Clock ( ICSFFCLK)

Actually ICSFFCLK is not 15625 Hz as you mentioned in your code.

31250 Hz (Internal Reference clock) X 512(FLL) = 16000000 Hz= 16MHz / 2 (Default)= 8Mhz

8Mhz / 8 (Bdiv) = 1Mhz

So the ICSFFCLK is 1Mhz and Not 15625 Hz.My point is ICSFFCLK is not coming directly from Internal reference source , instant of that after FLL.

Hope this will help you.

For reference of ICSFFCLK please see in Attachment AN3041.

Best Regards,

Robin

3,200 次查看
weapon
Senior Contributor I

Hi Maria,

Sorry for late response. Firstly please accept my apology for my wrong answer before. I red those decription about Fixed Clock again, I believe now I can catch the meaning.

1). In FLL engaged mode (FEI and FEE), this is always true and ICSFFE is always high --- In this case, Fixed clock is BUS clock.

2).In ICS Bypass modes, ICSFFE will get asserted for the following combinations of BDIV and RDIV values:

BDIV=00 (divide by 1), RDIV ≥ 010

• BDIV=01 (divide by 2), RDIV ≥ 011

• BDIV=10 (divide by 4), RDIV ≥ 100

• BDIV=11 (divide by 8), RDIV ≥ 101

For example, In FBI mode, ICSOUT = Internal Refrence Clock/ BDIV,  and ICSFFCLK = Internal RefrenceClock/RDIV.  You can see each BDIV and RDIV combination will result of  ICSOUT frequencies four times than the divided FLL reference clock (ICSFFCLK).

In this case, Fixed Clock is also BUS Clock.

Other cases, Fixed Clock is ICSFFCLK.

From your code, you application is using FEI mode, right?  as above analysis, Fixed clock is BUS clock = 1MHz. other word, MTIM's clock soure is 1MHz.

so we need to recalculate the modulo value. but the maximum delay get from MTIM is 256*256 = 65536us.

I recommend you to use RTI, it can generate 1 s interrupt. for detial, please refer to section 5.7 and section 5.8.7.

Hope my info is helpful.

B.R

Weiping

3,200 次查看
weapon
Senior Contributor I

Hi Maria,

As your setting, ICSFFCLK(Fixed clock freq) is 31.25KHz, I attached one picture to show you the clock path of ICSFFCLK, which is the divieded FLL reference clock.  please try to double your modulo of MTIM.

ICSFFCLK.jpg

B.R

Weiping

0 项奖励
回复
3,200 次查看
marmor
Contributor III

Another thing, I've looked at the manual and the clock frequency can be ICSFFCLK / 2 or ICSOUT / 2,depends on ICSFFE.

The manual also puts this about relj fixed frequency, even I do not understand very well.


The ICS provides the divided FLL reference clock as ICSFFCLK for use as an additional clock source for

peripheral modules. The ICS provides an output signal (ICSFFE) which indicates when the ICS is

providing ICSOUT frequencies four times or greater than the divided FLL reference clock (ICSFFCLK).

In FLL engaged mode (FEI and FEE), this is always true and ICSFFE is always high. In ICS Bypass

modes, ICSFFE will get asserted for the following combinations of BDIV and RDIV values:

   BDIV=00 (divide by 1), RDIV ≥ 010

• BDIV=01 (divide by 2), RDIV ≥ 011

• BDIV=10 (divide by 4), RDIV ≥ 100

• BDIV=11 (divide by 8), RDIV ≥ 101

system clock distribution.jpg

0 项奖励
回复
3,200 次查看
marmor
Contributor III

Hi Weiping Xu.

I changed the module as you said and does not work properly. Before, the for loop with the delay1s () function inside should produce a delay of one minute but produces a delay of 6 seconds or less and changing the value to the double produces a delay of 12 seconds or less.
I do not understand what could be wrong.

0 项奖励
回复