Timer1 Calculator error?

Timer1 Calculator error?

Postby momiccioli » Thu Jul 18, 2019 3:10 pm

Hello,

I am teaching my self PIC programming (Oh no another noob!). Actually my code is working I have verified it by checking with an Oscilloscope. I created a simple blinking circuit and I am using Timers 0,1 and 2 to blink at different rates. I used a Timer calculator to get the rates that I am looking for. However The calculator produce spot on numbers for Timer0. Timer1 and Timer2 are off, I have tried this with 2 calculators and they all agree on the settings. When I used those settings the rate was off and I backed into the values that work.

Timer0 1 Sec, Timer1 4 Sec and Timer2, 2 sec. As I have said I have this working but I had to tweak the preload for TMR1H and TMR2. The calculators say to use 0xB for T1 but that is giving me a 5 Sec rate. If I set TMR1H to 0xE I get a 4Sec rate and the Oscilloscope confirms it. What I would like to know is why? Hopefully someone can fill in the blanks.

I have been all through the data sheet and I either dont understand something or I have missed something. Here are the details including the program. If you need additional info I can provide. My assumption is I am missing something simple.

Thanks

Chip: PIC12F1572
Programmer: PICKIT4
Compiler: XC8-22 (V2.05)
MPLAB: 5.20
CPU Clock speed: 125Hz

Code: Select all
Timer Settings I am using
Timer   Prescaler   Incs/Sec    Count   PostScaler  Preload HZ      Secs    Period  Actual
0       256         122.07      256     1           133     0.99    1.008   2.02    134
1       2           15,625.00   65536   1           3044    0.25    3.999   8.00    3764
2       64          488.28      256     5           60      0.50    2.007   4.01    98



Code: Select all
/*
 * PIC12F1572.
 *
 * Pins:
 *                     +----+
 *                Vdd -|1  8|- Vss
 *                RA5 -|2  7|- RA0/ICSPDAT ESUART TX
 *                RA4 -|3  6|- RA1/ICSPLCK ESUART RX
 *           RA3/MCLR -|4  5|- RA2
 *                     +----+
 */

#pragma config FOSC = INTOSC  // INTOSC oscillator: I/O function on CLKIN pin.
#pragma config WDTE = OFF     // Watchdog Timer disable.
#pragma config PWRTE = OFF    // Power-up Timer enbable.
#pragma config MCLRE = ON     // MCLR/VPP pin function is MCLR.
#pragma config CP = OFF       // Program memory code protection disabled.
#pragma config BOREN = ON     // Brown-out Reset enabled.
#pragma config CLKOUTEN = OFF // CLKOUT function is disabled; I/O or oscillator function on the CLKOUT pin.
#pragma config WRT = OFF      // Flash Memory Write protection off.
#pragma config STVREN = ON    // Stack Overflow or Underflow will cause a Reset.
#pragma config BORV = LO      // Brown-out Reset Voltage (Vbor), low trip point selected.
#pragma config LVP = OFF      // High-voltage on MCLR/VPP must be used for programming.

#include <xc.h>

#define _XTAL_FREQ 500000   // Oscillator frequency.

void init_pic();
void __interrupt() interrupt_handler(void);

//------------------------------------------------------------------------------
// Main Program Loop
//------------------------------------------------------------------------------
int main() {
    init_pic();

    TRISAbits.TRISA5    = 0;
    LATAbits.LATA5      = 1; // Turn the LED on
    TRISAbits.TRISA2    = 0; // UART RX pin an input.
    LATAbits.LATA2      = 1; // Turn the LED on
    TRISAbits.TRISA4    = 0; // UART RX pin an input.
    LATAbits.LATA4      = 1; // Turn the LED on

    while (1) {
    }
}

//------------------------------------------------------------------------------
// Interrupt Handler
//------------------------------------------------------------------------------
void __interrupt() interrupt_handler(void) {
    if (INTCONbits.TMR0IF == 1) {
        INTCONbits.TMR0IF = 0;
        TMR0 = 134;
        LATAbits.LATA4 = ~PORTAbits.RA4;
    }

    if (PIR1bits.TMR1IF == 1) {                     // This is the 4 second timer
        PIR1bits.TMR1IF = 0;
        /*** Note ***
        setting TMR1H to 0xE gives a period width of 8, I had to back into this value
        setting TMR1H to 0xB gives a period width of 10, Calculator gives this value */
        TMR1H = 0xE;      // preset for timer1 MSB register
        TMR1L = 0xE4;     // preset for timer1 LSB register
        LATAbits.LATA2 = ~PORTAbits.RA2;
    }

    if (PIR1bits.TMR2IF == 1) {
        PIR1bits.TMR2IF = 0;
        TMR2 = 98;
        PR2 = 98;
        LATAbits.LATA5 = ~PORTAbits.RA5;
    }
}

