Author Topic: TIMER0 TMR0 pic18F2550 [SOLVED]  (Read 2620 times)

0 Members and 2 Guests are viewing this topic.

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
TIMER0 TMR0 pic18F2550 [SOLVED]
« on: May 22, 2016, 11:29:22 pm »
Hello everyone, I'm new here :) this looks like a friendly forum

So, I've been scratching my head for the past 3 days trying to get my PIC2550(first PIC to work with) to do timer0 interrupt, using external oscilator, 16MHz crystal, 22p caps.

the code toggle two leds, and that is exactly what happens, but I don't feel like i'm able to control the TMR0 at all.  :-//
When T08BIT is set, no matter what is the value of TMR0H or TMR0L, the LED toggles every exactly 4 seconds.
When T08BIT is not set, no matter what is the value of TMR0L, the LED toggles very fast.


I read the datasheet and still reading it. most relevant pages 26,32,34, & 127 in the datasheet http://ww1.microchip.com/downloads/en/devicedoc/39632c.pdf
The code is very small and I put comments on every command to explain it. It's easier to read it by downloading the attached file, i use tabs not spaces :/
Code: [Select]
#include <xc.h>;
#define _XTAL_FREQ 16000000

// BEGIN CONFIG
#pragma config FOSC = HS //External High-Speed Crystal
#pragma config WDT = OFF //Watchdog Timer disabled
#pragma config LVP = OFF //Single-Supply ICSP disabled
//END CONFIG

#define LED_PORT PORTCbits.RC0
#define LED_TRIS TRISCbits.TRISC0
#define LED2_PORT PORTCbits.RC1
#define LED2_TRIS TRISCbits.TRISC1

void SetupTimer0()
{
TMR0L = 0x00; //This value doesn't seem to be doing anything no matter what I put in it
TMR0H = 0x00; //This value doesn't seem to be doing anything no matter what I put in it
    T0PS0 = 1; //1:256 Prescale value
T0PS1 = 1; //1:256 Prescale value
T0PS2 = 1; //1:256 Prescale value
PSA = 0; //prescaler is assigned. Timer0 clock input comes from prescaler output.
T0SE = 0; //Increment on high-to-low transition on T0CKI pin
T0CS = 0; //Internal instruction cycle clock source(CLKO)
T08BIT = 1; //Timer0 is configured as a 8-bit timer/counter
TMR0ON = 1; //Enables Timer0
TMR0IE = 1; //Enable TIMER0 Interrupt

    PEIE = 1; //Enable Peripheral Interrupt
}

void interrupt ISR()
{
  if (TMR0IE && TMR0IF) {
  TMR0IF = 0;
  LED_PORT ^= 1; //Toggling led
  LED2_PORT ^= 1; //Toggling led
  }
 }

void main()
{
    LED_TRIS = 0; //set led port as output
    LED_PORT = 1; //start LED ON.

    LED2_TRIS = 0; //set led port as output
    LED2_PORT = 0; //start LED off.

    SetupTimer0();
ei(); // enable all interrupts
   
    while(1);
}

I'm using xc8 compiler, on a linux os.



Thank you all in advance . :)
« Last Edit: May 23, 2016, 02:39:19 am by MAD MACRO »
 

Offline Delta

  • Super Contributor
  • ***
  • Posts: 1221
  • Country: gb
Re: TIMER0 TMR0 pic18F2550
« Reply #1 on: May 23, 2016, 12:26:38 am »
You need to write your chosen value into the timer's register(s) in your ISR as well as at startup.  When the timer rolls over it starts counting from zero, not from whatever value you happened to write to it way back when!
 
The following users thanked this post: MAD MACRO

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: TIMER0 TMR0 pic18F2550
« Reply #2 on: May 23, 2016, 12:49:55 am »
well, that worked perfectly, thanks  :)

but, there's still something that doesn't make sense, crystal produces 16MHz frequency, the prescaler on timer0 is 256, (16000000/256 = 62500),
which means timer0 is supposed to tick every 1/62500 seconds, but with TMR0 not changed or set to 0x0000, it will be mutiplied by 65535,

(1/62500) * 65535 = 1.04 seconds, and not 4 seconds. Is my input frequency being divided by 4 ?


I read about PLL dividing frequency feature, but it shouldn't affect it, cuz I set FOSC to HS and not HSPLL....what am I missing ?

 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2543
  • Country: us
Re: TIMER0 TMR0 pic18F2550
« Reply #3 on: May 23, 2016, 01:08:43 am »
well, that worked perfectly, thanks  :)

but, there's still something that doesn't make sense, crystal produces 16MHz frequency, the prescaler on timer0 is 256, (16000000/256 = 62500),
which means timer0 is supposed to tick every 1/62500 seconds, but with TMR0 not changed or set to 0x0000, it will be mutiplied by 65535,

(1/62500) * 65535 = 1.04 seconds, and not 4 seconds. Is my input frequency being divided by 4 ?


I read about PLL dividing frequency feature, but it shouldn't affect it, cuz I set FOSC to HS and not HSPLL....what am I missing ?

Look at Figure 11-1.  Timer0 is clocked by Fosc/4.  Therefore, each timer tick will be 16MHz / 4 / 256 = 15.625KHz.
The pic18f2550 takes 4 clock cycles for each instruction and all of the timing is based on the instruction time. 
 
The following users thanked this post: MAD MACRO

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: TIMER0 TMR0 pic18F2550
« Reply #4 on: May 23, 2016, 01:17:12 am »
it's one of these "aaaaaah" moments. I get it now. coming from AVR land, this is new to me.

just a quick comparison: atmega328p can operate on maximum true 20MHz, and the pic18F2550 can operate on maximum 48MHz, which gives true 12MHz.
Did I get that right ?
« Last Edit: May 23, 2016, 02:40:30 am by MAD MACRO »
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2543
  • Country: us
Re: TIMER0 TMR0 pic18F2550
« Reply #5 on: May 23, 2016, 01:38:48 am »
The maximum clock frequency for the pic18f2550 is 48MHz.  But, that is only if the supply voltage is 5V.  Check the electrical specifications graph for lower voltages.

Also note, that the 8-bit PIC microcontrollers instruction cycle time is Fosc/4.  However, the larger PICs have variable cycle times based on the instruction being executed.  Since I've only used the 8-bit PICs, I don't know if the peripherals all run at the Fosc/4 clock speed or not.
 
The following users thanked this post: MAD MACRO


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf