• AVR Freaks

Helpful ReplyHot!PIC18F4580 timer 0 question - [SOLVED]

Page: 12 > Showing page 1 of 2
Author
Lucky Luka
Starting Member
  • Total Posts : 42
  • Reward points : 0
  • Joined: 2019/04/02 09:39:39
  • Location: Italy
  • Status: offline
2021/01/01 17:01:39 (permalink)
0

PIC18F4580 timer 0 question - [SOLVED]

Hi all
I am trying to use timer 0 to blink an LED: 1sec ON, 1 sec OFF.
I tought that using the formula in the attached pic I could have reached my goal.
I was wrong.
I obtained 1.114 sec ON and and 1.114 sec OFF.
Maybe the issue is related to what is written in the datasheet:
"If the TMR0 register is written to, the increment is inhibited for the following two instruction cycles. The user
can work around this by writing an adjusted value to the TMR0 register."
Is this the case? What values do I have to select as TMR0 in my formula? (I hope the formula is ok and the way I proceed is the one I chose... Any suggestions are welcome.)
Thanks
 
#include <xc.h>
#include "timer_header.h"
#include "stdint.h"
#include "stdbool.h"

#define LED1 LATCbits.LATC0 // Green LED
//#define LED2 LATCbits.LATC1 // Yellow LED

//#define BUTTON PORTBbits.RB0 // Button

uint16_t blink_count = 0;
//uint16_t button_count = 0;
//bool button_press = false;

// HIGH priority ISR
void __interrupt(high_priority) HPbuttonISR(void){
    // Check The Timer 0 Flag Bit
   if (INTCONbits.TMR0IF)
   {
      blink_count++;
      if(blink_count==10000) // 10000 timer overflows!
      {
        // Toggle green LED
        LED1 = ~LED1;
        // Clear The Global Counter
        blink_count = 0;
      }
      // Preload The Value To TMR1 Register Every Overflow Interrupt
      TMR0L = 55;
      INTCONbits.TMR0IF = 0; // Clear The Flag Bit
   }
}


void main(void) {
    // Configure the pins: OUT = 0, IN = 1
    TRISBbits.RB0 = 1;
    TRISCbits.RC0 = 0;
    TRISCbits.RC1 = 0;
    
    // 8MHz internal oscillator
    OSCCONbits.IRCF = 0x07;
    // Internal oscillator selected
    OSCCONbits.SCS = 0x03;
    // I wait until the oscillator's freq is stable
    while(OSCCONbits.IOFS!=1);
    
    // Timer 0 OFF
    T0CONbits.TMR0ON=0;
    // Timer 0: 8 bit
    T0CONbits.T08BIT=1;
    // Internal source clock
    T0CONbits.T0CS = 0;
    // Prescaler is bypassed --> 1:1
    T0CONbits.PSA = 1;
    // Prescaler value
    //T0CONbits.T0PS=2; //1:8
    // Preload The Value Which We've Calculated To The TMR0 8-Bit Register!
    TMR0L = 55;
    //RCONbits.IPEN = 1;
    // Enable Timer 0 interrupt
    INTCONbits.TMR0IE=1;
    // High priority for timer 0 interrupt
    INTCON2bits.TMR0IP=1;
        
    ei(); // This is like flipping the master switch to enable
          // all interrupts: it's like GIE = 1
    // Timer 0 ON
    T0CONbits.TMR0ON=1;
    
    LED1 = 0; // Switch OFF Green LED
    //LED2 = 0; // Switch OFF Yellow LED
        
    // Infinite loop
    while(1){
        
    }
            
    return;
}

post edited by Lucky Luka - 2021/01/04 09:49:07

Attached Image(s)

#1
du00000001
Just Some Member
  • Total Posts : 4120
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: online
Re: PIC18F4580 timer 0 question 2021/01/01 18:01:53 (permalink) ☄ Helpfulby Lucky Luka 2021/01/02 06:09:22
+2 (2)
Any reason for the 10 kHz interrupt (other than counting the interrupts)?
 
I'd suggest to lower the interrupt frequency by
  1. using the highest prescaler value available/practical
  2. if possible using TMR0 in 16-Bit mode
  3. using the highest applicable TMR0 reload value