//------------------------------------------------------------------------------
// Initialization Routine
//------------------------------------------------------------------------------
void init_pic() {
    OSCCONbits.SPLLEN = 0;    // PLL Enable
    OSCCONbits.IRCF   = 5;    // CPU Frequency 125 kHz
    OSCCONbits.SCS    = 0b00; // System Clock

    ANSELA = 0; // Analog off
    // Timer0 Settings ---------------------------------------------------------
    INTCONbits.TMR0IE     = 1; // Timer0 enable
    INTCONbits.TMR0IF     = 0; // Timer0 Overflow flag 
    OPTION_REGbits.PS     = 7; // Timer0 Pre-scaler Rate 256
    OPTION_REGbits.PSA    = 0; // Timer0 Pre-scaler Assignment
    OPTION_REGbits.TMR0SE = 0; // Timer0 Source Edge Select bit
    OPTION_REGbits.TMR0CS = 0; // Timer0 Clock Source Select bit
    TMR0 = 0;

    // Timer1 Settings ---------------------------------------------------------
    // Prescaler=1:2; TMR1 Preset=3044; Freq=2.00038Hz; Period=499,968,000 ns
    // ISR Timeout cycles:4T1CONbits.TMR1ON  = 1; // Timer1 On/Off
    T1CONbits.TMR1CS  = 0; // bit 1 Timer1 Clock Source Select bit: 0=Internal clock (FOSC/4) / 1 = External clock from pin T13CKI (on the rising edge)
    T1CONbits.T1CKPS1 = 0; // Timer1 Input Pre-scaler bits
    T1CONbits.T1CKPS0 = 1; // Timer1 Input Pre-scaler bits
    T1CONbits.nT1SYNC = 1; // bit 2 Timer1 External Clock Input Synchronization Control bit: 1=Do not synchronize external clock input
   
    PIR1bits.TMR1IF   = 0; // Timer1 Flag
    PIR1bits.TMR1GIF  = 0; // Timer1 Gate Flag
    T1GCONbits.TMR1GE = 0; // Timer1 Gate enable ignored if TMR1ON is 1
    T1GCONbits.T1GPOL = 0; // Timer1 Gate polarity
    T1GCONbits.T1GTM  = 0; // Timer1 Gate Toggle
    T1GCONbits.T1GSPM = 0; // Timer1 Pulse mode
    T1GCONbits.T1GGO_nDONE = 0;
    T1CONbits.TMR1ON  = 1; // bit 0 enables timer
   
    /*** Note ***
        setting TMR1H to 0xE gives a period width of 8, I had to back into this value
        setting TMR1H to 0xB gives a period width of 10, Calculator gives this value */
    TMR1H = 0xE;       // preset for timer1 MSB register)
    TMR1L = 0xE4;      // preset for timer1 LSB register


    // Timer2 Settings ---------------------------------------------------------
    T2CONbits.TMR2ON =  1; // Timer2 On/Off
    PIR1bits.TMR2IF =   0; // Timer2 Overflow flag
    T2CONbits.T2CKPS =  3; // Timer2 Pre-scaler 64
    T2CONbits.T2OUTPS = 9; // Timer2 Post scaler 5
    PIE1bits.TMR2IE =   0; // TMR2 to PR2 Match Interrupt Enable bit
    TMR2 = 0; // 8 bit register
    PR2 = 0; // 8 bit register

    OPTION_REGbits.INTEDG = 0b0; // Interrupt Edge Select bit
    OPTION_REGbits.nWPUEN = 0b1; // WPUx registers
    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;
    INTCONbits.INTE = 0;
    INTCONbits.IOCIE = 1;
    INTCONbits.INTF = 0;
    INTCONbits.IOCIF = 1;
momiccioli
 
Posts: 1
Joined: Thu Jul 18, 2019 2:19 pm

Re: Timer1 Calculator error?

Postby vloki » Fri Jul 19, 2019 10:10 am

Both interrupts for timer1 and timer2 are not enabled,
so the code to rewrite them is only executed if timer0 fires.

You can check this in the simulator and see what values TMR1 and TMR2
have when you rewrite them. (TMR2 is 84 and TMR1 is 769)

I wonder why timer2 is running at all with the code you provided.
I had to reconfigure PR2 in the init to get it started. (maybe a problem in simulator only)

Furthermore you should not preload t2. Forget that preload calculator here.
For T2 you specify the period () and thats it.

Guess you want to play with the 16-BIT PULSE-WIDTH MODULATION (PWM) MODULE
when you are done with this basic timer stuff?
vloki
Verified identity
 
Posts: 186
Joined: Wed May 28, 2014 8:42 am
Location: Germany
PIC experience: Professional 5+ years with MCHP products


Return to Timers

Who is online

Users browsing this forum: No registered users and 1 guest

cron