Hi all,
I am a beginner to freescale microcontrollers. Right now i'm trying to make a delay function that can be used to build an LCD function. I have succeeded in making a millisecond delay, but for some reasons i don't understand, the microsecond delay is not working.... seems like it's trapped. BTW, i check it by turning a led on and turn it off while at the same time turning another led after delaying it for 1000 us, and then turn it off and turn the first one after the same delay time. It all done in a while(1) loop. To my eyes, it should look as if the two leds are turned on.
here is my code
----on main module-------------
extern uint16_t flag;
void delay_ms(uint32_t delay) {
TI1_Enable();
TI1_EnableEvent();
TI1_SetPeriodMode(0);
while(delay!=0){
if(flag){
delay--;
flag = 0;
}
}
TI1_DisableEvent();
TI1_Disable();
}
void delay_us(uint32_t delay) {
TI1_Enable();
TI1_EnableEvent();
TI1_SetPeriodMode(1);
while(delay!=0){
if(flag){
delay--;
flag = 0;
}
}
TI1_DisableEvent();
TI1_Disable();
}
I use TimerInt with runtime setting type : from list of values. Mode 0 has 1ms period and mode 1 has 1us period. In addition, i use TPM12 for periodic interrupt source
-----------On Event------------------------------
uint16_t flag = 0;
void TI1_OnInterrupt(void)
{
/* Write your code here ... */
flag = 1;
}
FYI, i am using CodeWarrior v6.3 and MC9S08AW60
Thanks in advance
已解决! 转到解答。
Variables shared with an ISR must be volatile, or the compiler may produce completely random program behavior through optimizations, as it doesn't realize that the variable may be altered at any moment.
if I understand what you are trying to do.
1 uSec turn on LED 1 and then back off - - - for a short 1 uSec on time
then delay for 1 mSec with LED 2 turned on and then back off.
If I get this right LED 1 will only be on for 0.1% of the time - - thus most likely not visible - - - oops.
as in a very very short flash with so little on time that it will not be visible
Jim P
Variables shared with an ISR must be volatile, or the compiler may produce completely random program behavior through optimizations, as it doesn't realize that the variable may be altered at any moment.
Wooow... the replies come so quickly.... Thanks for the replies!!
@kef :
So, in your opinion it is practically impossible? But, i need the microsecond delays...
@ Lundin :
So i just have to declare it as volatile? Hmmm, i assume i should put the declaration in events.c. Is that right? Is it gonna work? Mr kef there says it is practically impossible
@BlackNight
Thanks a lot! I guess i can still update it using Processor Expert >> Update >> Update from package
BTW, how can i enable Delay100US? Oh, and can i use the wait1.h for ColdFire Microprocessor too?
Possible, if you set up your bus clock for top speed and code your ISR without intermediate Processor Expert layers. Still this will eat all CPU time and probably produce wrong delays. 1us periodic interrupt just to keep your 1us clock counter? Clear that's wrong idea.
Possible, if you set up your bus clock for top speed and code your ISR without intermediate Processor Expert layers. Still this will eat all CPU time and probably produce wrong delays. 1us periodic interrupt just to keep your 1us clock counter? Clear that's wrong idea.
Hmmm... i get your point... Honestly, i have thought that i got the problem because 1 us periodic interrupt made the CPU extremely busy, but i haven't got any other way to produce microsecond delay. Oh, and i don't want the counting method either, as i think it has poor precision. Can you give me advice of how i can get microsecond delays?
Thanks a million for your help
1) It will have poor precision when CPU will be too busy to handle periodic interrupt on time. 2) while loop cycle in your wait routine should take much less time than timer interrupt period, else it will fail counting timer ticks. Even if it looping faster than 1us interrupt, you should have some spare time to let your product doing something useful. Add and service yet another interrupt source and you will miss interrupt periods.
Make timer running. Use timer counter as a clock reference. Simplest case, timer is free running and overflows past 65535 to 0:
void delayNticks(short N) // delay N timer ticks, N=0..32767
// replace counter with timer counter register
{
short t0;
t0 = counter+N-1;
while ((signed short)(t0-counter) >= 0)
{
}
}
Hello,
I would presume that the real requirement here is to generate a delay period with microsecond resolution, rather than a delay period of one microsecond. It would appear that the OP was considering a delay based on timer ticks of 1 us, with the implication that there would be one interrupt per tick.
An alternative way of achieving the required resolution, with a single interrupt only at the expiry of the delay period, is to utilize output compare mode for a TPM channel. However, for software output compare mode, there will always be timing inacuracy due to setup and activation of the delay, and latency of interrupt processing at the conclusion of the delay. A correction can sometimes be applied to eliminate some of this inaccuracy, but there will be a minimum allowable delay period.
Polling the channel flag, rather than using interrupts, may reduce the timing uncertainty, but here interrupts would need to be globally disabled during the delay period (probably not an issue for a delay of a few microseconds). Best accuracy, with usually few latency issues will be achieved using the hardware output pin for the TPM channel, but this may not be appropriate for many applications.
What timing precision is actually required? The original indication was that the delays were required for a LCD function. For alphanumeric LCD modules with integral 8-bit or 4-bit parallel interface, the delay periods are usually not too critical, provided minimum delay requirements are met.
Regards,
Mac
As you are using Processor Expert, you might use the attached component (in MCU10.1 you can simply can import it using the menu Processor Expert > Import Package. Restart eclipse and you have a 'Wait' component available which allows you to wait for a specified time. It is using busy waiting and not a timer, so useful for a smaller waiting time, and I'm using it as well for things like in an LCD driver.
#include "WAIT1.h"
WAIT1_Waitms(5); /* wait for 5 ms */
WAIT1_Waitus(10); /* wait for 10 us */
and so on.
You might need to enable the Delay100US() method in your CPU component as well.
BK
Did you setup TI1_OnInterrupt to happen every microsecond, at 1MHz rate? That's quite ambitious even for 100MHz microcontroller. All CPU bus cycles are burnt jumping to ISR, then doing some PE code, then jumping to TI1_OnInterrupt, then returning from ISR and immediately reentering it, and again and again the same.