I am working with a STM8 timer (not my code, but maintaining it) and in it it uses a timer. Apparently the clock is set at 16MHz erfo 0.0625uS. The settings of the timer are ARRH=0x03 ARRL=0x20 therefore (0x0320=800) it resets at 800 (ergo 50us)
PSCR is set at 0 so the timer has the same freq as the micro.
Anyway, when checking this with an oscilloscope, it does not give good readings.
The timer interrupt is called at:
56us , 54uS, 54uS, 52uS, 52uS, 52us, 38us(!!!), 42us(?), 50us, 50us....
curiosly summed up it gives 500uS so it does count as 10 times 50uS
The first 8 times at the timer interrupt some AD conversion is happening so there is the possibility that an AD interrupt is being called in between too.
1) Do you think this is affecting the frequency of the timer?
2) why does it "correct" itself by firing an interrupt at 38uS??
I would appreciate any comment based on your embedded or STM8 experience, since I know precise answers would need to examine the code...
I'm not sure if you still need an answer. I once had the same and searched for a long time... simple solution in my case:
I had an ADC ISR with high jitter. That came from my main loop. In some sub-sub-sub routine the ADC interrupt was temporarily deactivated for a critical section (data transfer between interrupt and main loop context). The effect is exactly what you discribe:
Sometimes the time between two interrupts is longer, because the interupt is pending and waiting for execution until the interrupt is enabled again. The timer is still continuing to run. Timing example:
interrupt is disabled in main loop (or sub routine)
interrupt flag is set by timer -> interrupt pending
interrupt is enabled again -> ISR is executed too late
interrupt is disabled in main loop
interrupt flag is set by timer -> pending
interrupt is enabled again -> ISR is executed much too late
main loop does NOT disable interrupt for some case (maybe by control flow, maybe timing issue)
The next interrupt is executed at the right time which is 50 us after raising the last interrupt, NOT 50 us after calling the last ISR. --> time between ISR calling is shortened.
I hope I could help.
Related
I've got an issue with STM32F0 timers. I'm doing everything register level and am disabling a timer and zeroing the count. After this I re-enable external interrupts and restart the timer on receipt of an edge.
It seems though that it the interrupt happens very soon after the count has been written, the zeroing does not take place.
I'm wondering if there is a delay when writing to the counter. I wonder if there would have to be at least one pre-scaled clock cycle?
so i'm using an STM32F4 based bare bone board (Black Pill) to run a program for my project
i m using the STM32CubeIDE for code generating
Current Overtime cases explanatory
the figure you just saw, is a graph i made simply on paint to explain the post
my project revolve around inductance load protection against short circuits, (doesn't matter but just clarification)
i m using interrupts, where the first interrupt triggers once the current reaches a reference 1 value
second interrupt triggers once the if reaches Value Reference 1
since current noises can't be filtered in my case, I have to avoid the triggering of instruction of int 2
there for I put a delay that is a bit bigger then the noise period (about 100ns)
if delay ended and int trigger is still on (high) , shut down the system (change the output)
if delay ended and int trigger is off (low), keep the system running (keep initial output)
this is the code i came up with so far
enter code here
I believe what you're looking for is a "Timer" and some interrupt handling magic. I will expand a little.
If your interrupt is OFF (in NVIC only, the rest is configured), but an interrupt triggering event occurred, the interrupt will NOT fire (obviously). But if you enable the interrupt in NVIC after that, it will fire immediately.
Example:
You set up a GPIO as input, you setup EXTI (external interrupt) and SYSCFG (binding port to EXTI), basically, you make a rising edge interrupt
In NVIC the corresponding interrupt is OFF
Rising edge happens on GPIO, immediately goes back down to LOW
You enable an interrupt in NVIC
Interrupt fires (even if the input never had a rising edge after NVIC interrupt was turned on)
My idea is the following.
In the interrupt 1 handler, you do 2 things.
Disable interrupt 2 in NVIC
Launch a delay via Timer with interrupt.
When interrupt 1 fires, it immediately disables interrupt 2 and enables timer. The timer eventually fires its own interrupt, where it enables interrupt 2 in NVIC. If interrupt 2 event happened, the interrupt 2 handler will be called immediately. If not, interrupt 2 will not fire.
During all this waiting your MCU is free to do whatever it wants, full interrupt implementation.
I am working with Cortex M3 ARM processor.So, I have a main loop like this;
while(true){
foo();
System_Watchdog_Refresh();
__ASM("wfe");//System wait for event...
}
So, manufacturer company said to me this;
If you don't want to reset your program from wdt(Watchdog Timer), you should set a empty timer ISR for every 1 ms.
There is problem for me here because ı have used "System_Watchdog_Refresh();" function and yeah processor running this function every loop.How watchdog timer reset the processor in this state?
Note that:
System_Watchdog_Refresh(): Reset wdt timer
Wdt can't be disable
foo() function doesn't matter for this state
When ı remove "__ASM("wfe");" processor doesn't reset from wdt
Thank you...
WFE sets the processor to standby until the next interrupt (or event). So even though you refresh the watchdog, the processor goes to sleep immediately after that and in the absence of any other events, stays in that state until the watchdog expires and resets the processor. To prevent that, you will need something that periodically triggers an interrupt (like an empty timer that the manufacturer suggests) to ensure the processor wakes up and resumes execution, thereby also refreshing the watchdog.
The timer interval should be something reasonably close to, but much less than, the watchdog timeout to ensure you get the ideal mix of power-saving and reliability.
(Moved my comments to an answer, since the OP says it works for him.)
Let say an interrupt (interrupt 1) happens while I am in an ISR for another interrupt (interrupt 2) with the same or higher priority. Then before exiting the current ISR, I clear the interrupt flag of interrupt 1. Will the interrupt handler of interrupt 1 still be executed or interrupt 1 will be ignored?
For context, I am using STM32 microcontroller.
Thank you
AFAIK from the past experience of other CPUs, you loose the interrupt.
In such a case before clearing the interrupt 1 flag:
simply read the interrupt 1 flag bit and store it temporarily
clear the interrupt flag (in some CPUs reading it, clears it automatically)
at the end of the interrupt 2 check the stored bit
if it is not set, just leave interrupt 2 routine
if it is set and both interrupts have same priority (or it does not matter!):
just jump/call the other interrupt 1 routine ("stay" in interrupt 2 routine execution)
if it is set and interrupt 1 has not the same priority and you really have to assign it the proper one:
then it gets difficult, here some options:
once I forced the cpu to trigger an other unused interrupt 3 of the same priority like interrupt 1, so using interrupt 3 to execute "interrupt 1" routine
build the interrupt priority handling in code as far as you need it and can, using above trick and more...
PS: This should be described in the manual of the processor, whether clearing the interrupt bit will loose its execution - mostly yes, the interrupt bit is simply a "interrupt pending" bit. It's sometimes not easy to find the description, but daily business.
I don't much about how watchdog timer works in embedded environment and I am facing issue related to watchdog timer
Maximum time out value defined in one of the macro is 55 and when we try to set up this value from watchdog_set_period function ,our board is getting reboot
#define Max_time_out 55
watchdog_set_period(int period) // Set watchdogs timeout counter
where period = 55
Now is it something expected or how what is the reason for reboot
We are writing this period value to some driver which we are accessing through file descriptor.
The link states this description on watchdog timers.
A watchdog timer is a piece of hardware that can be used to automatically detect software anomalies and reset the processor if any occur. Generally speaking, a watchdog timer is based on a counter that counts down from some initial value to zero. The embedded software selects the counter's initial value and periodically restarts it. If the counter ever reaches zero before the software restarts it, the software is presumed to be malfunctioning and the processor's reset signal is asserted. The processor (and the embedded software it's running) will be restarted as if a human operator had cycled the power.
You haven't posted the code so we can't judge what exactly is the problem. If you have written the code check if your code is causing any problems which is causing the watch dog timer to reset.
A watchdog timer is a special kind of timer usually found on embedded systems that is used to detect when the running software/firmware is hung up on some task. The watchdog timer is basically a countdown timer that counts from some initial value down to zero.
When zero is reached, the watchdog timer understands that the system is hung up and resets it.
Therefore, the running software must periodically update the watchdog timer(in a infinite while loop) with a new value to stop it from reaching zero and causing a reset. When the running software is locked up doing a certain task and cannot update(refresh fails) the watchdog timer, the timer will eventually reach zero and a reset/reboot will occur.
So in summary, if you enable watchdog timer then you need to periodically refresh watchdog timer. Otherwise the board reboots when the watchdog timer expires.