Beyond that: reloading TMR0 as soon as possible - directly following the test for the TMR0IF flag.
 
Other options apply - like setting your cnt test to 8976 without changing anything else on your current code. (Although this is the worst of all possible solutions, it is the fastest way to realize a 0.5 Hz blink rate.)

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
#2
ric
Super Member
  • Total Posts : 29951
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: PIC18F4580 timer 0 question 2021/01/01 18:36:14 (permalink) ☄ Helpfulby Lucky Luka 2021/01/02 02:37:04
+2 (2)
Your existing code will run slow because you are not allowing for all the instructions that execute before you update the timer value.
Just changing
TMR0L = 55;

to
TMR0L += 55;

will allow for it automatically.
It is instructive to work out for yourself why this works.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#3
1and0
Access is Denied
  • Total Posts : 12108
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC18F4580 timer 0 question 2021/01/01 20:09:29 (permalink) ☄ Helpfulby Lucky Luka 2021/01/02 06:09:10
+2 (2)
Lucky Luka
Maybe the issue is related to what is written in the datasheet:
"If the TMR0 register is written to, the increment is inhibited for the following two instruction cycles. The user
can work around this by writing an adjusted value to the TMR0 register."
Is this the case? What values do I have to select as TMR0 in my formula? (I hope the formula is ok and the way I proceed is the one I chose... Any suggestions are welcome.)

That is part of the reason, and Ric gave the other reason. Also, your formula should subtract from 256, not 255.

To get a more accurate count, you'll have to account for all those:
TMR0L += 256 - 200 + 2;

#4
Lucky Luka
Starting Member
  • Total Posts : 42
  • Reward points : 0
  • Joined: 2019/04/02 09:39:39
  • Location: Italy
  • Status: offline
Re: PIC18F4580 timer 0 question 2021/01/02 02:43:52 (permalink)
0
1and0
To get a more accurate count, you'll have to account for all those:
TMR0L += 256 - 200 + 2;




I'm about to modify my program but I've thought about something...
Looking at the datasheet shouldn't an instruction cycle be over in 4 clock?
With that in mind shouldn't the formula be: TMR0L += 256 - 200 + 8?
Thanks

Attached Image(s)

#5
Lucky Luka
Starting Member
  • Total Posts : 42
  • Reward points : 0
  • Joined: 2019/04/02 09:39:39
  • Location: Italy
  • Status: offline
Re: PIC18F4580 timer 0 question 2021/01/02 04:51:03 (permalink)
0
Using the formula
TMR0L += 256 - 200 + 2;
The situation improved a lot: I obtain 1.002 sec ON and and 1.002 sec OFF.
Substituting 8 to 2 in the formula as I suggested the result is much worse.
I still don't understand why tough.
 
Then I tried to follow the idea of du00000001: I used timer 0 = as a 16 bit timer.
Something went wrong but I don't know where I made a mistake...
I obtain more than 1.5sec ON and 1.5 sec OFF LED blinking...
I have updated the formula and I've attached it to this post.
I don't understand what is the source of error: the formula or the program?
Maybe I've written the wrong register (TMR0L)? Even writing TMRL0 the result isn't good.
 
#include <xc.h>
#include "timer_header.h"
#include "stdint.h"
#include "stdbool.h"

#define LED1 LATCbits.LATC0 // Green LED
//#define LED2 LATCbits.LATC1 // Yellow LED

//#define BUTTON PORTBbits.RB0 // Button

uint32_t blink_count = 0;
//uint16_t button_count = 0;
//bool button_press = false;

// HIGH priority ISR
void __interrupt(high_priority) HPbuttonISR(void){
    // Check The Timer 0 Flag Bit
   if (INTCONbits.TMR0IF)
   {
      blink_count++;
      if(blink_count==50) // with 8 bit it is 10000 timer overflows!
      {
        // Toggle green LED
        LED1 = ~LED1;
        // Clear The Global Counter
        blink_count = 0;
      }
      // Preload The Value To TMR1 Register Every Overflow Interrupt
      TMR0L += 25538;
      INTCONbits.TMR0IF = 0; // Clear The Flag Bit
   }
}


