• AVR Freaks

Hot!Can anyone give me sample code for timer in pic16f676

Author
buildlab
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2019/06/26 11:50:03
  • Location: 0
  • Status: offline
2019/10/20 23:13:51 (permalink)
0

Can anyone give me sample code for timer in pic16f676

Hi i am new to pic programming. can anyone give me a sample code for initializing Timer 0 and making it run for 30 mins ? 
i have been working with a code which turns on a device for 30 mins, and turns off after 30 mins.
// CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator: High speed crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // RA3/MCLR pin function select (RA3/MCLR pin function is MCLR)
#pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include<pic.h>
#define _XTAL_FREQ 8000000
int readAdc(int);
int feedback_5,mpr;
int swt_1,swt_2,limit;
int counter,counter_2,sec;

void main(void) {
   PORTA = 0;
   PORTC = 0;
   TRISA = 0b000100;
   TRISC = 0b001111;
   ANSEL = 0b11110100;
   CMCON = 0x07;
   ADCON1 = 0b100;
   RC4 = 0;
   RC5 = 0;
   RA0 = 0;
   limit = 400;
    
    while(1)
       {
        feedback_5 = readAdc(2);
        mpr = readAdc(4);

 
        
        if ((feedback_5 > limit)&&(swt_1 == 0))
        {
             __delay_ms(50);
            counter = counter + 1;
            swt_1 = 1;
        }
        if ((feedback_5 < limit)&&(swt_1 == 1))
        {
            swt_1 = 0;
             __delay_ms(50);
        }
       
        if ((counter > 4)&&(mpr > limit)&&(swt_2 == 0))
        {
            RC4 = 1;
            swt_2 = 1;
            counter = 0;
        }
         if ((mpr < limit)&&(swt_2 == 1))
        {
            RC4 = 0;
            swt_2 = 5;
        }
        if ((mpr > limit)&&(swt_2 == 5))
        {
            RC4 = 1;
            swt_2 = 1;
        }
        if ((swt_2 == 1)&&(mpr > limit))
        {
            counter_2 = counter_2 + 1;                          /// integer incrementing in each step to work as a timer.
        }
        if (counter_2 > 3000)
        {
            sec = sec + 1;                                             // function of timer
            counter_2 = 0;
        }
        if (sec > 50)
        {
            RC4 = 0;
            counter = 0;
            swt_2 = 0;
            swt_1 = 0;
            sec = 0;
        }
       
    }
}
int readAdc(int channel){
    int vol;
        ADCON0 = 0x81 | (channel << 2);
       
        __delay_us(20);
        GO = 1;
        while(GO == 1);
        vol = (ADRESH << 8) + ADRESL;
        __delay_us(5);
        return vol;
}



 
i have been using an integer to increment its value each time the code runs. but i think the timer is more stable and efficent for this use.gone through the data sheet. i dont understand how to initialize it.
can anyone provide me help with a sample code to run just the timer for 30 minits so that i can understand and update my code  ?
#1

4 Replies Related Threads

    pcbbc
    Super Member
    • Total Posts : 1381
    • Reward points : 0
    • Joined: 2014/03/27 07:04:41
    • Location: 0
    • Status: offline
    Re: Can anyone give me sample code for timer in pic16f676 2019/10/21 03:14:05 (permalink)
    0
    A very simple example of TMR0 interrupts:
    //PIC16F676
    #pragma config FOSC = INTRCCLK  // Oscillator Selection bits (INTOSC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
    #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
    #pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
    #pragma config MCLRE = OFF      // RA3/MCLR pin function select (RA3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
    #pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
    #pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
    #pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

    #define _XTAL_FREQ 8000000

    //At 8MHz TMR0 with pre-scaler 1:256 will rollover at 2MHz / 65536 = 30.517Hz
    //30 minutes = 30 x 60 x 2MHz / 65536 = 54,931
    #define TICKS_PER_30MIN 54931

    #include <xc.h>
    #include <stdint.h>

    volatile uint16_t timer_counter;
    volatile uint16_t timer_flag;

    void __interrupt() ISR(void)
    {
        
        //T0 interrupt enabled and T0 interrupt fired
        if (INTCONbits.TMR0IE && INTCONbits.TMR0IF)
        {
            //If software timer is running...
            if (timer_counter)
            {
                //...decrement software timer.
                timer_counter--;
                //...check if timer popped...
                if (timer_counter == 0)
                {
                    //...set timer popped flag
                    timer_flag = 1;
                }
            }
            //Clear T0 interrupt
            INTCONbits.TMR0IF = 0;
        }
    }

    void main(void) {
        //Configure options:
        //  0 = PORTA pull-ups disabled
        //  0 = Interrupts on falling edge RA2/INT
        //  0 = TMR0 clocked from internal instruction clock
        //  0 = TMR0 increment on low-to-high transitions RA2/INT
        //  0 = Prescaler assigned to TMR0
        //  111 = TMR0 prescaler = 1:256
        OPTION_REG = 0b00000111;    

        timer_counter = TICKS_PER_30MIN;
        
        //Disable analogue pins
        ANSEL = 0;
        //All pins outputs
        TRISA = 0;
        
        //Enable T0 interrupt    
        INTCONbits.TMR0IE = 1;
        //Enable global interrupts
        INTCONbits.GIE = 1;
        
        while (1)
        {
            //If timer has popped...
            if (timer_flag)
            {
                //Toggle port pins
                PORTA ^= 0x01;
                //Reset counter atomically
                di();
                timer_counter = TICKS_PER_30MIN;
                timer_flag = 0;
                ei();
            }
        }
    }

    #2
    jack@kksound
    code tags!
    • Total Posts : 3220
    • Reward points : 0
    • Joined: 2014/05/14 10:03:19
    • Location: 0
    • Status: offline
    Re: Can anyone give me sample code for timer in pic16f676 2019/10/21 07:44:07 (permalink)
    0
    I think the timer0 on a 16F676 is an 8 bit timer not 16 bit.
    #3
    pcbbc
    Super Member
    • Total Posts : 1381
    • Reward points : 0
    • Joined: 2014/03/27 07:04:41
    • Location: 0
    • Status: offline
    Re: Can anyone give me sample code for timer in pic16f676 2019/10/21 09:08:26 (permalink)
    0
    jack@kksound
    I think the timer0 on a 16F676 is an 8 bit timer not 16 bit.

    Indeed.  timer counts from 0..255 and rolls over.
     
    OP asked for example using TMR0.  Who are we to argue?
     
    Note that I set the pre-scaler to 1:256.
    So now T0 is effectively a 16 bit counter at Fosc/4, just without access to the low order 8 bits in the pre-scaler.
    Hence why I divide by 65536 (256 timer ticks x 256 pre-scaler ticks = 65536).
    #4
    dan1138
    Super Member
    • Total Posts : 3283
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: Can anyone give me sample code for timer in pic16f676 2019/10/21 18:14:53 (permalink)
    +1 (1)
    The PIC16F676 is one of the more resource limited mid-range controllers that Microchip offers.
     
    It has just two timers and neither has a auto reload function.
     
    This makes it a challenge to code a long interval timeout that does not drift.
     
    It seems unlikely that the Original Poster(OP) wants a long winded description on the use of fraction interval dividers to realize low jitter, zero drift event notifications.
     
    It would be useful for the OP specify just how precise the 30 minute interval must be.
     
    Is plus or minus one minute close enough?
     
    Or does it need to be within one millisecond?
    #5
    Jump to:
    © 2019 APG vNext Commercial Version 4.5