Author Topic: PIC 18F4520 configuring TMR0  (Read 4606 times)

0 Members and 1 Guest are viewing this topic.

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
PIC 18F4520 configuring TMR0
« on: April 30, 2016, 05:02:21 pm »
Hello,

I have just started to learn the architecture of PICs.  I am programming a 18F4520, but I have bumped into a first problem which I don't know how to solve it.

The thing is, that I don't fully understand the datasheet.

First of all; What is the clock speed of internal clock (Mhz) of 18F4520? In the datasheet is written that is configurable. But I haven't configure nothing which refers to clock speed, because I can damage the chip.

Second; How can I configure  TMR0 (16bit mode) so that the output of one pin will toggle with the frequency of 4 Hz?
Can someone give an example for calculating the parameters for this particular chip. I am using the timer as 16 bit timer, I know that the internal clock for the timer is reduced 4 times, and then it can be reduced with the prescaler (which we configure).

Thank you for your help.
 

Offline Skimask

  • Super Contributor
  • ***
  • Posts: 1433
  • Country: us
Re: PIC 18F4520 configuring TMR0
« Reply #1 on: April 30, 2016, 05:36:00 pm »
First of all; What is the clock speed of internal clock (Mhz) of 18F4520? In the datasheet is written that is configurable. But I haven't configure nothing which refers to clock speed, because I can damage the chip.
Page 28 of DS39631A.  The internal clock speed is whatever you configure it to be...from 31Khz, up to 32Mhz.

Quote
Second; How can I configure  TMR0 (16bit mode) so that the output of one pin will toggle with the frequency of 4 Hz?
Can someone give an example for calculating the parameters for this particular chip. I am using the timer as 16 bit timer, I know that the internal clock for the timer is reduced 4 times, and then it can be reduced with the prescaler (which we configure).
Section 11 of DS39631A.
Break it down...

T0CON.6 = 0 = TMR0 is 16 bit counter
T0CON.5 = 0 = TMR0 source is the internal clock
T0CON.3 = 0 = TMR0 prescale is used
T0CON.2-0 = 001 = 1:4 prescale
Assume you're running 8 Mhz internal clock.
8 Mhz / 4  = 2Mhz which is the internal instruction clock cycle
2Mhz / 4 prescaler = 500khz
16 counter overflows every 65,536 counts
500khz / 65536 = 7.62939453125 Hz

Now you have to write code that uses either polling or an interrupt to check if the TMR0 counter overflowed and toggle a pin appropriately.

Without pre-setting the TMR0L & TMR0H bytes to a preset value each time the TMR0 overflows, you aren't going to get exactly 4Hz.

So, now write some code, some real code, and program it to a real PIC, on a real demo PCB of some sort, and report back.
I didn't take it apart.
I turned it on.

The only stupid question is, well, most of them...

Save a fuse...Blow an electrician.
 
The following users thanked this post: nForce

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: PIC 18F4520 configuring TMR0
« Reply #2 on: April 30, 2016, 06:22:21 pm »
For 8 bit pics, such as the PIC18s, the instruction clock is one fourth of the clock frequency. This means that if you're using the internal clock, configured as 8 MHz, your pic will effectively run at 8/4 = 2 MHz, or just about 2 MIPS.

Timer 0 is a "dumb" timer. it will count from wherever it is upwards, until it overflows and restarts from zero
When Timer 0 overflows it also generates an interrupt and you can use it to execute code after X counts. To set a specific time between two interrupts set TMR0H:L at a specific value

Timer 0 can use either the internal system clock or an external clock, the clock can also be divided by using a prescaler, to achieve longer time.

You can also use other timers, like timer 2. Timer 2 works in a different fashion. You set up the clock and then Timer 2 counts up until it matches a Period Register (PR2). in that moment it resets itself and generate an interrupt. As timer2 is also used by the CCP module as timebase, so it becomes useful to execute syncronious tasks, like loading the PWM module with a new period/sample
 

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: PIC 18F4520 configuring TMR0
« Reply #3 on: April 30, 2016, 06:42:57 pm »
Thank you,