void main(void) {
    // Configure the pins: OUT = 0, IN = 1
    TRISBbits.RB0 = 1;
    TRISCbits.RC0 = 0;
    TRISCbits.RC1 = 0;
    
    // 8MHz internal oscillator
    OSCCONbits.IRCF = 0x07;
    // Internal oscillator selected
    OSCCONbits.SCS = 0x03;
    // I wait until the oscillator's freq is stable
    while(OSCCONbits.IOFS!=1);
    
    // Timer 0 OFF
    T0CONbits.TMR0ON=0;
    // Timer 0: 16 bit
    T0CONbits.T08BIT=0;
    // Internal source clock
    T0CONbits.T0CS = 0;
    // Prescaler is bypassed --> 1:1
    T0CONbits.PSA = 1;
        
    // Preload The Value Which We've Calculated To The TMR0 16-Bit Register!
    TMR0L += 25538;
    
    // Enable Timer 0 interrupt
    INTCONbits.TMR0IE=1;
    // High priority for timer 0 interrupt
    INTCON2bits.TMR0IP=1;
        
    ei(); // This is like flipping the master switch to enable
          // all interrupts: it's like GIE = 1
    // Timer 0 ON
    T0CONbits.TMR0ON=1;
    
    LED1 = 0; // Switch OFF Green LED
    //LED2 = 0; // Switch OFF Yellow LED
        
    // Infinite loop
    while(1){
        
    }
            
    return;
}

Attached Image(s)

#6
du00000001
Just Some Member
  • Total Posts : 4120
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: online
Re: PIC18F4580 timer 0 question 2021/01/02 05:35:02 (permalink) ☄ Helpfulby Lucky Luka 2021/01/02 06:09:02
+2 (2)
The mistake? TMR0L is an 8-Bit register while you have to add a 16-Bit value.
If writing to TMR0 is not supported (not sure about that), you have to update TMR0H and TMR0L in the right sequence.

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
#7
ric
Super Member
  • Total Posts : 29951
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: PIC18F4580 timer 0 question 2021/01/02 05:58:56 (permalink) ☄ Helpfulby Lucky Luka 2021/01/02 06:09:59
+2 (2)
Lucky Luka
I'm about to modify my program but I've thought about something...
Looking at the datasheet shouldn't an instruction cycle be over in 4 clock?
With that in mind shouldn't the formula be: TMR0L += 256 - 200 + 8?

No, because the timer is also being clocked by Fosc/4, so one count per instruction.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#8
ric
Super Member
  • Total Posts : 29951
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: PIC18F4580 timer 0 question 2021/01/02 06:13:18 (permalink)
+2 (2)
du00000001
The mistake? TMR0L is an 8-Bit register while you have to add a 16-Bit value.
If writing to TMR0 is not supported (not sure about that), you have to update TMR0H and TMR0L in the right sequence.

TMR0 does support latched read and writes, but then you lose the elegance of an 8 bit add.
You have to read the 16 bit value as two 8 bit values into temporary storage (carefully reading TMR0L then TMR0H),
then do the 16 bit addition, then do two 8 bit writes (carefully writing TMR0H then TMR0L).
There's no automatic way to compensate for however many assembly instructions that process takes.
 
This is when you discover that TMR2 is the best one for a periodic interrupt, as it has a built in reload register (PR2).
You can get 10 KHz with these settings:
TMR2 prescale = 1:1
TMR2 postscale = 1:1
TMR2 PR2 = 199
Rate = (8000000/4)/(199+1) = 10000
 
I would agree that 1kHz is probably less overhead.
Just use the above settings but change the TMR2 postscale value to 1:10 to get 1kHz.
 
 
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#9
1and0
Access is Denied
  • Total Posts : 12108
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC18F4580 timer 0 question 2021/01/02 07:05:01 (permalink)
+1 (3)
Lucky Luka
Using the formula
TMR0L += 256 - 200 + 2;
The situation improved a lot: I obtain 1.002 sec ON and and 1.002 sec OFF.

I forgot to account for one more instruction cycle for the write to the TMR0 register; that is,
TMR0L += 256 - 200 + 2 + 1;

 
Lucky Luka
Substituting 8 to 2 in the formula as I suggested the result is much worse.
I still don't understand why tough.

