Continue to Site

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.

  • 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.

Timer0 Prescale

Status
Not open for further replies.

lord loh.

Member
I am using 18F452

I tried to experiment with timer0... I set a prescale factor and was generating interrupts. For each interrupt, I was incrementing a variable whih was in the watch.

However when I set precale 1:2 and prescale 1:4, the simulator did not generate any interrupts...

I looked for all possible typo errors etc.. But It just does not make sense. If I just change one bit in the T0CON, >>TOPS0,TOPS1,TOPS2, The programme works...

Has anyone ever faced such a problem...
Please help me out...

MACRO.INC
Code:
timer0.enable MACRO
			bsf T0CON,TMR0ON 			;Sets bit7 of the T0CON register
	ENDM
timer0.disable MACRO
			bcf T0CON,TMR0ON 			;Clears bit7 of the T0CON register
	ENDM

;Macro to set timer0 to 8bit / 16bits.
timer0.8Bits MACRO
				bsf T0CON,T08BIT		;Sets bit6 of the T0CON register
	ENDM
timer0.16Bits MACRO
				bcf T0CON,T08BIT		;Clears bit6 of the T0CON register
	ENDM

;Macro to select the timer0 clock source
timer0.counter MACRO
				bsf T0CON,T0CS			;Sets the bit5 of the T0CON register

	ENDM
timer0.timer MACRO
				bcf T0CON,T0CS			;Clears the bit5 of the T0CON register
	ENDM

;Macro to select the timer0 Clock edge
timer0.pTriggered MACRO
				bsf T0CON,T0SE			;Sets the bit4 of the T0CON register

	ENDM
timer0.nTriggered MACRO
				bcf T0CON,T0SE			;Clears the bit4 of the T0CON register
	ENDM

;Macro to set the timer0  prescalers
timer0.prescale1 MACRO
				bsf T0CON,PSA			;Sets the bit3 of the T0CON register
	ENDM
timer0.prescale2 MACRO					;Prescale 1:2
				bcf T0CON,PSA			;Sets the bit3 of the T0CON register
				bsf T0CON,T0PS0
				bsf T0CON,T0PS1
				bcf T0CON,T0PS2
	ENDM
timer0.prescale4 MACRO					;Prescale 1:4
				bcf T0CON,PSA			;Sets the bit3 of the T0CON register
				bsf T0CON,T0PS0
				bcf T0CON,T0PS1
				bcf T0CON,T0PS2
	ENDM
timer0.prescale8 MACRO					;Prescale 1:8
				bcf T0CON,PSA			;Sets the bit3 of the T0CON register
				bcf T0CON,T0PS0
				bsf T0CON,T0PS1
				bcf T0CON,T0PS2
	ENDM
timer0.prescale16 MACRO					;Prescale 1:16
				bcf T0CON,PSA			;Sets the bit3 of the T0CON register
				bsf T0CON,T0PS0
				bsf T0CON,T0PS1
				bcf T0CON,T0PS2
	ENDM
timer0.prescale32 MACRO					;Prescale 1:32
				bcf T0CON,PSA			;Sets the bit3 of the T0CON register
				bcf T0CON,T0PS0
				bcf T0CON,T0PS1
				bsf T0CON,T0PS2
	ENDM
timer0.prescale64 MACRO					;Prescale 1:64
				bcf T0CON,PSA			;Sets the bit3 of the T0CON register
				bsf T0CON,T0PS0
				bcf T0CON,T0PS1
				bsf T0CON,T0PS2
	ENDM
timer0.prescale128 MACRO				;Prescale 1:128
				bcf T0CON,PSA			;Sets the bit3 of the T0CON register
				bcf T0CON,T0PS0
				bsf T0CON,T0PS1
				bsf T0CON,T0PS2
	ENDM
timer0.prescale256 MACRO				;Prescale 1:256
				bcf T0CON,PSA			;Sets the bit3 of the T0CON register
				bsf T0CON,T0PS0
				bsf T0CON,T0PS1
				bsf T0CON,T0PS2
	ENDM

;Macros to configure interrupts
timer0.highPriority MACRO				;Set timer0 interrupt priority high
				bsf INTCON2,TMR0IP
	ENDM
timer0.lowPriority MACRO				;Set timer0 interrupt priority low
				bcf INTCON2,TMR0IP
	ENDM
timer0.interruptEnable MACRO
				bsf INTCON,TMR0IE		;Enables the timer0 interrupt.
	ENDM
timer0.interruptDisable MACRO
				bcf INTCON,TMR0IE		;Disables the timer0 interrupt.
	ENDM
