• AVR Freaks

Helpful ReplyHot!Trying to understand the Prescaler

Page: 1234 > Showing page 1 of 4
Author
zimpic
Super Member
  • Total Posts : 221
  • Reward points : 0
  • Joined: 2012/05/16 08:39:13
  • Location: Zimbabwe
  • Status: offline
2014/01/26 22:47:15 (permalink)
0

Trying to understand the Prescaler

I was given this prescaler as help on another project and have started a new thread firstly as it was related to my other thread but if someone finds themselves in a similar position they can possibly use the results of this thread to help them.
 
I ultimately want a 10 minute delay but need to understand this so that I can work it out for myself. Any help understanding the below or direction will be greatly appreciated. 

 
// Implements a 50ms delay
void wait(char ticks)
{
   TMR0 = 60;                    // Preset timer (prescaler is cleared also)
   INTCONbits.T0IF = 0;        // Clear overflow flag

   while (ticks) {
       if (INTCONbits.T0IF) {
           TMR0 = 60;
           INTCONbits.T0IF = 0;
           --ticks;
           }
       }
   return;
}

#1
Nikolay_Po
Super Member
  • Total Posts : 1932
  • Reward points : 0
  • Joined: 2012/04/01 13:49:27
  • Location: Russia, Novorossiysk
  • Status: offline
Re:Trying to understand the Prescaler 2014/01/26 23:31:22 (permalink)
0
Different chips have different prescalers. Your chip is PIC12F675 ?
#2
zimpic
Super Member
  • Total Posts : 221
  • Reward points : 0
  • Joined: 2012/05/16 08:39:13
  • Location: Zimbabwe
  • Status: offline
Re:Trying to understand the Prescaler 2014/01/26 23:58:09 (permalink)
0
Yes, my PIC is the PIC12F675. I don't understand anything of the code to get the delays
 
#3
Nikolay_Po
Super Member
  • Total Posts : 1932
  • Reward points : 0
  • Joined: 2012/04/01 13:49:27
  • Location: Russia, Novorossiysk
  • Status: offline
Re:Trying to understand the Prescaler 2014/01/27 00:18:01 (permalink)
5 (1)
See the Datasheet at page 29, figure 4.1. This is the block diagram of the TIMER0 with it's prescaler. Prescaler is common for both TIMER0 and watchdog timer.
The prescaler and the timer are peripheral devices on the same chip as the processor. They can be configured by setting corresponding bits:
 
  • T0CS - Timer0 clock select. Controls clock input for the timer and prescaler. Should be "0" in Your case. "0" means the clock frequency on the prescaler/timer input is Fosc/4. I.e. if the processor clock is 4MHz then prescaler clock will be 1MHz.
  • PSA - Prescaler assignment. Prescaler may not be used simultaneously by both timer and watchdog. You need leave this bit zero to enable the prescaler before the timer. If You'll enable prescaler for the timer the clock frequency for the timer become 1MHz/Prescaler_rate.
  • PS2:PS0 - Prescaler rate. See page 30. The highest ratio is 1:256 for the timer. With maximum ratio and internal Fosc/4 clocking You'll got 4MHz/4/256=3906,25Hz. This is the speed the timer ticks. Timer will increment every T=1/3906,25s.
If You cont till 60 decimal the timer0 will overflow every 15,616ms nominal. If You will not rewrite the timer value after overflow and will leave the timer alone, it will overflow every 256 ticks: 1/4MHz*4*256*256=65,536ms. To count 10 minutes You need 9155 timer0 ticks if maximum ratios are chosen at 4MHz clock.
You may choose TIMER1 with 1:8 prescaler ratio but 1:65536 overflow capability. It gives 0,524288s overflow period maximum at 4MHz chip oscillator clock.
post edited by Nikolay_Po - 2014/01/27 00:43:51
#4
Nikolay_Po
Super Member
  • Total Posts : 1932
  • Reward points : 0
  • Joined: 2012/04/01 13:49:27
  • Location: Russia, Novorossiysk
  • Status: offline