As Ric said, Timer0 is clocked at the rate of Fosc/4.
#10
1and0
Access is Denied
  • Total Posts : 12108
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC18F4580 timer 0 question 2021/01/02 07:10:16 (permalink) ☄ Helpfulby Lucky Luka 2021/01/02 07:39:37
+2 (2)
ric
TMR0 does support latched read and writes, but then you lose the elegance of an 8 bit add.
You have to read the 16 bit value as two 8 bit values into temporary storage (carefully reading TMR0L then TMR0H),
then do the 16 bit addition, then do two 8 bit writes (carefully writing TMR0H then TMR0L).
There's no automatic way to compensate for however many assembly instructions that process takes.

Early on into the ISR, assuming TMR0H is still 0x00 and there will be no carry. I wonder if the write to TMR0L can be performed with an addition instead? That is, will ADDWF instead of MOVWF on TMR0L work:
    movlw   high(.65536 - .40000 + 2 + 1)
    movwf   TMR0H
    movlw   low (.65536 - .40000 + 2 + 1)
    addwf   TMR0L

 
ric
This is when you discover that TMR2 is the best one for a periodic interrupt, as it has a built in reload register (PR2).

+1
#11
Lucky Luka
Starting Member
  • Total Posts : 42
  • Reward points : 0
  • Joined: 2019/04/02 09:39:39
  • Location: Italy
  • Status: offline
Re: PIC18F4580 timer 0 question 2021/01/02 08:03:56 (permalink)
0
Thank you all
In the end I think I've chosen the easiest way (for me):
Timer 0 @ 8bit, internal clock @ 500kHz, prescaler @ 1:1
 
1and0
I forgot to account for one more instruction cycle for the write to the TMR0 register; that is,
TMR0L += 256 - 200 + 2 + 1;


I have added 2 to the counter and I've obtained 1,004s blinking period.
I then tried to add 3 to the counter and i've obrained 0.996s blinking period.
I don't know if this issue can be solved using this timer.
 
#include <xc.h>
#include "timer_header.h"
#include "stdint.h"
#include "stdbool.h"

#define LED1 LATCbits.LATC0 // Green LED
//#define LED2 LATCbits.LATC1 // Yellow LED

//#define BUTTON PORTBbits.RB0 // Button

uint16_t blink_count = 0;
//uint16_t button_count = 0;
//bool button_press = false;

// HIGH priority ISR
void __interrupt(high_priority) HPbuttonISR(void){
    // Check The Timer 0 Flag Bit
   if (INTCONbits.TMR0IF)
   {
      blink_count++;
      if(blink_count==500) // with 8 bit 8MHz it was 10000 timer overflows!
      {
        // Toggle green LED
        LED1 = ~LED1;
        // Clear The Global Counter
        blink_count = 0;
      }
      // Preload The Value To TMR1 Register Every Overflow Interrupt
      TMR0L += 8;
      INTCONbits.TMR0IF = 0; // Clear The Flag Bit
   }
}


void main(void) {
    // Configure the pins: OUT = 0, IN = 1
    TRISBbits.RB0 = 1;
    TRISCbits.RC0 = 0;
    TRISCbits.RC1 = 0;
    
    // 500 kHz internal oscillator
    OSCCONbits.IRCF = 0x03;
    // Internal oscillator selected
    OSCCONbits.SCS = 0x03;
    // I wait until the oscillator's freq is stable
    while(OSCCONbits.IOFS!=1);
    
    // Timer 0 OFF
    T0CONbits.TMR0ON=0;
    // Timer 0: 8 bit
    T0CONbits.T08BIT=1;
    // Internal source clock
    T0CONbits.T0CS = 0;
    // Prescaler is bypassed --> 1:1
    T0CONbits.PSA = 1;
        
    // Preload The Value Which We've Calculated To The TMR0 8-Bit Register!
    TMR0L += 8;
    
    // Enable Timer 0 interrupt
    INTCONbits.TMR0IE=1;
    // High priority for timer 0 interrupt
    INTCON2bits.TMR0IP=1;
        
    ei(); // This is like flipping the master switch to enable
          // all interrupts: it's like GIE = 1
    // Timer 0 ON
    T0CONbits.TMR0ON=1;
    
    LED1 = 0; // Switch OFF Green LED
    //LED2 = 0; // Switch OFF Yellow LED
        
    // Infinite loop
    while(1){
        
    }
            
    return;
}

 
 
 

