I used PIC16f877A at proteus to do timer interrupt.

The code is pretty simple it has nothing to do rather than setting the timer1 registers , the while(1) loop is empty , the timer setting is as below.

When I run it the frequency of RB0 is too low it's just 32 Hz while it should be much greater than that, I sat the clock frequency both on fuses and proteus to 16 MHz, pre and post scalers 1:1 , but it still extremely low, I believe the is something wrong with ISIS it self , any ideas ?

main.c :

#include "config.h"
#include <stdint.h>

void main()
    // -- [[  IO Configurations ]] --
    TRISB0 = 0;
    TMR1 = 0;
    TMR1CS = 0;
    T1CKPS0 = 0;
    T1CKPS1 = 0;
    TMR1ON = 1;

  // -- [[ Interrupts Configurations ]] --
    TMR1IE = 1; // Timer1 Interrupt Enable Bit
    TMR1IF = 0; // Clear The Interrupt Flag Bit
    PEIE = 1;   // Peripherals Interrupts Enable Bit
    GIE = 1;    // Global Interrupts Enable Bit

        // Stay IDLE ,, Timer Interrupt Will Handle Everything For Us !

// Interrupt Service Routine - ISR
void __interrupt() ISR (void)
   // Check The Flag Bit
   if (TMR1IF)

        RB0 = ~RB0;


The code posted sets TIMER1 to be clocked from the FOSC/4 source and to assert an interrupt after 65536 clocks.

The interrupt handler toggles the state of RB0.

With a 16MHz oscillator the TIMER1 input clock is 4MHz, Divide 4MHz by 65536 the interrupt asserts every 16.384 milliseconds.

The signal on RB0 does a full cycle every 32.768 milliseconds or a frequency of 30.51Hz.

The results of your Proteus simulation seems correct.


Timing cannot be simulated on Proteus. It is the major con of Proteus. Use Proteus for only logic simulation, not for timing one.

Not only for PIC, simulation for MSP32, AVR, C2000 will give the same result.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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