timer0.clearInterruptFlag MACRO			;clears the timer0 interrupt flag
				bcf INTCON,TMR0IF
	ENDM

;Macro to check if interrupt has occured.
timer0.ifInterrupt MACRO tmrservice		;Check Timer0 overflow
				btfsc INTCON,TMR0IF			
				goto tmrservice
	ENDM


MAIN.ASM
Code:
	#include "p18f452.inc"
	#include "defs.inc"		
	#include "macros.inc"

;Define Xtal
	Xtal EQU 8000000
	PLL=FALSE

;Compute the clock time period
	IF PLL
	@clock_period SET 1/Xtal
	ELSE
clock_period SET 4/Xtal
	ENDIF
	
	;Declare Global Variables
	global terminate,test1,test2,test

	;Get external labels
	extern delay, highPriorityInterrupt, lowPriorityInterrupt

	;Allocate memory to variables
mainData udata
var1 res 1
tempData udata_ovr
w_shadow res 1
test1 res 1
test2 res 1
test res 1
	
	
	;Interrupt Vectors
resetV CODE 0X0000						;Interrupt Vector
 			goto main					;Goto mainroutine

highInterV CODE 0x0008					;High Priority Interrupt Vector
			goto highPriorityInterrupt 

lowInterV CODE 0x0018					;Low Priority Interrupt Vector
			goto lowPriorityInterrupt

	;Main routine
mainCode CODE							;The main code.
main:		;Initialize Interrupts
			interrupts.globalEnable
			interrupts.priorityEnable
			interrupts.peripheralEnable

			timer0.interruptEnable
			timer0.highPriority

			timer1.interruptEnable
			timer1.highPriority
			;Initialize Timers
			timer0.timer
			timer0.8Bits
			timer0.prescale4
			timer0.enable

			;timer1.timer
			;timer1.8Bits
			;timer1.prescale8
			;timer1.disable

			movlw 0x01
			movwf test1
			movwf test2
			movwf test
			
terminate:	bra terminate
	END

SUBROUTINE.ASM
Code:
	#include "p18f452.inc"
	#include "macros.inc"
	
;Declare labels global
	global delay, highPriorityInterrupt, lowPriorityInterrupt

;get labels	from other files
	extern terminate,test1,test2,test

;Define Variables
subData udata
delayCount res 1
pwmDuty res 1
timeTicks res 1

;Subroutine Code.
subroutine CODE


;Interrupt Service Routines
highPriorityInterrupt:
				incf test
				timer0.ifInterrupt masterTimer
				;timer1.ifInterrupt timer1int
				retfie


lowPriorityInterrupt:
				retfie




;This is a subroutine to create a delay.
delay:			movwf delayCount
delayLoop:		decfsz delayCount
				bra delayLoop
				return 1

;Subroutine to handle hardware timer interrupts.
hwtimer:	
				return 1

masterTimer:	
				nop
				timer0.clearInterruptFlag
				incf test1
				retfie

timer1int:		nop
				timer1.clearInterruptFlag
				incf test2
				retfie


	
		END
 
I am not 100% sure on this, and I havn't looked at the 18F452 datasheet, but setting the prescaler bits one at a time is a highly questionable practice. It puts a sequence of different values into the prrescaler, not all of which may be legal. I think it would better to write T0CON with a constant and save the bit operations for the RUN bit. It might also be a good idea to stop the timer before configuring it.

In the PIC 16F series I seem to remeber a specific procedure for switching the prescaler assignment between Timer0 and the Watchdog Timer. Can you find a similar mention in the 18F452 datasheet?
 
Last edited:
I am enabling the timer only after I have set the prescalar...

I I see no reliable way to set the bits of T0CON without doing it a bit at a time... T0CON has other bits used for different putposes... So I will have to read T0CON mask bits that I am not interested in, write bits that I need and write the T0CON back... This shall take far more machine cycles than doing it a bit at a time... Anyway, how are illegal combinations developed? I do not see such a thing in the watch window. Moreover, I am using the bit names defined in the p18f452.inc file...
 
The basic idea is that you decide the value you want for all of the bits at one time and you write that value. There is no requirement that the bits be set or cleared one at a time, nor is there a requirement that the existing values of the bits be preserved at every stage of the operation. I see nothing unreliable about that process. Your original post said that there was something wrong; I took a guess that maybe the sequence of read-modify-write instructions was causing a problem. If that is not the case then we must look elsewhere.

Let me consult the datasheet.

