0
\$\begingroup\$

I am using PIC16F886/ 4MHz external Frequency/ timer 1 (100ms)/prescaler is 1. I am trying to turn on off LED for every 100ms. In below code I need to change any setting to get exact value. or my formula is wrong.

If I do reverse calculation me getting 20Mhz

Count=65536-((Time*FOSC)/4*Prescalar))
3A98(hex)=15000
15000=65536-(time*4XMhz)/4*1
time=0.050s

OR

Count =65536-(100mS*4Mhz)/4*1
count=34464

#include <htc.h>
#define _XTAL_FREQ 4000000
__CONFIG(FOSC_HS & WDTE_ON& PWRTE_ON & CP_OFF & BOREN_ON & LVP_OFF & CPD_OFF  & DEBUG_OFF&MCLRE_ON &BOREN_ON&FCMEN_ON &WRT_OFF);
#define LED_RX RC7
unsigned char Counter=0;

void InitController() {

//  OSCCON=0X08;
    //OSCTUNE = 0x00;
    WREN=0;
    WDTCON = 0b00010111;
    PORTA    = 0b00000000;
    TRISA    = 0b00111000;
    TRISB =0b00001000;
    PORTB = 0b00000000;
    WPUB    = 0b00000000;
    ANSEL  = 0b00000000;
    ADCON0  = 0b00000000;
    TRISC = 0X00;
    PORTC = 0b00000000;
    ANSELH = 0b00000000;
    ADDEN  = 0;
    //T1OSCEN = 0;
    //INTEDG = 0; //falling edge
    //INTF = 0;
    //INTE = 1;
    PIE1=0b00000001;
    PIR1=0x01;
    INTCON = 0;
    //T1CON  = 0b00000101;
    T1CON=0X15;
    TMR1IE = 1;
    PEIE   = 1;
    GIE    = 1;

}
//===========================================================================
//                              Main program starts here.
//===========================================================================
void main(void) {
    unsigned char value;
    unsigned char conter = 0;
    InitController();

    while(1) {
    }
}

//==========================================================================
//                              Timer Interrupt - 5mSec
//==========================================================================
void interrupt isr(void) {

    asm("clrwdt");

    if (TMR1IF) {
        TMR1IF = 0;
        //  TMR1H = 0x3A;
        //  TMR1L = 0x98;
        TMR1H = 0x0B;
        TMR1L = 0xDB;
        Counter++;
        if(Counter>1) {
            Counter=0;
            LED_RX=!LED_RX;
        }
    }

}
\$\endgroup\$
1
  • \$\begingroup\$ Your Timer is working with Fosc/4 which means 1MHz \$\endgroup\$
    – Mike
    Commented Feb 12, 2020 at 11:45

1 Answer 1

0
\$\begingroup\$

Lets analyse your configuration:

T1CON=0x15

Referring to p79 of the datasheet this means

  • Prescaler=1
  • Clock=FOSC/4
  • Sync=Disable harmless but ignored
  • Timer=enabled

... as Mike commented, if your FOSC is 4MHz then you're driving the timer with a 1MHz clock.

Your formula could do with some more brackets:

Count=65536-((Time*(FOSC/4))/Prescaler)

You want to flip the LED every 0.1s but you can't request the timer to count 100000 because it's only 16 bits. Great time to use the prescaler (that's what it's for) but instead you're counting 50000/0.05s and ignoring alternate interrupts. This happens here

    Counter++;
    if(Counter>1) {
        Counter=0;
        LED_RX=!LED_RX;
    }

Note that on the first interrupt counter goes from 0 to 1 then on the second interrupt it goes 1 to 2 (i.e. greater than 1) resets to 0 and flips the LED.

Finally, this line is plain wrong

3A98(hex)=15000=65536-(time*4XMhz)/4*1

FOSC=4e6, time=0.05s so 65336-((0.05*(4e6/4))/1)=15336=0x3BE8

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.