• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Understanding timer

fan174

Member
The output of the sensor is connected to the Timer Clock Input Pin of PIC16F877A. and LED connected to port pin RD0

I want to flash LED when the timer goes from 0 to 10 .

My code
C:
/ PIC16F877A Configuration Bit Settings

// CONFIG
//MPLAB XC8
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = ON        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#define _XTAL_FREQ 20000000 //Specify the XTAL crystal FREQ

#include<xc.h>

void main(void)
{

    TRISC = 0b00000001;    //PORTC R0  pins are used as Input.
    TRISD = 0b00010000;    //PORTD R4  pins are used as output.

    //Loading starting value of counter 65536- 10 = 65426 = FFF6 hexa decimal
    TMR1H = 0xFF ;    // High byte FF
    TMR1L = 0xF6 ;    // Low Byte F6

    //Set T1CON Register

    TMR1ON  = 0; // Stops Timer1
    TMR1CS =  0; // Internal clock (FOSC/4)
    T1SYNC =  0; // Synchronize external clock input
    T1OSCEN = 0; // Oscillator is shut-off
    T1CKPS0 = 1;  //  1:8 prescale value
    T1CKPS1 = 1;

    TMR1IE=1; //Enable timer interrupt bit in PIE1 register
    GIE=1; //Enable Global Interrupt
    PEIE=1; //Enable the Peripheral Interrupt
    TMR1ON = 1; //Start Timer1

}


void interrupt timer_isr()
{
  if(TMR1IF ==1)
  {
    RD4 = 1;  // LED ON
    __delay_ms(500); //
    RD4 = 0;  // LED OFF
    TMR1IF=0; // Clear timer interrupt flag
  }
}
I do not have any idea why LED doesn't flash when 10 counts happen?

I hope someone would help me here
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
You need a foreverloop…. place a line in the main

while(1);

Otherwise the program will just keep rebooting...

You also need to disable the timer just before the delay as it'll still be running.. The other thing.. If you need a specific timebase then you will need to pre-load the timer every cycle...
 

fan174

Member
You need a foreverloop…. place a line in the main

You also need to disable the timer just before the delay as it'll still be running..
I didn't understand where to disable timer?

The other thing.. If you need a specific timebase then you will need to pre-load the timer every cycle...
I want to flash LED when the sensor activates 10 time

C:
// PIC16F877A Configuration Bit Settings

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = ON        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#define _XTAL_FREQ 20000000 //Specify the XTAL crystal FREQ

#include<xc.h>

void main(void) 
{
    
    TRISC = 0b00000001;    //PORTC R0  pins are used as Input.
    TRISD = 0b00010000;    //PORTD R4  pins are used as output.
    
    //Loading starting value of counter 65536- 10 = 65426 = FFF6 hexa decimal
    TMR1H = 0xFF ;    // High byte FF
    TMR1L = 0xF6 ;    // Low Byte F6
    
    //Set T1CON Register 
    
    TMR1ON  = 0; // Stops Timer1
    TMR1CS =  0; // Internal clock (FOSC/4)
    T1SYNC =  0; // Synchronize external clock input
    T1OSCEN = 0; // Oscillator is shut-off
    T1CKPS0 = 1;  //  1:8 prescale value
    T1CKPS1 = 1;
    
    TMR1IE=1; //Enable timer interrupt bit in PIE1 register
    GIE=1; //Enable Global Interrupt
    PEIE=1; //Enable the Peripheral Interrupt
    TMR1ON = 1; //Start Timer1
    while(1);
}


void interrupt timer_isr()
{
  if(TMR1IF ==1)
  { 
    TMR1ON  = 0; // Stops Timer1
    RD4 = 1;  // LED ON
    __delay_ms(500); // 
    RD4 = 0;  // LED OFF
    TMR1IF=0; // Clear timer interrupt flag
  }
}
 

fan174

Member
Now restart the timer in the interrupt..
tried below code but LED doesn't trigreed

C:
// PIC16F877A Configuration Bit Settings

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = ON        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#define _XTAL_FREQ 20000000 //Specify the XTAL crystal FREQ

#include<xc.h>