Edit: It seems that PSA can be changed on the fly in this series without the precautions required in the 16F series, because the Timer0 prescaler is not associated with the watchdog timer.
Edit: I still think that TMR0ON is the only bit that should be manipulated with bsf/bcf instructions.
 
Last edited:
I rewrote the code for debugging... I stripped down all macros and made a 1 file programme

Code:
include "p18f452.inc"

maindata udata
test1 res 1

resetV CODE 0X0000                        ;Interrupt Vector
              goto main                    ;Goto mainroutine

highInterV CODE 0x0008                    ;High Priority Interrupt Vector
            goto highPriorityInterrupt

lowInterV CODE 0x0018                    ;Low Priority Interrupt Vector
            goto lowPriorityInterrupt

    ;Main routine
mainCode CODE                            ;The main code.
main:        ;Initialize Interrupts



        bsf RCON,IPEN                ;Interrupt enable bit of Reset Control
        bsf INTCON,GIE
        bsf INTCON,PEIE

        bsf T0CON,T08BIT        ;Sets bit6 of the T0CON register
        bcf T0CON,T0CS            ;Clears the bit5 of the T0CON register
                bcf T0CON,PSA            ;Sets the bit3 of the T0CON register
                bcf T0CON,T0PS0         ;prescale bits.
                bcf T0CON,T0PS1
                bcf T0CON,T0PS2
        bsf INTCON2,TMR0IP
        bsf INTCON,TMR0IE        ;Enables the timer0 interrupt.
        bsf T0CON,TMR0ON             ;Sets bit7 of the T0CON register
terminate:    goto terminate   

highPriorityInterrupt:

                btfsc INTCON,TMR0IF           
                goto tmrservice
                retfie

lowPriorityInterrupt:
                retfie


tmrservice:
                bcf INTCON,TMR0IF
                incf test1
                retfie

END

I am watching tmr0 and test1

And the problem persists...
 
How do you know that interrupts are not occurring? Although the interrupt service is incrementing a counter, I don't see in your code a means to check their value externally. You may be omitting critical code that is causing this bug.

BTW, you are not saving/restoring context during interrupt service. This may be a source of your bug. The simplest way to restore context during high priority interrupt service is to use "retfie fast".
 
I tried "retfie FAST" it makes no difference.

I know that the interrupts are not occuring as I am watching the TMR0 register and there is no count increment when I give prescale 1:2 and 1:4

however there is increment for all other values of prescaling including 1:1

I had to make the update of the watch window realtime in Debugger>Settings...>Real time/Update tab.
 
debug code
Code:
include "p18f452.inc"

maindata udata
test1 res 1

resetV CODE 0X0000						;Interrupt Vector
   			goto main					;Goto mainroutine

highInterV CODE 0x0008					;High Priority Interrupt Vector
			goto highPriorityInterrupt 

lowInterV CODE 0x0018					;Low Priority Interrupt Vector
			goto lowPriorityInterrupt

	;Main routine
mainCode CODE							;The main code.
main:		;Initialize Interrupts



		bsf RCON,IPEN				;Interrupt enable bit of Reset Control
		bsf INTCON,GIE
		bsf INTCON,PEIE
		clrf LATE
		movlw 0x07
		movwf ADCON1
		movlw b'0000000'
		movwf TRISE		

		bsf T0CON,T08BIT		;Sets bit6 of the T0CON register
		bcf T0CON,T0CS			;Clears the bit5 of the T0CON register
				bcf T0CON,PSA			;Sets the bit3 of the T0CON register
				bcf T0CON,T0PS0			;prescaling bits
				bcf T0CON,T0PS1			;prescaling bits
				bcf T0CON,T0PS2			;prescaling bits
		bsf INTCON2,TMR0IP
		bsf INTCON,TMR0IE		;Enables the timer0 interrupt.
		bsf T0CON,TMR0ON 			;Sets bit7 of the T0CON register
terminate:	goto terminate	

highPriorityInterrupt:

				btfsc INTCON,TMR0IF			
				goto tmrservice
				retfie FAST

lowPriorityInterrupt:
				retfie


tmrservice:
				bcf INTCON,TMR0IF
				incf test1
				movff test1,LATE
				retfie FAST

END

This does not work in the simulator but gave an output on the CRO when programed to a real device.... Could this be a bug in the simulator?

Or a mistake made by me? Can anyone help me figure this out?
 
hahahaha

hahaha.. yeh, my bad.. didn't look at the date.. and ja ipen in the rcon.haha

short and sweet and so far off!!
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top