This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

HOW TO IMPLEMENT DEALY IN CODING

I have written code for sensing input and then output port to respond. I want to add delay between the two actions. Can any one help me out.

  • Have you no ideas of your own?

    Like time-stamping the change of the input and in your loop decide if enough time have passed for the output to toggle too?

    Or implementing a "delay chain" where you sample the input at a fixed speed and store in an n step long ring-buffer and every time you insert a new input sample into the ring buffer you take out an old sample and use to control the output - multiple pulses in the input will then repeat as the same number of pulses on the output, but delayed based on the length of this delay chain.

    Or change the "delay chain" to only store actual changes of the input with state+time and constantly peek the tail of the chain to see if it's time to extract and execute a change to the output.

  • It is a Infineon SAB 80C517 with a ARM core.

    will you send me code for delay chain.

  • I can provide a solution for a Cortex-M3 architecture but you only said ARM (generic)

  • Function init_delay() enables internal Cortex-M3 to count processor cycles
    Function delay() waits for the desired processor cycles

    #include <RTL.h>
    
    volatile U32 *DWT_CTRL    = (U32 *) 0xE0001000;         // Data Watchpoint and Trace counter register Control Register
    volatile U32 *DWT_CYCCNT  = (U32 *) 0xE0001004;         // Data Watchpoint and Trace counter register Cycle Count Register
    volatile U32 *SCB_DEMCR   = (U32 *) 0xE000EDFC;         // address of the register
    
    
    #define TRCENA                          (1<<24)
    
    void init_delay(void)
     {
      *SCB_DEMCR = *SCB_DEMCR | TRCENA;
      *DWT_CTRL = *DWT_CTRL | 1;
     }
    
    void delay(U32 cycles)
     {
      U32 tmp = *DWT_CYCCNT + cycles;
    
      while(*DWT_CYCCNT < cycles) {}
     }
    
    

  • Correction:

    void delay(U32 cycles)
     {
      U32 tmp = *DWT_CYCCNT + cycles;
    
      while(tmp < cycles) {}
     }
    

  • My bad, correction again:

    Correction:
    
    void delay(U32 cycles)
     {
      U32 tmp = *DWT_CYCCNT + cycles;
    
      while(*DWT_CYCCNT < tmp) {}
     }
    

  • "It is a Infineon SAB 80C517 with a ARM core."

    It seems the 80C517 has been suddenly quite modernized. For a good many years, it had a 8051 core...

  • Don't you think you need even further corrections than the following?

    void delay(U32 cycles)
     {
      U32 tmp = *DWT_CYCCNT + cycles;
    
      while(*DWT_CYCCNT < tmp) {}
     }
    

    What if DWT_CYCCNT + cycles overflows, resulting in tmp being set to a value less than DWT_CYCCNT? How long will your delay become then?

    That is of course if DWT_CYCCNT has the same numeric range as your U32. If it has less range, then tmp can be set to a value that is larger than DWT_CYCCNT can ever reach, which can cause an infinite delay.

    It doesn't hurt to make a full analysis of written code, to check all boundary cases, and figure out if the code can always be trusted or if there might be situations not covered.

  • "What if DWT_CYCCNT + cycles overflows, resulting in tmp being set to a value less than DWT_CYCCNT? How long will your delay become then?"

    You can reset the register at first

  • But if the register is reset, then it can't be used by other parts of the code that might need to measure time. It's quite common to busy-loop short delays, but using a free-running timer and potentially a timer interrupt to keep track of longer delays or for measuring the time between two events.

    Isn't it much better to rewrite the code so it doesn't matter if DWT_CYCCNT overflows during the delay?