void main(void) 
{
    
    TRISC = 0b00000001;    //PORTC R0  pins are used as Input.
    TRISD = 0b00010000;    //PORTD R4  pins are used as output.
    
    //Loading starting value of counter 65536- 10 = 65426 = FFF6 hexa decimal
    TMR1H = 0xFF ;    // High byte FF
    TMR1L = 0xF6 ;    // Low Byte F6
    
    //Set T1CON Register 
    
    TMR1ON  = 0; // Stops Timer1
    TMR1CS =  0; // Internal clock (FOSC/4)
    T1SYNC =  0; // Synchronize external clock input
    T1OSCEN = 0; // Oscillator is shut-off
    T1CKPS0 = 1;  //  1:8 prescale value
    T1CKPS1 = 1;
    
    TMR1IE=1; //Enable timer interrupt bit in PIE1 register
    GIE=1; //Enable Global Interrupt
    PEIE=1; //Enable the Peripheral Interrupt
    TMR1ON = 1; //Start Timer1
    while(1);
}


void interrupt timer_isr()
{
  if(TMR1IF ==1)
  { 
    TMR1ON  = 0; // Stops Timer1
    RD4 = 1;  // LED ON
    __delay_ms(500); // 
    RD4 = 0;  // LED OFF
    TMR1IF=0; // Clear timer interrupt flag
    
    TMR1ON  = 1; // Start Timer1
  }
}
 

fan174

Member
I'll take a looksee.... I'll have to create a project.... I'll report back soon.
modified version of code but LED doesn't triggered
C:
// PIC16F877A Configuration Bit Settings

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF        // Watchdog Timer Enable bit (WDT disable)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#define _XTAL_FREQ 20000000 //Specify the XTAL crystal FREQ

#include<xc.h>

void main(void) 
{
    PORTD = 0b00000000;
    
    TRISC = 0b00000001;    //PORTC R0  pins are used as Input.
    TRISD = 0b00010000;    //PORTD R4  pins are used as output.
    
    //Loading starting value of counter 65536- 10 = 65426 = FFF6 hexa decimal
    TMR1H = 0xFF ;    // High byte FF
    TMR1L = 0xF6 ;    // Low Byte F6
    
    //Set T1CON Register 
    
    TMR1ON  = 0; // Stops Timer1
    TMR1CS =  0; // Internal clock (FOSC/4)
    T1SYNC =  0; // Synchronize external clock input
    T1OSCEN = 0; // Oscillator is shut-off
    T1CKPS0 = 1;  //  1:8 prescale value
    T1CKPS1 = 1;
    
    TMR1IE=1; //Enable timer interrupt bit in PIE1 register
    GIE=1; //Enable Global Interrupt
    PEIE=1; //Enable the Peripheral Interrupt
    TMR1ON = 1; //Start Timer1
    
    while(1);
}


void interrupt timer_isr()
{
  if(TMR1IF ==1)
  { 
    TMR1ON  = 0; // Stops Timer1
    RD4 = 1;  // LED ON
    __delay_ms(500); // 
    RD4 = 0;  // LED OFF
    TMR1IF=0; // Clear timer interrupt flag
    
    TMR1ON  = 1; // Start Timer1
  }
}
 

fan174

Member
TRISD = 0; You have RD4 set to input!!
code is not working as expected

LED triggering on some time interval. LED doesn't trigger when the sensor become high 10 times's

C:
// PIC16F877A Configuration Bit Settings

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF        // Watchdog Timer Enable bit (WDT disable)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#define _XTAL_FREQ 20000000 //Specify the XTAL crystal FREQ

#include<xc.h>

void main(void) 
{
    PORTD = 0b00000000;
    
    TRISC0 = 1;    //PORTC R0  pins are used as Input.
    TRISD4 = 0;    //PORTD R4  pins are used as output.
    
     //Loading starting value of counter 65536- 10 = 65426 = FFF6 hexa decimal
    TMR1H = 0xFF ;    // High byte FF
    TMR1L = 0xF6 ;    // Low Byte F6
    
    //Set T1CON Register 
    
    TMR1ON  = 0; // Stops Timer1
    TMR1CS =  0; // Internal clock (FOSC/4)
    T1SYNC =  0; // Synchronize external clock input
    T1OSCEN = 0; // Oscillator is shut-off
    T1CKPS0 = 1;  //  1:8 prescale value
    T1CKPS1 = 1;
    
    TMR1IE=1; //Enable timer interrupt bit in PIE1 register
    GIE=1; //Enable Global Interrupt
    PEIE=1; //Enable the Peripheral Interrupt
    TMR1ON = 1; //Start Timer1
    
    while(1);
}


void interrupt timer_isr()
{
  if(TMR1IF ==1)
  { 
    TMR1ON  = 0; // Stops Timer1
    RD4 = 1;  // LED ON
    __delay_ms(5000); // 
    RD4 = 0;  // LED OFF
    TMR1IF=0; // Clear timer interrupt flag
    
    TMR1ON  = 1; // Stops Timer1
  }
}
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
What is your trigger?? If your trigger is on RC0 ( ext int ) then you need to change your code to fire the interrupt when RC0 goes high or low..

