I just got into PIC-programming on Microchips MPLAB X IDE. My programm requires two timers. TMR4 has an interrupt interval of 500ms and TMR2 interrupts every second. When starting the program, the two timers are synced up, so within a small margin of error, when the TMR4 interrupts for the second time, TMR2 also executes the interrupt code. But when I stop TMR2 for a period of time and then start it again, the two timers are completely out of Sync.
Is there a way to resynchronize the two timers or to restart them?
Why are you stopping the timers?
There is no need to be stopped when interrupt happened. TMR2 and TMR4 are functional identical. When the interrupt is triggered the TMR2IF or TMR4IF is set. If also set TMR2IE or TMR4IE then the interrupt is triggered.
The registers PR2 and PR4 (also prescaler) must be set according to desired frequency. The value of TMR2 or TMR4 is compared to that of the period register, PR2 or PR4, on
each clock cycle. When the two values match, the comparator generates a match signal as the timer output and trigger interrupt, TMR2IF or TMR4IF is set. If also set TMR2IE or TMR4IE then the interrupt is triggered. This signal also resets the value of TMR2 orTMR4 counters to 0 and timers continue running. When you finish your interrupt program just clear TMR2IF or TMR4IF to enable next timer interrupt.
If you wont to resynchronize the timer then just reset the TMR2 and TMR4 registers value to 0. If you wont to resynchronize in main program then first disable interrupts clear TMR2 and TMR4 and enable interrupts again.
Related
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 want to solve a very particular problem with an Arduino, running on a ATmega328
I have timer1 run in fast PWM mode for generating a PWM Signal with given Period an duty cycle. The duty cycle is set by OCR1A: So at timer restart the level of the output pin gets high and after the duty period it gets low. This works.
Additionally I want to carry out an analog measurement exactly some time after the rising signal. So I enabled the OCR1B interrupt and define the time by writing to OCR1B. When the timer reaches the value in OCR1B the interrupt handler is invoked and the measurement done. This works.
Now I want to do this ADC conversion twice at different counter times, say my_OCRB1 and my_OCRB2. But there is only on OCR1B Register I can use. Is it ok to prepare the content of OCR1B to the next value my_OCRB2 after the first ADC conversion at is finished? Will it work and again rise an interrupt, when the timer is still counting up?
Is there a better solution?
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.)
Background: I am trying to make my embedded application go to sleep when there is no CAN activity with the __WFI() and then wake up whenever a CAN interrupt is received. Before enterring sleep mode, I disable all interrupts and clear their pending states in the NVIC registers.
To start, right now I'm just trying to make sure that I can sleep forever when I have all interrupts disabled.
for(int i = 0; i < IRQ_MAX; i++)
{
IRQ_ClearPending((IRQ)i);
IRQ_Disable((IRQ)i);
}
__DSB();
__ISB();
__WFI();
MCU_Reset();
I checked the NVIC registers, and they are all set to 0, which should mean that all interrupts are disabled and there are no pending interrupts. However, everytime I execture the WFI (Wait for interrupt) instruction, it will just NOP on me.
Why can I not enter sleep mode? Do I actually have to somehow disable all of my peripherals and disable the interrupts at their source or is there a way to just mask all interrupts minus the CAN?
Thank you for your time. Let me know if there is anything I can do to clarify the question.
Check for imprecise external abort, which does not cause exception immediately.
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.