16F PIC TMR0 Example

    TMR0 is an 8 byte timer that can be pre-scaled to change vary its incrementing cycle. Pre-scaling is important as we may want the Timer Register to increment faster/slower in different applications. The speed in which it does cycle is dependent on both the external crystal speed and the pre-scaling options.

    To change the pre-scaling for TMR0, the following bits of the OPTION Register are modified

OPTION_REG.0 = X   '000 - 1 : 2
OPTION_REG.1 = X   '001 - 1 : 4
OPTION_REG.2 = X   '010 - 1 : 8
                   '011 - 1 : 16
                   '100 - 1 : 32
                   '101 - 1 : 64
                   '110 - 1 : 128
                   '111 - 1 : 256

   The OPTION register contains 8 bytes of information, the other 5 are for completely different options, so when I modify settings that are shared in Byte registers with other options, I access them like above, so I don't accidentally change anything I don't want to.

    To change the pre-scaler too 1:4 (increment the TMR0 register every 4th clock cycle), the following would be used:

OPTION_REG.0 = 1
OPTION_REG.1 = 0
OPTION_REG.2 = 0

    Now to make a timer that can be used to count mS and Seconds very accurately. An easy way to find out how much time each clock cycle will take is to use a cycle calculator such as this. Make sure that the Internal Check Box is selected, now be sure that 4Mhz is the clock speed, and the pre-scaler is set to 1:2, you will see that the TMR0 period is now 512uS, so every time the TMR0 clock reaches 255, and rolls over to 0, 512uS has elapsed. Now we have a basis in which we can write our program.

Device = 16F877
Xtal = 4
   		   
Dim uS as Word
Dim mS as Word
Dim S as Word	

Symbol GIE = INTCON.7				' Global Interrupt Enable Bit
Symbol TMR0_uS = 512		  		' Set time interval of TMR0
Symbol TMR0_Enable = INTCON.5			' This option enables TMR0 interrupts
Symbol TMR0_Overflow = INTCON.2			' This is the TMR0 overflow flag
			
ON_INTERRUPT Int_Sub

Goto Initialization			
			
Int_Sub:

	GIE = 0

	If TMR0_Overflow = 1 And TMR0_Enable = 1 Then
	   TMR0_Overflow = 0
	   uS = uS + TMR0_uS
	   If uS >= 1000 Then
	   	  uS = uS - 1000
	  	  mS = mS + 1
		  If mS >= 1000 Then 
		  	 mS = mS - 1000
			 S = S + 1
		  EndIf
	   EndIf
	EndIf
	
	GIE = 1
	
	Context Restore
	
Initialization:
	
	TMR0_Enable = 0	   	   	 	' Disable TMR0 interrupts
	
	uS = 0		  			' Clear timer registers
	mS = 0		  			' 
	S = 0		  			'

	OPTION_REG.0 = 0   			'000	-	1 : 2
	OPTION_REG.1 = 0   			'
	OPTION_REG.2 = 0			
	OPTION_REG.5 = 0			' Select Internal Clock Source

	TMR0 = 0	   			' Clear the TMR0 register
	
	TMR0_Enable = 1				' Enable TMR0 Interrupts
	
	GIE = 1		  			' Enable Global Interrupts
		
Main:

	Repeat 					' Create a loop
	
	Until S = 60				' That waits for 60 seconds
	
	' 60 seconds has occurred
	
	S = 0		 	 		' Clear the seconds register
	
	Goto Main				' Loop for ever

 Skip Navigation Links.

Collapse Site Tutorial IndexSite Tutorial Index
Collapse 16F PIC Examples16F PIC Examples
LED's
Switches
Keypads
LCD's
7 Seg Displays
ADC
DAC
Expand MotorsMotors
Expand ThermometersThermometers
DS1307 RTC Chip
DS275
EEPROM's
RF Modules
RGB LED's
Code Snippets
Collapse Code SnippetsCode Snippets
PIC's EEPROM
Collapse Internal TimersInternal Timers
TMR0
TMR1
TMR2
Expand 18F PIC Examples18F PIC Examples
Expand Handy TipsHandy Tips