Sorry, but I can't find what is the clock speed if I don't configure it? It is written that the factory calibrated the chip so it runs on 8 Mhz. So if I don't configure nothing which refers to the clock speed, it is then 8 Mhz?

I don't want to mess with the clock speed at the beginning.



 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: PIC 18F4520 configuring TMR0
« Reply #4 on: April 30, 2016, 07:16:35 pm »
Check the default values of fuse settings and default values of clock related registers. Typicslky it runs on the internal oscillators. Check the clock tree in the data sheet.
================================
https://dannyelectronics.wordpress.com/
 

Offline vodka

  • Frequent Contributor
  • **
  • Posts: 518
  • Country: es
Re: PIC 18F4520 configuring TMR0
« Reply #5 on: April 30, 2016, 08:00:07 pm »
Exactly from the schema What don't you understand?

Quote
So if I don't configure nothing which refers to the clock speed, it is then 8 Mhz?

Are you referring if you don't configure the preescaleer?

So, the answer can be unknown, because it is impossible knowlegde which data can have the register OSCCON when it turns on. Therefore ,
my advice is that you always initialize when you use the internal oscillator.

     

 

Offline Skimask

  • Super Contributor
  • ***
  • Posts: 1433
  • Country: us
Re: PIC 18F4520 configuring TMR0
« Reply #6 on: April 30, 2016, 09:52:10 pm »
Specifically to the O/P...

Reading one page isn't going to tell you the whole story.

You want to know what the default configuration of the PIC is upon power up?  Search the PDF for the word "default".

You want to know what the default config of the oscillator is on power up?  Search the PDF for the word "oscillator".

Page 30 and 250 of the datasheet will give you a clue as to what the default configuration of the oscillator is on power up.
I didn't take it apart.
I turned it on.

The only stupid question is, well, most of them...

Save a fuse...Blow an electrician.
 

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: PIC 18F4520 configuring TMR0
« Reply #7 on: May 24, 2016, 01:44:45 pm »
First of all; What is the clock speed of internal clock (Mhz) of 18F4520? In the datasheet is written that is configurable. But I haven't configure nothing which refers to clock speed, because I can damage the chip.
Page 28 of DS39631A.  The internal clock speed is whatever you configure it to be...from 31Khz, up to 32Mhz.

Quote
Second; How can I configure  TMR0 (16bit mode) so that the output of one pin will toggle with the frequency of 4 Hz?
Can someone give an example for calculating the parameters for this particular chip. I am using the timer as 16 bit timer, I know that the internal clock for the timer is reduced 4 times, and then it can be reduced with the prescaler (which we configure).
Section 11 of DS39631A.
Break it down...

T0CON.6 = 0 = TMR0 is 16 bit counter
T0CON.5 = 0 = TMR0 source is the internal clock
T0CON.3 = 0 = TMR0 prescale is used
T0CON.2-0 = 001 = 1:4 prescale
Assume you're running 8 Mhz internal clock.
8 Mhz / 4  = 2Mhz which is the internal instruction clock cycle
2Mhz / 4 prescaler = 500khz
16 counter overflows every 65,536 counts
500khz / 65536 = 7.62939453125 Hz

Now you have to write code that uses either polling or an interrupt to check if the TMR0 counter overflowed and toggle a pin appropriately.

Without pre-setting the TMR0L & TMR0H bytes to a preset value each time the TMR0 overflows, you aren't going to get exactly 4Hz.

So, now write some code, some real code, and program it to a real PIC, on a real demo PCB of some sort, and report back.

I have successfuly read the datasheet, and now I know that the default internal osc is 1 Mhz.

But how can I adjust the  TMR0L and TMR0H appropriately so that I get 4 Hz toggle. Can you do the example for 4 Hz? I will play with different frequency later.