Attached Image(s)

#12
1and0
Access is Denied
  • Total Posts : 12108
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC18F4580 timer 0 question 2021/01/02 08:55:11 (permalink)
+1 (1)
Lucky Luka
I have added 2 to the counter and I've obtained 1,004s blinking period.
I then tried to add 3 to the counter and i've obrained 0.996s blinking period.
I don't know if this issue can be solved using this timer.
void __interrupt(high_priority) HPbuttonISR(void){ 
    // Check The Timer 0 Flag Bit
   if (INTCONbits.TMR0IF)
   {
      blink_count++;
      if(blink_count==500) // with 8 bit 8MHz it was 10000 timer overflows!
      {
        // Toggle green LED
        LED1 = ~LED1;
        // Clear The Global Counter
        blink_count = 0;
      }
      // Preload The Value To TMR1 Register Every Overflow Interrupt
      TMR0L += 8;
      INTCONbits.TMR0IF = 0; // Clear The Flag Bit
   }
}


Adding 3 is the correct solution, and I would expect you to get an on-off period of exactly 2 seconds.  I suspect the different on time and off time are caused by this
        LED1 = ~LED1;

generating different paths thru the code.  So, replace these two lines
        LED1 = ~LED1;
 
      TMR0L += 8;

with these
        LED1 ^= 1;

      TMR0L += 256 - 250 + 2 + 1;  // add 9

and see. ;)
 
#13
Lucky Luka
Starting Member
  • Total Posts : 42
  • Reward points : 0
  • Joined: 2019/04/02 09:39:39
  • Location: Italy
  • Status: offline
Re: PIC18F4580 timer 0 question 2021/01/02 10:06:02 (permalink)
0
Hi
I've tried to modify the code as you said but I obtained the same period of 2 - 0.004s
That was my first eye measure with the scope.
Then I made an auto measure of the period and it looks like I was right: it's not precisely 2 sec.
I hope I haven't done some mistake in the measurements since I'm still learning both in the microcontrllers field and in oscilloscopes measures but that's what I've obtained...
 
#include <xc.h>
#include "timer_header.h"
#include "stdint.h"
#include "stdbool.h"

#define LED1 LATCbits.LATC0 // Green LED
//#define LED2 LATCbits.LATC1 // Yellow LED

//#define BUTTON PORTBbits.RB0 // Button

uint16_t blink_count = 0;
//uint16_t button_count = 0;
//bool button_press = false;

// HIGH priority ISR
void __interrupt(high_priority) HPbuttonISR(void){
    // Check The Timer 0 Flag Bit
   if (INTCONbits.TMR0IF)
   {
      blink_count++;
      if(blink_count==500) // with 8 bit 8MHz it was 10000 timer overflows!
      {
        // Toggle green LED
        LED1 ^= 1;
        // Clear The Global Counter
        blink_count = 0;
      }
      // Preload The Value To TMR1 Register Every Overflow Interrupt
      TMR0L += 9;
      INTCONbits.TMR0IF = 0; // Clear The Flag Bit
   }
}


void main(void) {
    // Configure the pins: OUT = 0, IN = 1
    TRISBbits.RB0 = 1;
    TRISCbits.RC0 = 0;
    TRISCbits.RC1 = 0;
    
    // 500 kHz internal oscillator
    OSCCONbits.IRCF = 0x03;
    // Internal oscillator selected
    OSCCONbits.SCS = 0x03;
    // I wait until the oscillator's freq is stable
    while(OSCCONbits.IOFS!=1);
    
    // Timer 0 OFF
    T0CONbits.TMR0ON=0;
    // Timer 0: 8 bit
    T0CONbits.T08BIT=1;
    // Internal source clock
    T0CONbits.T0CS = 0;
    // Prescaler is bypassed --> 1:1
    T0CONbits.PSA = 1;
        
    // Preload The Value Which We've Calculated To The TMR0 8-Bit Register!
    TMR0L += 9;
    
    // Enable Timer 0 interrupt
    INTCONbits.TMR0IE=1;
    // High priority for timer 0 interrupt
    INTCON2bits.TMR0IP=1;
        
    ei(); // This is like flipping the master switch to enable
          // all interrupts: it's like GIE = 1
    // Timer 0 ON
    T0CONbits.TMR0ON=1;
    
    LED1 = 0; // Switch OFF Green LED
    //LED2 = 0; // Switch OFF Yellow LED
        
    // Infinite loop
    while(1){
        
    }
            
    return;
}

