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
}
已解决! 转到解答。
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
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 .
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
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.
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
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:
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
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
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
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.
B.R
Weiping
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
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.