I don't need the code, just a mathematical explanaiton and example. As I see this problem; at first I have to increase the prescaler (not 1:4 but 1:8) and then find two numbers for TMR0L and TMR0H.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: PIC 18F4520 configuring TMR0
« Reply #8 on: May 24, 2016, 02:41:37 pm »
4Hz means each flip is 125ms, or 125000 cpu cycles.

If you run the timer at 8 bits, that 125000/256 = 488.28 times. That means you can either a prescaler, and/or with re-load, and may have to some counting in the isr;

for 16-bit timer, 125000/64K = 1.90 times. That means you can either reload + some processing in the isr.

The approach above gives you the lowest jitter but may not be 100% accurate in terms of timing.

An alternative approach, which provides accurate ***long-term*** timing but will give you jitter, is to not reset the timer but keeps track of its value.

Like this in the isr

Code: [Select]
  timer0_cnt+=0x100;  //update timer0 counter for 8-bit; use 0x10000ul for 16-bit timer. Adjust appropriately if prescalers is used
  if (timer0_cnt >= F_CPU / F_OUT / 2) { //desired duration has elapsed
    timer0_cnt -= F_CPU / F_OUT / 2; //update timer0 counter
    flip PIN_OUTPUT; //flip output pin
  }
================================
https://dannyelectronics.wordpress.com/
 

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: PIC 18F4520 configuring TMR0
« Reply #9 on: May 24, 2016, 03:09:27 pm »
Sorry, but forget the counting and jitter. It can be approx. 4 Hz. I don't know how to choose the numbers for TMR0L and TMR0H and prescaler such that the bit will toggle with frequency 4 Hz.


This is a great example:
Quote
Assume you're running 8 Mhz internal clock.
8 Mhz / 4  = 2Mhz which is the internal instruction clock cycle
2Mhz / 4 prescaler = 500khz
16 counter overflows every 65,536 counts
500khz / 65536 = 7.62939453125 Hz

I know how to program, I just need an explanation in a logical and mathematical way with an example.

But I have to use TMR0H and TMR0L, because that way I can learn something new.

Thanks.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: PIC 18F4520 configuring TMR0
« Reply #10 on: May 24, 2016, 03:41:21 pm »
1. Create an isr that trips every 125000us/2 on 1:1 prescaler, and flip your output pin every two isr executions.

2. create an isr that trips every 125000us on 2:1 prescaler, and flip your output pin every isr execution.
================================
https://dannyelectronics.wordpress.com/
 

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: PIC 18F4520 configuring TMR0
« Reply #11 on: May 24, 2016, 04:21:27 pm »
How did you calculate/get the numbers which we assign to TMR0L and TMR0H?
 

Offline Skimask

  • Super Contributor
  • ***
  • Posts: 1433
  • Country: us
Re: PIC 18F4520 configuring TMR0
« Reply #12 on: May 24, 2016, 06:39:26 pm »
Oh for fucks sake...

Quote
Assume you're running 8 Mhz internal clock.
8 Mhz / 4  = 2Mhz which is the internal instruction clock cycle
2Mhz / 4 prescaler = 500khz
16 counter overflows every 65,536 counts
500khz / 65536 = 7.62939453125 Hz

Can you think out of the box for just a minute?
Modify that quote just a bit maybe?
Here...I'll do it for you.
Let's see if you follow me...

Quote
Assume you're running 8 Mhz internal clock.
8 Mhz / 4  = 2Mhz which is the internal instruction clock cycle
2Mhz / 4 prescaler = 500khz
16 counter overflows every 65,536 counts, but is preloaded with 32768 everytime it overflows.
500khz / 32767 = 15.259254737998596148564104129154 Hz
I didn't take it apart.
I turned it on.

The only stupid question is, well, most of them...

Save a fuse...Blow an electrician.
 
