Delay_us() is not accurate

mikroC, mikroBasic and mikroPascal PRO for Microchip’s 8-bit PIC MCUs.
Post Reply
Author
Message
Lane_srb
Posts: 3
Joined: 11 Jul 2019 07:40

Delay_us() is not accurate

#1 Post by Lane_srb » 01 Sep 2019 15:10

Hi everyone!

I am trying to make Delay_us(4), but when I run it and test it with simple led blinking it blink around 500ms it is not exactly 500ms. But when I try with Delay_ms(500) I have no issue, did anybody know the reason? The reason why I need so small delay is because I try to make sin wave with maximum of 1kHz.

Code:

Code: Select all

long int wait = 0;

void main() {
 //*****************************
 OSCCON = 0b01110111;
 OSCTUNE = 0b10000000;
 //*****************************

 TRISD = 0x00;
 ANSELD = 0x00;
 
 LATD.B0 = 1;
 
 while(1){
  wait ++;
  if(wait == 125000 ){
    LATD.B0 = ~LATD.B0;
    wait = 0;
  }
  Delay_us(4);
 }
}

User avatar
jovana.medakovic
mikroElektronika team
Posts: 986
Joined: 18 Dec 2018 10:36

Re: Delay_us() is not accurate

#2 Post by jovana.medakovic » 02 Sep 2019 09:03

Hello,

Can you tell me which MCU you are using?
Also, can you zip and send me your project?

Kind regards,
Jovana

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Delay_us() is not accurate

#3 Post by janni » 02 Sep 2019 14:00

Lane_srb wrote:I am trying to make Delay_us(4), but when I run it and test it with simple led blinking it blink around 500ms it is not exactly 500ms. But when I try with Delay_ms(500) I have no issue, did anybody know the reason?
The reason is quite obvious - code execution takes time. When the time is comparable with delay, it cannot be neglected.

Lane_srb
Posts: 3
Joined: 11 Jul 2019 07:40

Re: Delay_us() is not accurate

#4 Post by Lane_srb » 02 Sep 2019 16:49

Tnx for replies!

I am using PIC18F45K22 with 16MHz internal oscillator. I have attached the project file.
janni wrote:
Lane_srb wrote:I am trying to make Delay_us(4), but when I run it and test it with simple led blinking it blink around 500ms it is not exactly 500ms. But when I try with Delay_ms(500) I have no issue, did anybody know the reason?
The reason is quite obvious - code execution takes time. When the time is comparable with delay, it cannot be neglected.
So you think that the delay of 4uS is to fast? I have also tried with TMR0 to measure the 4uS, but in this case I used internal oscillator of 8MHz and I have calculated that one cycle for TMR0 is 1uS(FOSC/4, 1:2 prescaler ), and then TMR0 = 256 - 4 +2 to get 4 cycle, is my calculation correct?

Also I have question about calculating TMR0, if TMR0 goes from 256 to 0 and looking at my calculation TMR0 will start from 254, right? I need to ask that because that confuse me a little bit. If I am right then I made a bad calculation :D
Attachments
Led_blink_example.rar
(29.04 KiB) Downloaded 64 times

User avatar
jovana.medakovic
mikroElektronika team
Posts: 986
Joined: 18 Dec 2018 10:36

Re: Delay_us() is not accurate

#5 Post by jovana.medakovic » 03 Sep 2019 08:58

Hello,

If you want to use delay_us(4) and if statement, your code will execute comparison 125000 times with delay and as @janni told - code execution takes time. However, if you use delay_ms(500), your code will only wait 500ms and after that execute the code. Because of that, the first case is not precise.

Regarding the timer interrupt, I recommend you to use our Timer Calculator, it will help you.

Kind regards,
Jovana

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Delay_us() is not accurate

#6 Post by janni » 03 Sep 2019 13:03

Lane_srb wrote:So you think that the delay of 4uS is to fast?
That depends on processor clock. If instruction cycle execution time is comparable with delay then accurate delays may not be possible. And they can hardly be accurate without using interrupts.
I have also tried with TMR0 to measure the 4uS, but in this case I used internal oscillator of 8MHz and I have calculated that one cycle for TMR0 is 1uS(FOSC/4, 1:2 prescaler ), and then TMR0 = 256 - 4 +2 to get 4 cycle, is my calculation correct?
Not exactly - writing to TMR0 register causes 2-cycle break in counting, i.e. 1us at 8MHz clock so one timer count, not two. Timer0 is not best for repeated operations and requires too much overhead (reloading) for so short delays. Timer2 is much better for equidistant interrupts. Also 8MHz clock is too slow for 4us interval. Doing anything sensible in ISR (Interrupt Service Routine) will use some execution time and you'll want your main code to have time to execute, as well. I don't think anything less than 32MHz will do in your project - and that's assuming only very short ISR.

Lane_srb
Posts: 3
Joined: 11 Jul 2019 07:40

Re: Delay_us() is not accurate

#7 Post by Lane_srb » 03 Sep 2019 23:50

jovana.medakovic wrote:Hello,

If you want to use delay_us(4) and if statement, your code will execute comparison 125000 times with delay and as @janni told - code execution takes time. However, if you use delay_ms(500), your code will only wait 500ms and after that execute the code. Because of that, the first case is not precise.

Regarding the timer interrupt, I recommend you to use our Timer Calculator, it will help you.

Kind regards,
Jovana
Thanks for this calculator! I used this calculator with configuration : PIC18F, MCU clock 64MHz, for 4uS interrupt time and I get TMR0 preload= 192. When I used formula from previous post I get TMR0 preload 194, why in this calculator what you send me not calculate 2 cycle delay for TMR0?

Is execute time of 125000 calculated value or some fixed value? And if I use 64MHz MCU clock execute time for code will be the same or not?

And again, thanks for replying and helping me to understand this!

Post Reply

Return to “PIC PRO Compilers”