Re:Trying to understand the Prescaler 2014/01/27 00:25:29 (permalink)
0
I haven't saw the configuration of the timer in Your code. It's possible that the timer runs from the default clock source - the T0CKI pin. So the TIMER0 may count not from internal ocsillator but from electrical noise ont this pin. You should explicitly configure the timer You use for delays. Just understand that the timer is another device on the chip which have it's own configuraton, inputs and outputs.
#5
zimpic
Super Member
  • Total Posts : 221
  • Reward points : 0
  • Joined: 2012/05/16 08:39:13
  • Location: Zimbabwe
  • Status: offline
Re:Trying to understand the Prescaler 2014/01/27 00:42:01 (permalink)
0
Thank you very much for the advice and assistance, I will read everything you suggested and then try to work it out, If I have any questions I will post. Many thanks
 
Rodney 
#6
zimpic
Super Member
  • Total Posts : 221
  • Reward points : 0
  • Joined: 2012/05/16 08:39:13
  • Location: Zimbabwe
  • Status: offline
Re:Trying to understand the Prescaler 2014/01/28 02:58:33 (permalink)
0
Nikolay_Po

See the Datasheet at page 29, figure 4.1. This is the block diagram of the TIMER0 with it's prescaler. Prescaler is common for both TIMER0 and watchdog timer.
The prescaler and the timer are peripheral devices on the same chip as the processor. They can be configured by setting corresponding bits:

  • T0CS - Timer0 clock select. Controls clock input for the timer and prescaler. Should be "0" in Your case. "0" means the clock frequency on the prescaler/timer input is Fosc/4. I.e. if the processor clock is 4MHz then prescaler clock will be 1MHz.
  • PSA - Prescaler assignment. Prescaler may not be used simultaneously by both timer and watchdog. You need leave this bit zero to enable the prescaler before the timer. If You'll enable prescaler for the timer the clock frequency for the timer become 1MHz/Prescaler_rate.
  • PS2:PS0 - Prescaler rate. See page 30. The highest ratio is 1:256 for the timer. With maximum ratio and internal Fosc/4 clocking You'll got 4MHz/4/256=3906,25Hz. This is the speed the timer ticks. Timer will increment every T=1/3906,25s.
If You cont till 60 decimal the timer0 will overflow every 15,616ms nominal. If You will not rewrite the timer value after overflow and will leave the timer alone, it will overflow every 256 ticks: 1/4MHz*4*256*256=65,536ms. To count 10 minutes You need 9155 timer0 ticks if maximum ratios are chosen at 4MHz clock.
You may choose TIMER1 with 1:8 prescaler ratio but 1:65536 overflow capability. It gives 0,524288s overflow period maximum at 4MHz chip oscillator clock.

If my understanding is correct each tick is 15,616ms?  therefore am I correct in saying  that where in my code it states wait(4); this is actually a delay of 62,464ms = 0.06 Seconds?
 
Sorry I am still very confused. If I was to increase TMR0=100; then is it correct to say 1 tick is equal to 1,561,600ms = 26 minutes
Sorry I am desperately confused
#7
Nikolay_Po
Super Member
  • Total Posts : 1932
  • Reward points : 0
  • Joined: 2012/04/01 13:49:27
  • Location: Russia, Novorossiysk
  • Status: offline
Re:Trying to understand the Prescaler 2014/01/28 05:15:12 (permalink)
0
The timer 0 is just 8 bit counter clocked by prescaler. Have You configured clock input for the prescaler and prescaler assignment? You had to perform before using the timer. I've give You an idea what bit values needed for the timer0 exploitation.
The timer0 can count only from 0 to 255 and will overflow at the tick next the 255. I've mistaken when saying that 60 decimal gives 15.6ms delay. Actually the timer sets the flag at the next tick after reaching the 255 decimal value. So if You load the timer with 60 decimal it counts 255-60+1=196 ticks from loading "60" till overflow. 196 ticks are 49,152ms. When You increase the value loaded into the timer0 the delay to overflow will decrease because less amount of ticks are left before 255-to-0 overflow. Even if You load zero on overflow (needn't because there will be zero after overflow itself) maximum delay will be 256 ticks, this is only 65,536ms.
To run 10 minutes delay perform:
  1. Configure prescaler clock input;
  2. Configure prescaler assignment;
  3. Turn on the timer0;
  4. Write zero in timer0;
  5. Clear timer overflow flag;
  6. Load the value 9155 decimal into 16-bit counter variable;
  7. Wait until the timer0 overflow flag is set;
  8. Clear overflow flag;
  9. Decrease counter variable;
  10. If variable is not zero repeat from point 7. If zero continue next step below;
  11. The 10 minutes are passed. Do what You need to do after 10 minutes timeout.