The following users thanked this post: nForce

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: PIC 18F4520 configuring TMR0
« Reply #13 on: May 24, 2016, 07:19:09 pm »
Quote
How did you calculate/get the numbers which we assign to TMR0L and TMR0H?

It's all laid out bare in prior posts.

Taking Approach 2 for example:

Code: [Select]
#define TMR0_OFST  (F_CPU / F_OUT / 2 / 2) //tmr0 offset for 2:1 prescaler to generate F_OUT under F_CPU

  TMR0 = -TMR0_OFST; //load tmr0 offset for F_OUT. Prescaler is set to 2:1

that's all you need.
================================
https://dannyelectronics.wordpress.com/
 
The following users thanked this post: nForce

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2548
  • Country: us
Re: PIC 18F4520 configuring TMR0
« Reply #14 on: May 24, 2016, 07:57:47 pm »
Complete example.  Sorry I don't have a pic18f4520 to test the code.

Code: [Select]
/*
 * File:   main.c
 * Author: Mark
 *
 * Created on May 24, 2016, 2:38 PM
 */

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>


// Configuration bits

// CONFIG1H
#pragma config OSC = INTIO7     // Oscillator Selection bits (Internal oscillator block, CLKO function on RA6, port function on RA7)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRT = ON        // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 3         // Brown Out Reset Voltage bits (Minimum setting)
// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC   // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = ON      // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = OFF      // MCLR Pin Enable bit (RE3 input pin enabled; MCLR disabled)
// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON         // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))


// Global variables
int led=0;

/*
 *  Main function
 */
void main() {

   // Configure the internal oscillator
   OSCCONbits.IRCF = 7;  // Set internal oscillator frequency to 8 MHz
   OSCCONbits.SCS = 2;   // Select internal oscillator

   // Configure I/O pin
   TRISAbits.TRISA0 = 0;   // Select RA0 pin as output
   
   // Configure Timer0
   /*
         The TMR0 interrupt is generated when the TMR0 register
         overflows from FFFFh to 0000h in 16-bit mode. This overflow
         sets the TMR0IF flag bit.
   
         For 4 Hz interrupt and 8 MHz clock:
            Fosc/4 = 2MHz
            ticks = 2MHz / 256 prescaler / 4 Hz interrupt = 1953
            TMR0 = 65535 - 1953 = 0xf85e
   
         DON'T FORGET TO RESET TMR0 VALUES IN ISR
    */
   TMR0H = 0xf8;     // Timer0 register (high byte)
   TMR0L = 0x5e;     // Timer0 register (low byte)
   
   T0CONbits.PSA = 0;      // Timer0 clock input comes from prescaler output
   T0CONbits.T0PS = 7;     // Set 1:256 prescale value
   T0CONbits.T0CS = 0;     // Select internal instruction cycle clock
   T0CONbits.T08BIT = 0;   // Select 16-bit timer/counter
   T0CONbits.TMR0ON = 1;   // Enable timer0
   
   // Enable interrupts
   INTCON=0xc0;      // GIE and PEIE interrupts
   
   // Enter main loop
   while (1) {
     
   }
}

/*
 *  Interrupt service routine
 */
void interrupt isr()
{
   if (TMR0IE && TMR0IF) {
      TMR0IF = 0;       // Clear Timer0 interrupt
      TMR0H = 0xf8;     // Timer0 register (high byte)
      TMR0L = 0x5e;     // Timer0 register (low byte)
     
      if (++led > 1) led=0;   // Toggle LED value
      LATAbits.LA0 = led;     // Set RA0 pin
   }
}

« Last Edit: May 24, 2016, 08:01:20 pm by MarkF »
 
The following users thanked this post: nForce

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: PIC 18F4520 configuring TMR0
« Reply #15 on: May 27, 2016, 08:51:02 pm »
Thank you, I had a software bug in my code.

I have one little question tho. I am programming this in assembly with simulator :

Why is this line of code working:
Code: [Select]
bsf LATB,7

But below the bit 4 it does not set.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf