Connect with us

How do I make hour-long delay with mid-range PIC?

Discussion in 'Microcontrollers, Programming and IoT' started by max_torch, Nov 30, 2015.

Scroll to continue with content
  1. max_torch

    max_torch

    111
    1
    Feb 9, 2014
    I only know how to make short delays. How do I make an hour-long delay used to perform an hourly interrupt (ISR is about transferring data to EEPROM). I am using mid-range PIC or PIC16F628A or PIC16F877A or other similar ones. The timing has to be independent of the main processor. Should I use TMR0, TMR1, or TMR2? Will I need to use a second external crystal oscillator, and will it have to be 32.768KHz?
     
  2. Harald Kapp

    Harald Kapp Moderator Moderator

    10,999
    2,502
    Nov 17, 2011
    I wouldn't "waste" a timer for this purpose - they aren't meant to be used on that time scale anyway.
    Do you have some kind of a clock routine in your code? Then use this to generate a software interrupt (or call to the equivalent subroutine) every hour.
    If you don't have a clock routine, make one by using a simple counter that is incremented e.g. every second or millisecond and which triggers the sw-interrupt (or call) when it reaches a count that is equivalent to 1hour (e.g. 3600 seconds).
     
  3. max_torch

    max_torch

    111
    1
    Feb 9, 2014
    I don't know how I could make an accurate clocking routine in the main code since the main code is not a consistent repetitive loop, it takes different amounts of time to process the incoming data. I don't know how to embed an accurate counter in the main code in this circumstance, that's why I was thinking if I should use one of the TMR peripherals and have a separate oscillator for it..
    The timing of the one hour has to occur while the microcontroller is processing data.
     
  4. Harald Kapp

    Harald Kapp Moderator Moderator

    10,999
    2,502
    Nov 17, 2011
    You don't have to.
    Use a timer to create e.g. a millisecond interrupt, then count milliseconds. Reset the millisecond counter when it has reached 3600000 ant the 1hour interrupt (or subroutine call) has been activated.
     
  5. Sadlercomfort

    Sadlercomfort Ash

    424
    55
    Feb 9, 2013
    You need to create a timer0 interrupt routine of 60 seconds. Then your subroutine for the interrupt should include a count variable, which counts to 60 (60s x 60 = 1 hour).

    To do this you need to work out the value of TMR0 using this formula:
    Freq. out = Freq. osc / [prescaler * (256 - TMR0) * count]


    Simply rearrange to make TMR0 the subject.





    Here's a basic example which flashes an LED.


    Code:
    volatile char counter = 0;
    
    void interrupt Timer0_ISR(void)
    {
        if (counter ==16)
        {
        goto flash_led;
        }
        counter++;
        return;
         
    
    flash_led:
    //Set LED HIGH
    return; 
    }
    
    
    void main(void)
    {
    ADCON1 = 0b00000111;
    TRISA=0b00000000;
    TRISB=0b00000001;            //Initialise I/O ports  (RB0 set as output)
    TRISC=0b00000000;          //Initialise I/O ports
    PORTA=0b00000000;
    PORTB=0b10000000;          //Initialise I/O ports
                       
    TMR0=6;
    OPTION_REG=0b01000000;    //Enable Rising Edge Trigger
    TMR0IE=1;                       //Enable TMR0 Overflow Interruprt
    GIE=1;                           //Enable Global Interrupt
    
    
    
        while(1)
        {
        }
    }
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-