post edited by Nikolay_Po - 2014/01/28 05:22:25
#8
zimpic
Super Member
  • Total Posts : 221
  • Reward points : 0
  • Joined: 2012/05/16 08:39:13
  • Location: Zimbabwe
  • Status: offline
Re:Trying to understand the Prescaler 2014/01/29 01:21:10 (permalink)
0
Nikolay_Po

The timer 0 is just 8 bit counter clocked by prescaler. Have You configured clock input for the prescaler and prescaler assignment? You had to perform before using the timer. I've give You an idea what bit values needed for the timer0 exploitation.
The timer0 can count only from 0 to 255 and will overflow at the tick next the 255. I've mistaken when saying that 60 decimal gives 15.6ms delay. Actually the timer sets the flag at the next tick after reaching the 255 decimal value. So if You load the timer with 60 decimal it counts 255-60+1=196 ticks from loading "60" till overflow. 196 ticks are 49,152ms. When You increase the value loaded into the timer0 the delay to overflow will decrease because less amount of ticks are left before 255-to-0 overflow. Even if You load zero on overflow (needn't because there will be zero after overflow itself) maximum delay will be 256 ticks, this is only 65,536ms.
To run 10 minutes delay perform:
  1. Configure prescaler clock input;
  2. Configure prescaler assignment;
  3. Turn on the timer0;
  4. Write zero in timer0;
  5. Clear timer overflow flag;
  6. Load the value 9155 decimal into 16-bit counter variable;
  7. Wait until the timer0 overflow flag is set;
  8. Clear overflow flag;
  9. Decrease counter variable;
  10. If variable is not zero repeat from point 7. If zero continue next step below;
  11. The 10 minutes are passed. Do what You need to do after 10 minutes timeout.


