Hot!PIC12F675 Timer Example

Author
pulse1
New Member
  • Total Posts : 6
  • Reward points : 0
  • Status: offline
2011/12/13 07:05:20 (permalink)
5 (1)

PIC12F675 Timer Example

Hello all,
 
I have a PIC12F675 setup with the internal oscillator at 4Mz. I have GP4 and GP5 connected to LEDs and have selected GP2 as an analogue input. The PIC main program cannot be copied here since the line of work i'm in prohibits it, I can however tell you I am need of a 1second timer in C language. I'm using a HI-TECH C lite compiler, MPLAB IDE 8.8 and PICkit3 icd.
 
I have delay functions already in my program, however I'm in need of a function that starts a 1 second timer then lets the PIC move on to do other things.
 
I'm a hardware engineer so i'm new to software but I am interested in learning this so I'm not looking for code to copy and paste, I'd like to figure it out so any help would be appretiated. I've checked the forums for my question but have come up short thus far so even a link to a thread which is useful might assist me in my work.
 
Cheers!
#1

13 Replies Related Threads

    1and0
    Access is Denied
    • Total Posts : 8701
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re:PIC12F675 Timer Example 2011/12/13 07:24:14 (permalink)
    0
    Setup Timer0 or Timer1 for an ~1 ms (or other interval) interrupt.  Inside the ISR, increment a counter and set a flag when this counter reaches one second.
    #2
    pulse1
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Status: offline
    Re:PIC12F675 Timer Example 2011/12/13 08:03:18 (permalink)
    0
    ISR = Interrupt Service Handler
     
    My understanding is that this differs from a normal function I would call up in my main program, because it only executed when an interrupt takes place (IE when my counter over flows). This is how I have my code at the moment, the exact details I'm still trying to pluck from the datasheet.
     
    NOTE: COMMENTS ARE WHERE CODE SHOULD BE
     
    //I assume INTCLK is set to 4MHz somehow but I have not set it in my code as it stands so I'm a little unsure if I really do have 4MHz
     
    OPTION_REG=0b11000111; //WPU disabled, Interrupt on rising edge INT pin, Prescaler Rate Select bits = 1 : 256
     
    void interrupt ()
    {
     //set timer value IE max is 255 for Timer0
     //reset interrupt flag to 0
     //increment a variable by 1
    }
     
    void main (void)
    {
        while(1)
        {
        //reset Timer0
            if (/*timervariable is <1second*/)
            {
            }
            else
            {
            break;
            }
    }
     
    I'm a little unsure as to the syntax for this code, so i'm checking my PIC12F675 datasheet but if someone can fill in the blanks it would save me a lot of time.
     
    My plan is to make a simple timer program which after 1second toggles an LED, this will be a good start from there I can manipulate what I have written into the more complex program I have already created.
     
    I hope I have the main building blocks in my code example above, or am I missing something?
    #3
    WaltR
    Super Member
    • Total Posts : 3759
    • Reward points : 0
    • Joined: 2003/11/07 12:38:21
    • Status: offline
    Re:PIC12F675 Timer Example 2011/12/13 08:09:44 (permalink)
    0
    Here is an example of the technique stated by 1and0:
    http://forum.sparkfun.com...ic.php?f=6&t=22429

    Look in the third file at the ISR and MAIN functions for Sys_task_counter and Sys_tick_f.
    #4
    pulse1
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Status: offline
    Re:PIC12F675 Timer Example 2011/12/13 08:41:54 (permalink)
    0
    Thanks to all for the helpful comments, I shall get to work now and post back if I get really stuck in the mud.
     
    Cheers!
    #5
    pulse1
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Status: offline
    Re:PIC12F675 Timer Example 2011/12/14 03:17:35 (permalink)
    0
    Hi all,
     
    This is my first attempt at a TIMER0 1second counter, please let me know what you think.
     
    I expected the code to toggle GP4 output high and low every second, but I'm not see that result.
     
    At first I have two if statements which made GP4 stays on
     
    Then I changed it to else if for the second expression and now GP4 stays off
     
    Thoughts/comments/suggestions much appreciated.
     
    Cheers!
     
    source code below and source files attached.
     
    // Filename:   Timer.c
    // Author:    JS  
    // Revision:   Ver 0.1
    // Programming Device: PICKit 3 (PIC12F675)              
    // Complier:   HI-TECH ANSI C Complier                     
    // IDE:     Microchip MPLAB IDE v8.80
    // Last Updated:  14/12/2011                           /* Changelog:
    V0.1
    timer0 configured and GP4 and GP5 set to alternate on/off every 1second */
    /*Configuration Bits - not set in code        
    BG1:BG0 (Bandgap Calibration Bits for BOD and POR voltage)=    DEFAULT  
    FOSC2:FOSC0 (Oscillator selection Bits) = 100           INTOSC oscillator:I/O function on GP4/OSC2/CLKOUT pin,       
                      I/O function GP5/OSC1/CLKIN    
    WDTE - Watchdog Timer Enable bit - WDT disabled             
    PWRTE - Power-up Timer bit - PWRT disabled             
    MCLRE - GP3/MCLR pin function select - GP3/MCLR pin function is MCLR               
    BOREN - Brown-out detect Enable bit - BOD disabled              
    CP - Code Protection bit - Program Memory code protection is disabled    
    CPD - Data Code Protection bit - Data memory code protection is disabled
    */         // Header Files                   
    #include <pic.h>  //Header file for libpicio (pic_read, pic_write, ...)
    #include <htc.h>  //This file identifies the processor being used and calls other include files as appropriate
    #include <stdio.h>  //Standard Input and Output Library Header file, contains macro definitions, constants, and declarations of functions
          //and types used for various standard input and output operations.
    #include <pic12f675.h> //Header file containing PIC12F675 Register definitions /*
    Timer init values TMR0 timer and pre-scaler - pre-scale of 1 to 64, (2, 4, 8, 16, 32, 64, 128, 256) prescaler = 1:64, set prescaler in option_reg to PS_256 TMR0 prescale = 1:64, OPTION_REG, bits 2-0 = 101
    prescaler assignment = TMR0, OPTION_REG bit 3 = 0
    TMR0 clock source = Instr cycle, OPTION_REG, bit 5 = 0 4MHz Fosc/4 = 1MHz INTCLK
    1MHz INTCLK/64 Prescaler = 15.626KHz Clock sent to TMR0 register
           = 15625 Prescaler clock cycles per second.
           = time for one cycle = 1/Prescaler Clock Frequency = 64us
       
      Sys_tick_counter = 1s/64us = 15625 decimal value, when reached can be used to display a second has been counted
           = 500ms/64us = 7813 decimal value, when reached can be used to display half a second has been counted
           = 250ms/64us = 3906 decimal value, when reached can be used to display quarter of a second has been counted       I want a 1 second counter, so Sys_tick_counter will equal 15625 (1sec)
    */
    #define TMR0_cnt   255    // value to be subtracted away from timer0 register (max of 255 allowed)
    #define Sys_tick_counter 15625 // max value of //Variables
    unsigned int Timerfinished; //shows when the timer count has reached 1second
    unsigned int alarmledon; //shows when the status of the alarm led
    unsigned int Sys_tick; //timer0 overflow/interrupt count value // Functions in the program               
    void initialise (void); // Function's name: initialise            
    //  Function:   Sets up the PIC12F675 I/O ports functionality    
    void initialise (void)
    {
     VRCON=0x00;    //Disable voltage reference
     CMCON=0b00000111;   //Disable comparator
     ANSEL=0x00;    //A/D disabled       
     GPIO=0;     //Clear GPIO
     TRISIO=0b00001111;  //Set GPIO4 AND GPIO5 as outputs. Set GPIO0, GPIO2, GPI01 and GPIO3 as inputs
     WPU=0;      //Disable all weak pull up 
     OPTION_REG=0b00000101;   //Timer0 Prescaler 1:2
     T1CON=0x00;    //Timer1 disabled
    } // Interrupt Sub Routine
    void interrupt isr(void)
    {
     if((T0IE==1) && (T0IF==1)) //If TMR0 Overflow Interrupt Enable bit and T0IF: TMR0 Overflow Interrupt Flag bit equal 1, interrupt.
     { // every 64us
     T0IF = 0;
     TMR0 = TMR0_cnt;
     Sys_tick++;
         if (Sys_tick_counter==15625)
      {
      Timerfinished=1;
      Sys_tick=0;
      }  
        }
    }  // // Main Program                       
    void main(void)
    {
    initialise();  //Initialise
    Timerfinished=0; //Set timer finished indicator to zero
    TMR0 = TMR0_cnt; //Set timer0 to 255
    Sys_tick=0;
     while(1)
     {
      if((Timerfinished==1)&&(alarmledon==0)) //if 1second timer has finished and alarm led is off
      {
      GPIO4=1; //enable alarm led
      alarmledon=1; //alarm led is on
      }
      
      else if((Timerfinished==1)&&(alarmledon==1)) //if 1second timer has finished and alarm led is on
      {
      GPIO4=0; // disable alarm led
      alarmledon=0; //alarm led is off
      } 
     }
    }

    #6
    pulse1
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Status: offline
    Re:PIC12F675 Timer Example 2011/12/14 05:21:17 (permalink)
    0
    fdan00
    did you enable the global interrupt?

    not sure what tmr1 is doing there.

    INTCON register bit 7
     
    GIE=1; //added to initialise function, to turn on Global Interrupt Enable
     
    removed timer1 since it is not used
    T1CON=0x00;    //Timer1 disabled
     
    still no flashy led, not sure if my timer0 values are correct.
     
    My working out is as follows
    Fosc        =4MHz
    INTCLK    =Fosc/4    =1MHz
    Timer0CLK=1MHz/Prescaler    =1MHz/64=15625
     
    Timer0 Tcyc time =1/Timer0CLK    =64us
     
    if I load timer0 with 255 count, it will take 16.32ms (64usx255) to interrupt once.
     
    I want a 1second timer so
    1s/16.32ms= 61 interrupt counts to indicate 1second has been counted.
     
    going to continue scratching head until it makes sense
     
     
     
    Cheers!
     
    #7
    pulse1
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Status: offline
    Re:PIC12F675 Timer Example 2011/12/14 06:48:23 (permalink)
    +1 (2)
    fdan00

    you didn't enable tmr0 interrupt and global interrupt.

    after fixing that and commenting out the tmr0 offset loading, the code behaved as expected: the code kept gp4 low for ~4ms, and in the isr, it sets Timerfinished (because Sys_tick_counter is always 15625). after that, it flips gp4.

    Hi fdan00,
     
    I've made those changes plus a couple of other things I spotted wrong with my code and have reuploaded the final working code for anyone else who needs it.
     
    Thankyou All, for your time and help, i'm gonna sign off now and start patching this code into my project program.
     
    Regards.
     
    GP4 output on PIC12F675 toggled every 1.0 seconds with the below source code  

     
    // Filename:   Timer.c 
    // Author:    JS  
    // Revision:   Ver 1.0
    // Target Device:  PIC12F675  
    // Programming Device: PICKit 3 (PIC12F675)              
    // Complier:   HI-TECH ANSI C Complier                     
    // IDE:     Microchip MPLAB IDE v8.80
    // Last Updated:  14/12/2011                           /* Changelog:
    V1.0
    */
    /*Configuration Bits - not set in code        
    BG1:BG0 (Bandgap Calibration Bits for BOD and POR voltage)=    DEFAULT  
    FOSC2:FOSC0 (Oscillator selection Bits) = 100           INTOSC oscillator:I/O function on GP4/OSC2/CLKOUT pin,       
                      I/O function GP5/OSC1/CLKIN    
    WDTE - Watchdog Timer Enable bit - WDT disabled             
    PWRTE - Power-up Timer bit - PWRT disabled             
    MCLRE - GP3/MCLR pin function select - GP3/MCLR pin function is MCLR               
    BOREN - Brown-out detect Enable bit - BOD disabled              
    CP - Code Protection bit - Program Memory code protection is disabled    
    CPD - Data Code Protection bit - Data memory code protection is disabled
    */         // Header Files                   
    #include <pic.h>  //Header file for libpicio (pic_read, pic_write, ...)
    #include <htc.h>  //This file identifies the processor being used and calls other include files as appropriate
    #include <stdio.h>  //Standard Input and Output Library Header file, contains macro definitions, constants, and declarations of functions
          //and types used for various standard input and output operations.
    #include <pic12f675.h> //Header file containing PIC12F675 Register definitions #define Sys_tick_counter 60 //Timer0 interrupt count to make a 1second flag //Variables
    unsigned int Timerfinished; //shows when the timer count has reached 1second
    unsigned int alarmledon; //shows when the status of the alarm led
    unsigned int Sys_tick; //timer0 overflow/interrupt count value // Functions in the program               
    void initialise (void); // Function's name: initialise            
    //  Function:   Sets up the PIC12F675 I/O ports functionality    
    void initialise (void)
    {
     VRCON=0x00;    //Disable voltage reference
     CMCON=0b00000111;   //Disable comparator
     ANSEL=0x00;    //A/D disabled       
     GPIO=0;     //Clear GPIO
     TRISIO=0b00001111;  //Set GPIO4 AND GPIO5 as outputs. Set GPIO0, GPIO2, GPI01 and GPIO3 as inputs
     WPU=0;      //Disable all weak pull up 
     OPTION_REG=0b00000101;  //Timer0 Prescaler 1:64
     INTCON=0b10100000;  //Global Interrupt Enabled and TMR0 Overflow Interrupt Enabled
    } // Interrupt Sub Routine
    void interrupt isr(void)
    {
     if((T0IE==1) && (T0IF==1)) //If TMR0 Overflow Interrupt Enable bit and T0IF: TMR0 Overflow Interrupt Flag bit equal 1, interrupt.
     { // every 64us
     T0IF = 0;
     Sys_tick++;
         if (Sys_tick>=Sys_tick_counter)
      {
      Timerfinished=1;
      Sys_tick=0;
      }  
        }
    }  // // Main Program                       
    void main(void)
    {
    initialise();  //Initialise
    Timerfinished=0; //Set timer finished indicator to zero
    Sys_tick=0;
     while(1)
     {
      if((Timerfinished==1)&&(alarmledon==0)) //if 1second timer has finished and alarm led is off
      {
      GPIO4=1; //enable alarm led
      alarmledon=1; //alarm led is on
      Timerfinished=0; //Set timer finished indicator to zero
      Sys_tick=0;
      }
      
      else if((Timerfinished==1)&&(alarmledon==1)) //if 1second timer has finished and alarm led is on
      {
      GPIO4=0; // disable alarm led
      alarmledon=0; //alarm led is off
      Timerfinished=0; //Set timer finished indicator to zero
      Sys_tick=0;
      } 
     }
    }
     

    post edited by pulse1 - 2011/12/14 07:09:43
    #8
    jack21
    New Member
    • Total Posts : 2
    • Reward points : 0
    • Joined: 2012/06/01 10:09:03
    • Location: 0
    • Status: offline
    Re:PIC12F675 Timer Example 2012/06/02 08:07:18 (permalink)
    0
    hi every one, i have a program to show you and i'm not ver good at pics,please i need help from you ,i'm not very good at pics.tell me what should i do,regards!here is my code:
     
    //Led clignotante sur Port GPIO
    #include <pic12rf675.h> // includ le fichier pic12f675
    #include <delay.c> //includ le fichier delay en µs
    #include <delay.h>

    void main()
    {
    TRISIO0 = 1 ; //GPIO0 configuré en entrée
    TRISIO1 = 0 ; //GPIO1 configuré en sortie
    TRISIO2 = 0 ; //GPIO2 configuré en sortie
    TRISIO3 = 0 ; //GPIO3 configuré en sortie
    TRISIO4 = 1 ; //GPIO4 configuré en entrée
    TRISIO5 = 0 ; //GPIO5 configuré en sortie
    ANSEL   = 0x41 ; //pin AN0 is configured as analog
    ADCON   = 0xC3 ; // reference voltage is Vdd
    while(1)
        {
    GPIO4 = GPIO5 ;
    GPIO5 = 1 ;
    delayMs    (1000);
    GPIO5 = 0 ;
    delayMs(9000);
        }
    do
    {
    if(GPIO0==x)
    }
        GPIO0 = GPIO1 ;
        GPIO1 = 1 ;
        GPIO2 = 0;
        GPIO3 = 0;
    }
    else if(GPIO==x)
    {
        GPIO0 = GPIO2 ;
        GPIO2 = 1 ;
        GPIO1 = 0 ;
        GPIO3 = 0 ;
    }
    else
    {
        GPIO0 = GPIO4 ;
        GPIO3 = 1 ;
        GPIO1 = 0 ;
        GPIO2 = 0 ;
    }
    }
    }
    #9
    vl
    Super Member
    • Total Posts : 222
    • Reward points : 0
    • Joined: 2012/05/15 22:29:27
    • Location: 0
    • Status: offline
    Re:PIC12F675 Timer Example 2012/06/02 08:33:51 (permalink)
    #10
    The Lightning Stalker
    New Member
    • Total Posts : 3
    • Reward points : 0
    • Joined: 2013/05/24 08:47:34
    • Location: 0
    • Status: offline
    Re:PIC12F675 Timer Example 2017/10/17 07:55:16 (permalink)
    +1 (1)
    pulse1GP4 output on PIC12F675 toggled every 1.0 seconds with the below source code

    Except it doesn't.  Relying on overflows alone will not get there.  What you have to do is preload the TMR0 register with the remainder of ticks.  By using a 1:32 prescaler and using the simulator to tweak the order of some lines of code, I was able to get exactly 1 second intervals.  Unfortunately this does not work for my project since Timer0 does not run in sleep mode, but here you go.
    // Filename: Timer.c
     
    // Author: JS
    // Revision: Ver x.x
    // Target Device: PIC12F675
    // Programming Device: PICkit 1 (PIC12F675)
    // Complier: XC8
    // IDE: Microchip MPLAB X IDE v4.00
    // Last Updated: 17/10/2017
    /* Changelog:
    * V1.0
    * Vx.x The Lightning Stalker exact 1s interval, ported to XC8, set CONFIG word, tested in simulator and on PICkit 1
    */
    // Why not set the CONFIG word right here?
    #pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/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 = OFF // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
    #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>
    //and types used for various standard input and output operations.
    #define Sys_tick_counter 122 //Timer0 interrupt count
    //Variables
    unsigned int Timerfinished; //shows when the timer count has reached 1second
    unsigned int alarmledon; //shows when the status of the alarm led
    unsigned int Sys_tick; //timer0 overflow/interrupt count value
    // Functions in the program
    void initialise(void); // Function's name: initialise
    // Function: Sets up the PIC12F675 I/O ports functionality
     
     
     
     
     
     
     
    void initialise(void) {
    VRCON = 0x00; //Disable voltage reference
    CMCON = 0b00000111; //Disable comparator
    ANSEL = 0x00; //A/D disabled
    GPIO = 0; //Clear GPIO
    TRISIO = 0b00001111; //Set GPIO4 AND GPIO5 as outputs. Set GPIO0, GPIO2, GPI01 and GPIO3 as inputs
    WPU = 0; //Disable all weak pull up
    INTCON = 0b10100000; //Global Interrupt Enabled and TMR0 Overflow Interrupt Enabled
    TMR0 = 240; //Preload timer register to generate first flag at 1 second
    OPTION_REG = 0b00000100; //Start Timer0 and set Prescaler to 1:32
    } // Interrupt Sub Routine
     
     
     
     
     
     
     
    void interrupt isr(void) {
    if (T0IF == 1) //If T0IF: TMR0 Overflow Interrupt Flag bit equal 1, service timer interrupt
    { // every 8192ns
    if (Sys_tick >= Sys_tick_counter) {
    Timerfinished = 1;
    TMR0 = 239; //Preload again for flag at exactly 1 second (32us overhead)
    Sys_tick = 0;
    }
    T0IF = 0;
    Sys_tick++;
    }
    } // // Main Program
     
     
     
     
     
     
     
    void main(void) {
    initialise(); //Initialise
    GPIO5 = 0; //Drive GP5 low to flash D0 on the PICkit 1
    Timerfinished = 0; //Set timer finished indicator to zero
    Sys_tick = 0;
    while (1) {
    if ((Timerfinished == 1)&&(alarmledon == 0)) //if 1second timer has finished and alarm led is off
    {
    GPIO4 = 1; //enable alarm led
    alarmledon = 1; //alarm led is on
    Timerfinished = 0; //Set timer finished indicator to zero
    Sys_tick = 0;
    } else if ((Timerfinished == 1)&&(alarmledon == 1)) //if 1second timer has finished and alarm led is on
    {
    GPIO4 = 0; // disable alarm led
    alarmledon = 0; //alarm led is off
    Timerfinished = 0; //Set timer finished indicator to zero
    Sys_tick = 0;
    }
    }
    }
     

    Also make sure to check Project Properties > XC8 Linker > Calibrate oscillator, and you will probably want to do a manual calibration as well or else it can be off by seconds every minute.
     
    I should add that this was compiled with XC8 v1.43 and the timing is somewhat dependent on the compiler. You may need to adjust by moving instructions around and trying different preloads and prescaler settings.
    post edited by The Lightning Stalker - 2017/10/18 16:55:35
    #11
    PIC_fann
    Starting Member
    • Total Posts : 81
    • Reward points : 0
    • Joined: 2018/04/09 08:11:15
    • Location: 0
    • Status: offline
    Re:PIC12F675 Timer Example 2019/02/13 07:44:45 (permalink)
    0
    Hi,
    I tested The Lightning Stalker method, and i get EXACTLY 1second interrupt. 
    But i did not want to make a simple copy paste to the code, i want to understund it...
    Can anyone explain me how he set  TMR0 = 239 ?
    Why se started with this value ? how to calculate it?
     
    Thank you in advance for your explanations.



    #12
    mbrowning
    Just a Member
    • Total Posts : 1203
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re:PIC12F675 Timer Example 2019/02/13 09:56:06 (permalink)
    0
    Necro-Necro posting !
     
    not calculated, tweaked. It's a fudge factor that might vary depending on the compiler.
    using the simulator to tweak the order of some lines of code, I was able to get exactly 1 second intervals.


    Oh well - there's always next year
    #13
    AMPS
    Super Member
    • Total Posts : 317
    • Reward points : 0
    • Status: offline
    Re:PIC12F675 Timer Example 2019/02/14 03:17:31 (permalink)
    0
    Calculation are simple. 
    formula is: value= 2^16-[(delay_ms)* crystal frequency]/4* prescalar
     2^16 or2^8 is based on timer you choose. Timer0 is 8 bit timer1 are 16 bit.
    Crystal frequency : based on config setting 4Mhz/8mhz etc
    Prescalar selected based on Datasheet in particular timer. it may be timer0/timer1
     
    if choosen pic16F886   timer1 16 bit timer 4mhz  prescallar 8 internal oscilator 8mhz need timing of 1ms
    regvalue= 65536-((1ms*8Mhz)/(4*8))
    regvalue=65536-250
    regvalue=65286
    Timer 1 value isFF06 TMR1H=FF TMR1L=06

    Amps
    *.*.*.*.*.*.*.*.*.*.*.*.*
    #14
    Jump to:
    © 2019 APG vNext Commercial Version 4.5