Then in the while loop in main use a control flag to flash the LED. But! What do you want to happen once the timer hits 10... Do you need to reload the timer to count 10 again?? The reason I ask is: you have your timer setup as a timer and not a counter???

Scenario:-- Count to 10.. flash LED.. then what??
 

fan174

Member
What is your trigger?? If your trigger is on RC0 ( ext int ) then you need to change your code to fire the interrupt when RC0 goes high or low..

Then in the while loop in main use a control flag to flash the LED. But! What do you want to happen once the timer hits 10... Do you need to reload the timer to count 10 again?? The reason I ask is: you have your timer setup as a timer and not a counter???

Scenario:-- Count to 10.. flash LED.. then what??
Scenario:-- Count to 10.. flash LED.. reload the timer to count 10 flash LED repeat process continuously

C:
// PIC16F877A Configuration Bit Settings

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF        // Watchdog Timer Enable bit (WDT disable)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#define _XTAL_FREQ 20000000 //Specify the XTAL crystal FREQ

#include<xc.h>

void main(void) 
{
    PORTD = 0b00000000;
    
    TRISC0 = 1;    //PORTC R0  pins are used as Input.
    TRISD4 = 0;    //PORTD R4  pins are used as output.
    
     //Loading starting value of counter 65536- 10 = 65426 = FFF6 hexa decimal
    TMR1H = 0xFF ;    // High byte FF
    TMR1L = 0xF6 ;    // Low Byte F6
    
    //Set T1CON Register 
    
    TMR1ON  = 0; // Stops Timer1
    TMR1CS =  0; // Internal clock (FOSC/4)
    T1SYNC =  0; // Synchronize external clock input
    T1OSCEN = 0; // Oscillator is shut-off
    T1CKPS0 = 1;  //  1:8 prescale value
    T1CKPS1 = 1;
    
    TMR1ON = 1; //Start Timer1
    
    while(1)
    {
       if(TMR1IF ==1)
      { 
          TMR1ON  = 0; // Stops Timer1
       
          RD4 = 1;  // LED ON
          __delay_ms(500); // 
          RD4 = 0;  // LED OFF
         
          TMR1IF=0; // Clear timer interrupt flag
          TMR1ON  = 1; // Stops Timer1
      }  
    }
    
}
 
Last edited:

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
Try this;-
C:
// PIC16F877A Configuration Bit Settings
// CONFIG
//MPLAB XC8
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
#define _XTAL_FREQ 20000000 //Specify the XTAL crystal FREQ
#include<xc.h>
void main(void)
{
    TRISC = 0b00000001;    //PORTC R0  pins are used as Input.
    TRISD = 0b00000000;    //PORTD R4  pins are used as output.
    //Loading starting value of counter 65536- 10 = 65426 = FFF6 hexa decimal
    TMR1H = 0xFF ;    // High byte FF
    TMR1L = 0xF6;    // Low Byte F6
    //Set T1CON Register
    TMR1ON  = 0; // Stops Timer1
    TMR1CS =  1; // Internal clock (FOSC/4)
    T1SYNC =  0; // Synchronize external clock input
    T1OSCEN = 1; // Oscillator is shut-off
    T1CKPS0 = 0;  //  1:8 prescale value
    T1CKPS1 = 0;
    TMR1IE=1; //Enable timer interrupt bit in PIE1 register
    GIE=1; //Enable Global Interrupt
    PEIE=1; //Enable the Peripheral Interrupt
    TMR1ON = 1; //Start Timer1
    while(1);
}

void interrupt timer_isr()
{
  if(TMR1IF ==1)
  {
    RD4 = 1;  // LED ON
    __delay_ms(500); //
    RD4 = 0;  // LED OFF
    TMR1IF=0; // Clear timer interrupt flag
    TMR1H = 0xFF ;    // High byte FF
    TMR1L = 0xF6;    // Low Byte F6
  }
}
 

fan174

Member
Try this;-

T1OSCEN = 1; // Oscillator is shut-off
hello Ian
Thanks a lot for the program
your comment says Oscillator is shut off that is the wrong statement

T1OSCEN: Oscillator enable control bit
1 = Oscillator is enabled
0 = Oscillator is shut off