Hi I was given the OPTION_REG settings when given the code
OPTION_REG = 0b11010111;

 
Looking on the data sheet
bits,0.1,2 111 sets the prescaler to 1:256
Bit3 set to 0 assigning the prescaler to the TIMER0 module
Bit 4 set to 1 increment  on high to low transition on GP2/T0CKI pin (don't understand this)
Bit 5 0 TMR0 clock source select bit, internal instruction cycle clock
Bit 6 interrupt on rising edge of GP2/INT pin  (don't understand this)
Bit 7 GPIO Pull - up Enable bit disabled.
So as per your above instructions this covers the first 3 point?
 

void wait(char ticks)
{
    TMR0 = 60;                    // Preset timer (prescaler is cleared also)
    INTCONbits.T0IF = 0;        // Clear overflow flag point 5 and  8
 
    while (ticks) {
        if (INTCONbits.T0IF) {
            TMR0 = 60;
            INTCONbits.T0IF = 0;
            --ticks;
            }
        }

 
The rest of the instructions I just don't understand sorry  sad
then  the code wait(4); does that refer to the number of cycles the timer must run to achieve the desired time?
 
Sorry I just cant grasp this.
 
Rod
#9
zimpic
Super Member
  • Total Posts : 221
  • Reward points : 0
  • Joined: 2012/05/16 08:39:13
  • Location: Zimbabwe
  • Status: offline
Still Trying to understand the Prescaler 2014/01/29 05:44:59 (permalink)
0
I have tried and tried and still don't follow the setting of the prescaler and how to calculate the delay.
 
this is my understanding 222-60+1=196 Ticks  (why do we add 1)
each tick is 0.250mS = 0.00025 Seconds
 
so wait(100); = 0.00025*100=0.025 Seconds.
 
so when I program the PIC12F675 as below
 

#include <xc.h>  
#define _XTAL_FREQ 4000000 //oscillator frequency for delays.
#define LED1   GPIO0
#define LED2   GPIO1
#define LED3 GPIO2
#define LED4  GPIO3
#define LED5 GPIO4
#define LED6  GPIO5
 
// #pragma config statements for PIC12F675 
#pragma config  BOREN = ON 
#pragma config  CPD = OFF 
#pragma config  FOSC = INTRCIO 
#pragma config  MCLRE = OFF 
#pragma config  WDTE = OFF 
#pragma config  CP = OFF 
#pragma config  PWRTE = ON 
 
void wait(char);
 
void main(void) {   
    ANSEL = 0;           // all ADC pins set to digital I/O   
    TRISIO = 0b001000;   // bits 0,1,2, 4,5 are outputs  Bit 3 input  
 
//                               76543210
    OPTION_REG = 0b11010111;    // Enable TMR0, use prescaler, value is 256
//    TMR0 will now overflow at about 65ms
 
while(1) {
    LED1=(1);    // Flash LED at startup to confirm code is running    
    wait(100); 
    LED1= 0; 
    wait(100);
 
 }
 
        } //End Forever loop 
 
void wait(char ticks)
{
    TMR0 = 60;                    // Preset timer (prescaler is cleared also)
    INTCONbits.T0IF = 0;        // Clear overflow flag
 
    while (ticks) {
        if (INTCONbits.T0IF) {
            TMR0 = 60;
            INTCONbits.T0IF = 0;
            --ticks;
            }
        }
    return;
}

the LED flashes on for 4 seconds off for 4 seconds.
 
So I am still none the wiser.sad
 
 
#10
Ian.M
Super Member
  • Total Posts : 13268
  • Reward points : 0
  • Joined: 2009/07/23 07:02:40
  • Location: UK
  • Status: offline
Re:Still Trying to understand the Prescaler 2014/01/29 06:20:40 (permalink)
0
There are significant issues with using Timer 0 with a prescaler on a midrange device for generating an interrupt with exact timing other than the timer's natural rollover period.
  • Writing to the timer clears its prescaler.  This means that when you adjust the timer by reloading it, unless you have some extremely tricky code to syncronise the write to the prescaler rollover, you loose track of however many instruction (Fosc/4) cycles the prescaler has counted since the last timer increment, and the period is extended by that amount. However as the internal oscillator is no better than +/- 1%, this is only an issue when using a crystal.
  • If you have multiple interrupt sources or the main program ever disables interrupts, the interrupt latency is unpredictable so simply reloading with a constant leads to an unpredictable result. Instead you need to add to the current timer value.
  • Timer 0 increment is inhibited for TWO instruction cycles after any write to it. Additionally any increment during a RMW instruction modifying it is lost (e.g. ADDWF TMR0,F).  
The combination of these issues makes it very difficult (near impossible) to do cycle accurate timing for arbitrary periods with Timer 0 for any prescaler other than 1:1 (disabled) and as 1:1 has a maximum period of 256 instruction cycles, the overhead of context save/restore for the ISR consumes an undesirably large fraction of the total processing time if you are codiong in a high level language. 
 
Are you interested in some code that will maintain an accurate realtime 10Hz tick count using Timer 1 free-running on a PIC16F88 @20MHz?   It keeps track of the excess delay over the desired 100ms period and 'bumps' the tick count when the excess exceeds another 100ms. Its suitable for timing intervals from a few seconds to 13 1/2 years!  Just ask and I'll post it and also help tweak it for a PIC12F675 @4MHz.    Normally one can use a CCP module with Timer 1 to get exact (cycle accurate) timing but your PIC12F675 doesn't have a CCP module and I wanted to reserve the PIC16F88 CCP module for other uses.
 
 
#11
zimpic
Super Member
  • Total Posts : 221
  • Reward points : 0
  • Joined: 2012/05/16 08:39:13
  • Location: Zimbabwe
  • Status: offline
Re:Still Trying to understand the Prescaler 2014/01/29 06:33:47 (permalink)
0
Yes Please, that would be fantastic, I have desperately been trying to get to understand this. I really appreciate the help, then I try to follow and understand the code.
 
Thank you so much!
 
Best wishes
 
Rod
#12
Nikolay_Po
Super Member
  • Total Posts : 1932
  • Reward points : 0
  • Joined: 2012/04/01 13:49:27
  • Location: Russia, Novorossiysk
  • Status: offline
Re:Trying to understand the Prescaler 2014/01/29 06:37:51 (permalink)
0
zimpic
Hi I was given the OPTION_REG settings when given the code
OPTION_REG = 0b11010111;

 Hi. I see now. The config is OK. But it will be better to write it another way to show the bit names. I don't know how this they do in C, I do it this way in Assembler:
  MOVLW 1<<NOT_GPPU || 1<<INTEDG || 0<< T0CS || 1<<T0SE || 0<<PSA || B'111'<<PS0
 MOVWF OPTION_REG


Looking on the data sheet
...Bit 4 set to 1 increment  on high to low transition on GP2/T0CKI pin (don't understand this)

This is relevant to the GP2/T0CKI pin only, not to the Fosc/4 clock source. This bit controls when the incrementing will be performed, on the rising edge or falling edge of the pulse on GP2/T0CKI pin if it was selected as TMR0 clock source.
 
...Bit 6 interrupt on rising edge of GP2/INT pin  (don't understand this)

This is relevant to the external interrupt input, not to the timer.
 
So as per your above instructions this covers the first 3 point?

Yes.
#13
Ian.M
Super Member
  • Total Posts : 13268
  • Reward points : 0
  • Joined: 2009/07/23 07:02:40
  • Location: UK
  • Status: offline
Re:Still Trying to understand the Prescaler 2014/01/29 07:12:46 (permalink)
0
O.K.   I'm actually working on a project for a friend on an Olimex PIC-IO with a PIC16F88 installed.   
I'm attaching* the early test code which includes the Timer 1 setup and ISR.   It doesn't do much yet, but the counter ticks is tracking execution time accurately already.  It would be trivial to modify to maintain two separate counters to time your two lights.
For 4MHz clock, use 1:2 prescale and #define COUNT100MS 50000UL
 
Here's the key parts of the code. 
ISR:
 
volatile uint32_t ticks=0; // tick count in 1/10 s units

#define COUNT100MS 62500UL // for 10Hz tick rate
#define T1ROLLOVER 0x10000UL

//ISR
void interrupt ISR(void) {
    static uint16_t excess=0;

    if(PIE1bits.TMR1IE && PIR1bits.TMR1IF) {
        PIR1bits.TMR1IF=0;
        ticks++;
        excess+=T1ROLLOVER-COUNT100MS;
        if(excess>=COUNT100MS) {
            excess-=COUNT100MS;
            ticks++;
        }
    }
}

Timer 1 and interrupt setup:
 
    TMR1=0;
    T1CONbits.T1CKPS=3;   //1:8 Prescaler
    T1CONbits.TMR1CS=0; //Fosc/4 clock source
    T1CONbits.TMR1ON=1; //Timer 1 on
   
    PIR1bits.TMR1IF=0;
   PIE1bits.TMR1IE=1;   //Timer 1 interrupt
   INTCONbits.PEIE=1;   //Peripheral interrupts
   INTCONbits.GIE=1;    //Global interrupts

 
As ticks is a multi-byte variable you neede to disable interrupts while reading/writing it in the main program.
#define ATOMIC for(INTCONbits.GIE=0;!INTCONbits.GIE;INTCONbits.GIE=1)

 
Then you can do:
 
ATOMIC t=ticks;
if(t>6000) { //10 minutes
    ATOMIC ticks=0; // reset tick count
    // do whatever is required
}


* Due to this specific forum's filetype restrictions you will have to rename the attached zip file to remove the .txt extension before you unpack it.
 
Edit: corrected 4MHz COUNT100MS define
post edited by Ian.M - 2014/01/29 07:43:11
#14
Nikolay_Po
Super Member
  • Total Posts : 1932
  • Reward points : 0
  • Joined: 2012/04/01 13:49:27
  • Location: Russia, Novorossiysk
  • Status: offline
Re:Still Trying to understand the Prescaler 2014/01/29 07:17:25 (permalink)
5 (1)
zimpicthis is my understanding 222-60+1=196 Ticks  (why do we add 1)

Not quite correct. 255-60+1=196. Or 256-60=196. This is because the timer is 8 bit. It's minimum value (right after overflow) is 0b00000000, maximum value (right before the overflow) is 0b11111111. The timer counts only forward. I.e. it can only increase every tick. But because it's 8-bit nature the next tick after reaching 0b11111111 is overflowing the timer. The next value after 0b11111111 should be 0b100000000 but this is 9 bit. The timer is only 8 bit. So only 0b00000000 is remaining after icrement from 0b11111111. This phenomenon is called "overflow" and is marked by timer overflow flag.
You can vary the number of ticks before the overflow (the time to overflow) by overwriting timer value. Higher value written means the sooner overflow. This is clear?

each tick is 0.250mS = 0.00025 Seconds

Let's try from the hardware side:
  1. Oscillator clock Fosc is 4000000 ticks per second.
  2. The clock at the input of the prescaler is Fpresc=Fosc/4=4000000/4=1000000 ticks per second.
  3. After the prescaler the tick rate is divided by prescaler ratio. I.e. Ftmr0=Fpresc/256=1000000/256=3906.25 ticks per second. I.e. The timer increments 3906.25 times per second.
  4. If timer value was overwrote, the next overflow (and the corresponding flag setup) occurs after 256-Value ticks of timer clock. I.e. Tovf=(256-Value)/Ftmr0=(256-60)/3906.25=0.050176s (50.0176ms).
  5. You count the overflows by the tick variable inside the wait() function. Without some small overheads the Wait(ticks) time will be T=ticks*Tovf=100*0.050176=5.0176s nominal. Indeed You should take the Fosc tolerance and stability in account. And the Ian's notes about resetting the prescaler too.
 
the LED flashes on for 4 seconds off for 4 seconds.

In ideal case the LED should stay on or off about 5s with Your code. The speed You've observed seems to be reasonable.

#15
zimpic
Super Member
  • Total Posts : 221
  • Reward points : 0
  • Joined: 2012/05/16 08:39:13
  • Location: Zimbabwe
  • Status: offline
Re:Still Trying to understand the Prescaler 2014/01/29 07:21:11 (permalink)
0
Thanks very much, Can I use this code for the 12F675 which I will be using for my project
#16
Nikolay_Po
Super Member
  • Total Posts : 1932
  • Reward points : 0
  • Joined: 2012/04/01 13:49:27
  • Location: Russia, Novorossiysk
  • Status: offline
Re:Still Trying to understand the Prescaler 2014/01/29 07:33:07 (permalink)
5 (1)
You can write Your own code indeed :) for this quite simple task.
#17
zimpic
Super Member
  • Total Posts : 221
  • Reward points : 0
  • Joined: 2012/05/16 08:39:13
  • Location: Zimbabwe
  • Status: offline
Re:Still Trying to understand the Prescaler 2014/01/30 04:18:47 (permalink)
0
Nikolay_Po 
  1. Oscillator clock Fosc is 4000000 ticks per second.
  2. The clock at the input of the prescaler is Fpresc=Fosc/4=4000000/4=1000000 ticks per second.
  3. After the prescaler the tick rate is divided by prescaler ratio. I.e. Ftmr0=Fpresc/256=1000000/256=3906.25 ticks per second. I.e. The timer increments 3906.25 times per second.
  4. If timer value was overwrote, the next overflow (and the corresponding flag setup) occurs after 256-Value ticks of timer clock. I.e. Tovf=(256-Value)/Ftmr0=(256-60)/3906.25=0.050176s (50.0176ms).
  5. You count the overflows by the tick variable inside the wait() function. Without some small overheads the Wait(ticks) time will be T=ticks*Tovf=100*0.050176=5.0176s nominal. Indeed You should take the Fosc tolerance and stability in account. And the Ian's notes about resetting the prescaler too.
  Hi This stared making sense until I tried it practically then the wheels fell off.
from the above formula which I understood how you go to it
 
T=ticks*Tovf=100*0.050176=5.0176s I wanted to get as close to a minute as possible so I used the following
 
T=ticks*Tovf=1200*0.050176=60.2112s
The results make no sense
 
1200 = 8 seconds
1000 = 11 seconds
900 = 6 seconds
400 = 7 seconds
 
My method of timing is using a stop watch which is not accurate but the results are no where near what is expected.
This makes me wonder if I have made another mistake in the code. So I have included it all below.
 
   
// SET UP FOR PIC12F675
 
#include <xc.h>  
#define _XTAL_FREQ 4000000 //oscillator frequency for delays.
#define LED1   GPIO0
#define LED2   GPIO1
#define LED3 GPIO2
#define LED4  GPIO3
#define LED5 GPIO4
#define LED6  GPIO5
 
// #pragma config statements for PIC12F675 
#pragma config  BOREN = ON 
#pragma config  CPD = OFF 
#pragma config  FOSC = INTRCIO 
#pragma config  MCLRE = OFF 
#pragma config  WDTE = OFF 
#pragma config  CP = OFF 
#pragma config  PWRTE = ON 
 

void wait(char);
 
void main(void) {   
    ANSEL = 0;           // all ADC pins set to digital I/O   
    TRISIO = 0b001000;   // bits 0,1,2, 4,5 are outputs  Bit 3 input  
 
//                               76543210
    OPTION_REG = 0b11010111;    // Enable TMR0, use prescaler, value is 256
//    TMR0 will now overflow at about 65ms
 
while(1) {
    LED1=(1);    // Flash LED at startup to confirm code is running    
    wait(400); 
    LED1= 0; 
    wait(400);
 
 }
 
        } //End Forever loop 
 
void wait(char ticks)
{
    TMR0 = 60;                    // Preset timer (prescaler is cleared also)
    INTCONbits.T0IF = 0;        // Clear overflow flag
 
    while (ticks) {
        if (INTCONbits.T0IF) {
            TMR0 = 60;
            INTCONbits.T0IF = 0;
            --ticks;
            }
        }
    return;
}
       

 
 



#18
Nikolay_Po
Super Member
  • Total Posts : 1932
  • Reward points : 0
  • Joined: 2012/04/01 13:49:27
  • Location: Russia, Novorossiysk
  • Status: offline
Re:Still Trying to understand the Prescaler 2014/01/30 06:34:24 (permalink)
0
You can't use the numbers higher than 255 for the current wait() code because the variable ticks have char type:
 
zimpic
void wait(char ticks)  
    {


If I'm not mistaken the char type is 8 bit only, so it can handle the range only 0..255. Because of overflowing the ticks variable you may got:
 
  • 1200 -> char -> 176 ticks -> 8.8s
  • 1000 -> char ->  232 ticks -> 11.6s
  • 900 -> char -> 132 ticks -> 6.6s
  • 400 -> char -> 144 ticks -> 7.2s
Are this your practical resuls?
 
You need change the type of tiks parameter in wait() function. 
post edited by Nikolay_Po - 2014/01/30 06:40:50
#19
zimpic
Super Member
  • Total Posts : 221
  • Reward points : 0
  • Joined: 2012/05/16 08:39:13
  • Location: Zimbabwe
  • Status: offline
Re:Still Trying to understand the Prescaler 2014/01/30 06:46:32 (permalink)
0
If the prescaler is changed will this make a difference? also by reducing the value going into TMR0 to 1
 
How am I ever going to get a time delay of 10 minutes.
#20
Page: 1234 > Showing page 1 of 4
Jump to:
© 2019 APG vNext Commercial Version 4.5