PIC10F322 LED blinking using timer and interrupt

Thread Starter

killerfish

Joined Feb 27, 2009
29
Hi All,
This is my first time working on PIC chip, so I started by blinking an LED using timer and interrupt first. I wanted it to On for 1s and then Off for another 1s. I had tried coded the timer called for interrupt, and it work good. But the counting for time isn't correct. The counting was On for about 2s and then Off for another 2s, which is isn't correct. Is there something wrong with the calculation or is there a misunderstanding? The chip is 16MHZ, timer0 is 8 bits and no prescaler.

My formulas is:
Fosc/4 = 16MHZ/4 = 4MHZ ( no prescaler)

period for a tick= 1 / 4MHZ = 0.00000025s

time for 8 bit count = 0.00000025 * 256 = 0.000064s

Loop count = 1/0.000064 = 15625

my code:

Code:
#define _XTAL_FREQ 16000000
#include <xc.h>

#pragma config FOSC = INTOSC    // Oscillator Selection bits (INTOSC oscillator: CLKIN function disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF       // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
#pragma config LPBOR = ON      // Brown-out Reset Selection bits (BOR disabled)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)

int z = 0;
unsigned long int count=0;
void main(void) {
 
    ANSELA = 0x00;

    TRISA = 0b0100;
    TRISAbits.TRISA2 = 1;
    LATAbits.LATA0 = 0;

    INTCONbits.GIE=1;        /* Enable Global Interrupt*/
    INTCONbits.PEIE = 1;  /* Enable peripheral Interrupt */

    OPTION_REGbits.T0CS = 0;

    OPTION_REGbits.PSA = 1;
    //OPTION_REGbits.PS0 = 1; /* set prescaler to 256 */
    //OPTION_REGbits.PS1 = 1;
    //OPTION_REGbits.PS2 = 1;
    OPTION_REGbits.INTEDG = 0;
    TMR0 = 0;
    INTCONbits.TMR0IF = 0;
    INTCONbits.TMR0IE = 1;
 
    while(1){
    }
 
   return;
}


void __interrupt(high_priority) tcInt(void)
{

        INTCONbits.TMR0IF = 0;
     
        if (count == 15625)
        {
            z = 0;
            LATAbits.LATA0 = ~LATAbits.LATA0;
            count =0;
        }
     
        ++count;

return;
}
Greatly appreciate your helps
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,377
Can’t check the math right now but at line 51 try 15625L to specify a long constant. That value will also fit into an int.
Same for line 16.
 

Thread Starter

killerfish

Joined Feb 27, 2009
29
Can’t check the math right now but at line 51 try 15625L to specify a long constant. That value will also fit into an int.
Same for line 16.
Changed as per your advise. It doesn't made any different.

Funny I don't get it why. Cross checked with my oscilloscope, it showed 2s high and 2s low LED signal exact.
 

ericgibbs

Joined Jan 29, 2010
11,906
hi killer,
Why have you chosen 256 as the multiplier.?
E
I will recheck my test program timing, getting some unexpected results.???
 
Last edited:

Thread Starter

killerfish

Joined Feb 27, 2009
29
hi killer,
Why have you chosen 256 as the multiplier.?
E
I will recheck my test program timing, getting some unexpected results.???
2^8=256

0.00000025s * 256 = 0.000064s

The 8 bits timer count from 0 to 255 and then overflow will occur. It also mean the interrupt will be trigger 255 times and check whether the count has hit 1 second in my program.

Hope I am right till here.
 

AlbertHall

Joined Jun 4, 2014
10,909
You are using the internal clock but haven't selected a frequency. The default frequency is 8MHz so, when the program is expecting 16MHz, everything takes twice as long.
You need to set OSCCON IRCF to '111'.
 

Thread Starter

killerfish

Joined Feb 27, 2009
29
You are using the internal clock but haven't selected a frequency. The default frequency is 8MHz so, when the program is expecting 16MHz, everything takes twice as long.
You need to set OSCCON IRCF to '111'.
Thank you!!! :D Finally it worked!

Noob me because I thought by defining XTAL frequency should set it.
 
Last edited:

AlbertHall

Joined Jun 4, 2014
10,909
I thought by defining XTAL frequency should set it.
That just tells your program what the clock frequency is. I think the only standard thing that uses it is the delay macro - __delay_us() and __delay_ms() - but you can use it yourself. For instance you might modify your flashy LED program to work correctly with a wide range of clock frequencies by automatically setting the 15625 value appropriately.
 

Thread Starter

killerfish

Joined Feb 27, 2009
29
That just tells your program what the clock frequency is. I think the only standard thing that uses it is the delay macro - __delay_us() and __delay_ms() - but you can use it yourself. For instance you might modify your flashy LED program to work correctly with a wide range of clock frequencies by automatically setting the 15625 value appropriately.
Good idea. Will do....:)
 
Top