Attached Image(s)

#14
1and0
Access is Denied
  • Total Posts : 12108
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC18F4580 timer 0 question 2021/01/02 10:29:43 (permalink) ☄ Helpfulby Lucky Luka 2021/01/02 10:31:42
+3 (3)
Lucky Luka
I've tried to modify the code as you said but I obtained the same period of 2 - 0.004s
That was my first eye measure with the scope.
Then I made an auto measure of the period and it looks like I was right: it's not precisely 2 sec.
I hope I haven't done some mistake in the measurements since I'm still learning both in the microcontrllers field and in oscilloscopes measures but that's what I've obtained...

I just tested your code in the MPLAB Simulator and the LED blinks at exactly one-second on-time and one-second off-time. So, it is either your scope or the accuracy of the internal oscillator which can be ±2%, ±5% or ±10% depending on the temperature.
#15
ric
Super Member
  • Total Posts : 29951
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: PIC18F4580 timer 0 question 2021/01/02 17:41:31 (permalink) ☄ Helpfulby Lucky Luka 2021/01/04 09:47:12
+3 (3)
1.004s is an error of only 0.4%
As 1and0 mentions, even at just 25C, the internal oscillator is only specified to +/- 2%, it's even worse over a range of temperatures.
https://ww1.microchip.com...oc/39637d.pdf#page=441
So, your error is well under what the datasheet guarantees.
You need an external crystal, or a newer PIC with a more precise internal osciullator if you want a more accurate clock rate.
 
post edited by ric - 2021/01/02 17:42:48

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#16
du00000001
Just Some Member
  • Total Posts : 4120
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: online
Re: PIC18F4580 timer 0 question 2021/01/02 17:57:06 (permalink) ☄ Helpfulby Lucky Luka 2021/01/04 09:47:35
+2 (2)
And don't forget that the scope inserts its own error. Although digital scopes might be better than 1% (the magic number for good analog scopes), the timebase error might easily add 0.1 % (or more).

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
#17
Lucky Luka
Starting Member
  • Total Posts : 42
  • Reward points : 0
  • Joined: 2019/04/02 09:39:39
  • Location: Italy
  • Status: offline
Re: PIC18F4580 timer 0 question 2021/01/04 09:47:48 (permalink)
0
Thank you all.
#18
dan1138
Super Member
  • Total Posts : 4246
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: PIC18F4580 timer 0 question 2021/01/04 13:05:31 (permalink)
+2 (2)
1and0
I just tested your code in the MPLAB Simulator and the LED blinks at exactly one-second on-time and one-second off-time.

The MPLABX simulator has some dodgy behavior for instruction cycle counts with the TIMER0 in PIC18F targets.
 
Sometime in 2019 I have raised an issue with Microchip support on the TIMER0 count behavior being different from how the real part work. I have not checked the v5.45 of MPLABX to see if it has been fixed.
 
The specific issue I raised is that in the real device any write to the TIMER0 count register results in a two instruction cycle delay before TIMER0 starts to count, but there are some opcodes that can be used to write the TIMER0 count register where the simulator starts the TIMER0 count without a delay.
 
So the bottom line here is that getting a cycle accurate count period from TIMER0 is tricky and hard to verify with the dodgy simulator.
#19
Lucky Luka
Starting Member
  • Total Posts : 42
  • Reward points : 0
  • Joined: 2019/04/02 09:39:39
  • Location: Italy
  • Status: offline
Re: PIC18F4580 timer 0 question 2021/01/04 13:14:54 (permalink)
0
dan1138
The specific issue I raised is that in the real device any write to the TIMER0 count register results in a two instruction cycle delay before TIMER0 starts to count, but there are some opcodes that can be used to write the TIMER0 count register where the simulator starts the TIMER0 count without a delay.
 

Do you confirm that there is to account for one more instruction cycle for the write to the TMR0 register other than those two mentioned?
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2021 APG vNext Commercial Version 4.5