PIC10F322 LED blinking using timer and interrupt

Discussion in 'Embedded Systems and Microcontrollers' started by killerfish, Jan 10, 2019.

  1. killerfish

    Thread Starter Member

    Feb 27, 2009
    27
    4
    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 (Text):
    1. #define _XTAL_FREQ 16000000
    2. #include <xc.h>
    3.  
    4. #pragma config FOSC = INTOSC    // Oscillator Selection bits (INTOSC oscillator: CLKIN function disabled)
    5. #pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
    6. #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
    7. #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
    8. #pragma config MCLRE = OFF       // MCLR Pin Function Select bit (MCLR pin function is MCLR)
    9. #pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
    10. #pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
    11. #pragma config LPBOR = ON      // Brown-out Reset Selection bits (BOR disabled)
    12. #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
    13. #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
    14.  
    15. int z = 0;
    16. unsigned long int count=0;
    17. void main(void) {
    18.  
    19.     ANSELA = 0x00;
    20.  
    21.     TRISA = 0b0100;
    22.     TRISAbits.TRISA2 = 1;
    23.     LATAbits.LATA0 = 0;
    24.  
    25.     INTCONbits.GIE=1;        /* Enable Global Interrupt*/
    26.     INTCONbits.PEIE = 1;  /* Enable peripheral Interrupt */
    27.  
    28.     OPTION_REGbits.T0CS = 0;
    29.  
    30.     OPTION_REGbits.PSA = 1;
    31.     //OPTION_REGbits.PS0 = 1; /* set prescaler to 256 */
    32.     //OPTION_REGbits.PS1 = 1;
    33.     //OPTION_REGbits.PS2 = 1;
    34.     OPTION_REGbits.INTEDG = 0;
    35.     TMR0 = 0;
    36.     INTCONbits.TMR0IF = 0;
    37.     INTCONbits.TMR0IE = 1;
    38.  
    39.     while(1){
    40.     }
    41.  
    42.    return;
    43. }
    44.  
    45.  
    46. void __interrupt(high_priority) tcInt(void)
    47. {
    48.  
    49.         INTCONbits.TMR0IF = 0;
    50.      
    51.         if (count == 15625)
    52.         {
    53.             z = 0;
    54.             LATAbits.LATA0 = ~LATAbits.LATA0;
    55.             count =0;
    56.         }
    57.      
    58.         ++count;
    59.  
    60. return;
    61. }
    62.  
    Greatly appreciate your helps
     
    Last edited: Jan 11, 2019
  2. JohnInTX

    Moderator

    Jun 26, 2012
    3,392
    1,714
    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.
     
  3. killerfish

    Thread Starter Member

    Feb 27, 2009
    27
    4
    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.
     
  4. ericgibbs

    Moderator

    Jan 29, 2010
    6,573
    1,276
    hi killer,
    Why have you chosen 256 as the multiplier.?
    E
    I will recheck my test program timing, getting some unexpected results.???
     
    Last edited: Jan 11, 2019
  5. killerfish

    Thread Starter Member

    Feb 27, 2009
    27
    4
    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.
     
  6. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,832
    1,626
    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'.
     
    killerfish and JohnInTX like this.
  7. killerfish

    Thread Starter Member

    Feb 27, 2009
    27
    4
    Thank you!!! :D Finally it worked!

    Noob me because I thought by defining XTAL frequency should set it.
     
    Last edited: Jan 11, 2019
  8. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,832
    1,626
    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.
     
    killerfish likes this.
  9. killerfish

    Thread Starter Member

    Feb 27, 2009
    27
    4
    Good idea. Will do....:)
     
Loading...