Have you tested code? Is it working for you? I am outside
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
No!! Read the datasheet... T1OSCEN can be used ( when in counter mode )
datasheet said:
Counter mode is selected by setting bit TMR1CS. In
this mode, the timer increments on every rising edge of
clock input on pin RC1/T1OSI/CCP2 when bit
T1OSCEN is set, or on pin RC0/T1OSO/T1CKI when
bit T1OSCEN is cleared.
But without the OSC bit, the input is unstable..
 

fan174

Member
No!! Read the datasheet... T1OSCEN can be used ( when in counter mode )


But without the OSC bit, the input is unstable..
Ian Rogers Thank you

Your code worked for me

Modification

TRISC = 0b00000001; //PORTC R0 pins are used as Input.
TRISB = 0b00000001; //PORTB R0 pins are used as Input.
TRISD = 0b00000000; //PORTD R4 pins are used as output.

I want to check RB0 if It's high.. start counter.. count 10.. stop counter.. flash LED..

if RB0 is low.. stop counter

if RB0 becomes high again start counter.. count 10.. stop counter.. flash LED

repeat process in the loop
 

fan174

Member
Modification

TRISC = 0b00000001; //PORTC R0 pins are used as Input.
TRISB = 0b00000001; //PORTB R0 pins are used as Input.
TRISD = 0b00000000; //PORTD R4 pins are used as output.
Ian Please check my code

I want to check RB0 if It's high.. start counter.. count 10.. stop counter.. flash LED..

if RB0 is low.. stop counter

if RB0 becomes high again start counter.. count 10.. stop counter.. flash LED

repeat process in the loop

C:
// PIC16F877A Configuration Bit Settings
// CONFIG
//MPLAB XC8
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
#define _XTAL_FREQ 20000000 //Specify the XTAL crystal FREQ
#include<xc.h>
void main(void)
{
    TRISB = 0b00000001;    //PORTB R0  pins are used as Input.
    TRISC = 0b00000001;    //PORTC R0  pins are used as Input.
    TRISD = 0b00000000;    //PORTD R4  pins are used as output.
	
    //Loading starting value of counter 65536- 10 = 65426 = FFF6 hexa decimal
    TMR1H = 0xFF ;    // High byte FF
    TMR1L = 0xF6;    // Low Byte F6
   
   //Set T1CON Register
    TMR1ON  = 0; // Stops Timer1
    TMR1CS =  1; // Internal clock (FOSC/4)
    T1SYNC =  0; // Synchronize external clock input
    T1OSCEN = 1; // Oscillator is shut-off
    T1CKPS0 = 0;  //  1:8 prescale value
    T1CKPS1 = 0;
   
    TMR1IE=1; //Enable timer interrupt bit in PIE1 register
    GIE=1; //Enable Global Interrupt
    PEIE=1; //Enable the Peripheral Interrupt
    TMR1ON = 1; //Start Timer1
    while(1)
	
	{
	   if (RB0 == 1)
	   {
	      TMR1ON = 1; //Start Timer1
	   }
	   
	   else 
	   {
	       TMR1ON = 0; //Stop Timer1
	   }
}

void interrupt timer_isr()
{
  if(TMR1IF ==1)
  {
    RD4 = 1;  // LED ON
    __delay_ms(500); //
    RD4 = 0;  // LED OFF
    TMR1IF=0; // Clear timer interrupt flag
    TMR1H = 0xFF ;    // High byte FF
    TMR1L = 0xF6;    // Low Byte F6
  }
} [code]
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
When you stop the counter... It may be a good idea to reset the timer so it will count to 10... I also found that the T1OSCEN needs to be 0 if you are counting on RC0.. I had it set to 1 as I was testing the count on RC1...

**NOTE** One pitfall. The timer has to see a falling edge before it will count a rising edge.. so if the RC0 pin is high it will count the next rising.. If the pin RC0 is low when you start, then the first rising edge will be missed so it will see 11 pulses and not 10.. Before starting the count, read RC0... If it is low preload with -9, if its high then preload with -10...
 

fan174

Member
When you stop the counter... It may be a good idea to reset the timer so it will count to 10... I also found that the T1OSCEN needs to be 0 if you are counting on RC0.. I had it set to 1 as I was testing the count on RC1...

**NOTE** One pitfall. The timer has to see a falling edge before it will count a rising edge.. so if the RC0 pin is high it will count the next rising.. If the pin RC0 is low when you start, then the first rising edge will be missed so it will see 11 pulses and not 10.. Before starting the count, read RC0... If it is low preload with -9, if its high then preload with -10...
When I ran the program in post #17. the counter doesn't work when the sensor is high

I don't understand why it's not working I have checked connection it's okay
 

EE World Online Articles

Loading

 
Top