Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

interrupt and __delay_ms()

Status
Not open for further replies.

nikouz

Newbie level 6
Joined
Feb 5, 2021
Messages
14
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
115
Hi all
I am new as you already know. Doing lecel 6 in automation & electronics. I am using MPLABX and XC8. The PIC we working on is 16F88 or 16F1829(i know they are ages back but use them only for the MPLAB) personaly i run all our LAB exercises on curiosity board with 16F18446.
Before upload codes and fault pics and makes everyone crazy i will ask a question: Can we have an interrupt to execute code with __delay_ms() function. For being
more accurate i am typing a simple code as example:

for(i=0; i<5; i++){ RB1 = 1; __delay_ms(15000); RB1 = 0; __delay_ms(15000); }


Thank you for your time
 
Last edited by a moderator:

There is nothing to stop you using delays in interrupts and it will compile but it is bad programming to do so. The problem is that the delay routines work by running loops within loops to use up the time and then return. When you enter an interrupt on those devices the GIE bit is automatically reset until the interrupt routine ends then it is turned back on. That means no further interrupts can be processed until the current one is finished so delaying the return may mean other interrupt triggers are missed.

A better method is to use a timer to create interrupts periodically, for example TMR1 to create interrupts every 100mS then count the interrupts to create the delay you want. Using that method allows the program to continue execution until the delay time is reached, even if you are not doing anything else at the same time.

Brian.
 
  • Like
Reactions: nikouz

    nikouz

    Points: 2
    Helpful Answer Positive Rating
There is nothing to stop you using delays in interrupts and it will compile but it is bad programming to do so. The problem is that the delay routines work by running loops within loops to use up the time and then return. When you enter an interrupt on those devices the GIE bit is automatically reset until the interrupt routine ends then it is turned back on. That means no further interrupts can be processed until the current one is finished so delaying the return may mean other interrupt triggers are missed.

A better method is to use a timer to create interrupts periodically, for example TMR1 to create interrupts every 100mS then count the interrupts to create the delay you want. Using that method allows the program to continue execution until the delay time is reached, even if you are not doing anything else at the same time.

Brian.
thank you for the answer. Also the info very usefull. I was experimenting only with few thinks on interrupts to get a knowledge of how to code few thinks.I manage now to run the small code.The problem was that i had to define again the external clock in the interrupt.c file to run the __delay_ms(). I was experimenting with the extern declarations. Thank you any way quick and good answer.All the best.
 

Hi
Yes. You can create a "delay_ms()" or "timer " to turn off and on "RB1".

If your program is just this "FOR" loop, it is not a problem and with "delay_ms()" you can control how long the "RB1" is on and off.

But if you have a program, loop, or line other than this loop "FOR":
An "delay_ms()" delay causes the program to run for several minutes in the same loop, and the next line of the program does not run until the loop is completed.
If you use a timer, the timer and the line of other programs are performed consecutively, and whenever the timer overflows and the time you want arrives, then the "RB1" turns off or on. In this way, the whole program does its job and is not delayed.
 
Hi,

Or you use the PWM periferal and need no processing power at all. The processor may sleep 100% of the time.
It it will be as precise as your clock.

Whether you can/should use one or the other method depends in your requirements.
Using delay_ms is the worst of all. Worst regarding processing power and worst regarding accuracy and precision.
I'd say I almost never use it in main loop and even less in ISRs.
Only where other methods are not useful.

Example: Building an almost precise hour/minutes clock is impossible with delay_ms.
But using timer_periferals and ISRs will make it stable and precise.

Klaus
 

Hello Nikous, As an effort to help, i am doing that right now too in STM32F407
Intrrupt delay as i see it acts as following.
you have a counter which counts up every clock cycle defined by the periphery.
you are defining it to call interrupt function when the counting reaches its upper boundary.

then you define how many count overrun you want to reach and that is your delay.
Then delay function is stuck on the myticks<us while the myticks variable keeps climbing up every time the timer reaches it counting limit.
The heart of the STM32 code shown bellow describing the proccess.
Code:
    void delay(int us)
    {
        TIM4->CR1|=TIM_CR1_CEN;
        myticks=0;
        while(myticks<us);
        TIM4->CR1&=~TIM_CR1_CEN;
           
    }
void TIM4_IRQHandler(void)
{
    myticks++;
  TIM4->SR&=~TIM_SR_UIF;
}  
int main(void)
{
    RCC->APB1ENR|=RCC_APB1ENR_TIM4EN;
    TIM4->PSC=0;
    TIM4->ARR=21;
    TIM4->CR1|=TIM_CR1_URS;
    TIM4->DIER|=TIM_DIER_UIE;
    TIM4->EGR=TIM_EGR_UG;
    NVIC_EnableIRQ(TIM4_IRQn);
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top