# PIC16F887 Timer1 problems

Status
Not open for further replies.

#### bones_bones

##### New Member
Hi
I seem to be having dificulty using the Timer1 module to increment every second. As I understand it there is a 32.768KHz crystal clock built into the PIC on pins PORTC.0 and PORTC.1 (If I'm incorrect in this fact please let me know) and there is no need to build a crystal-cap circuit.

In my code I would like to have a HIGH output on PORTD.0 every minute and as soon as the comparator meets the requirements, to then pull PORTD.0 LOW. However timer1 doesn't seem to incremet at all.

There are no problems wth the comparator section as I've used that bit of code for another circuit that functioned perfectly and therfore i'll leave out that bit.

Could someone please have a quick look at my code and see if you can spot the problems.

PHP:
#include	"D:\Program Files\Microchip\MPASM Suite\p16f887.inc"   ;yes that is my root drive

__config _CONFIG1, (_INTRC_OSC_CLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF)
__config _CONFIG2, (_BOR40V & _WRT_OFF)

;vaiable declarations
cblock	0x20
minutes
seconds
count
endc

;reset and ISR
org		0x00
goto	reset
org		0x04
goto	isr

reset
;====================================================================================
;setting up timer1 for 1 sec increments
bcf		STATUS, RP0
bcf		STATUS, RP1		;bank 0
movlw	0xbe
movwf	T1CON		        ;timer1 is set to increment every sec but is not yet enabled-
clrf	PORTC		                ;using 32.768 crystal clock and a prescaler of 1:8

bsf		STATUS, RP0		;bank 1
movlw	0x03
movwf	TRISC			;set PORTC.0 and PORTC.1 ans inputs

bcf		STATUS, RP0		;bank 0
;interrupt for timer1
movlw	0x40
movwf	INTCON			;enable Peripheral Interrupts

bsf		STATUS, RP0		;bank 1
bsf		PIE1, 0			;enable overflow interrupt

bcf		STATUS, RP0		;bank 0
;timer 1 set up but not enabled
;====================================================================================

;setting up on off switch and clearing variables
;====================================================================================
clrf	TRISD

bcf		STATUS, RP0		;bank 0
clrf	PORTD
clrf	PORTC
clrf	PORTA

call	oc_delay		                 ;call delay for crystal to settle

clrf	seconds			         ;register to increment seconds
clrf	minutes			         ;register to increment minutes
clrf	count			                 ;register used in delay loop
clrf	TMR1H			         ;clear timer1 to start at 0
clrf	TMR1L
bsf		T1CON, 0		         ;enable timer1
bsf		INTCON, 7		         ;interrupts enabled
;====================================================================================

;main function
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
main_loop
call	test_time		                 ;function to test if a minute has gone by
nop
goto	main_loop

test_time
movlw	0x01			         ;test condition (this may seem comlicated for a min, but in future i want to have longer periods)
subwf	minutes, 0
btfss	STATUS, C		                 ;has the varible minutes reached a min
return						 ;NO -- then do nothing
call	comparitor_on	;Yes -- turn on comparitor to use as a kill switch-
bsf		PORTD, 0		          ;       and pull PORTD.0 HIGH
return
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
isr
;test if interrupt was generated correctly
btfsc	PIR1, 0
goto	sec_inc

sec_inc
bcf		PIR1, 0
incf	seconds			          ;increment seconds-
movlw	0x3c			          ;and test if seconds has reached 60(decimal)
subwf	seconds, 0
btfss	STATUS, C
goto	end_isr			          ;IF seconds != 60 return to main loop through an isr end procedure
clrf	seconds			          ;IF seconds == 60 clear seconds-
incf	minutes			          ;and incremet minutes
goto	end_isr

end_isr						   ;ISR end procedure
bcf		STATUS, RP1
movlw	0xc0
movwf	INTCON
retfie
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

oc_delay					;delay loop for crystal
movlw	0xff
movwf	count
back
decfsz	count
goto	back
return

end

Last edited:

#### kpatz

##### New Member
Timer1 has a built-in oscillator but you still have to provide the crystal and supporting caps to use it. Look at page 66 of the datasheet for the circuit for using a crystal with the LP oscillator. For timer1 you'd do the same thing but the crystal/cap circuit would be connected between the T1OSO and T1OSI pins.

Set the prescaler to 0. When using a 32768 KHz crystal, the timer will increment 32768 times per second. The timer interrupt isn't generated until the timer overflows, when it reaches 65535 and rolls back to zero. So, the way your code is now, you'll only get a timer1 interrupt once every 16 seconds. So, set the prescaler bits to 0, and set bit 7 of TMR1H when you start the timer and also everytime the timer interrupt occurs. This resets the timer to 32768 so it only needs 1 second to overflow. Then you'll get a timer interrupt once per second, which you can use for your timing.

Last edited:

#### bones_bones

##### New Member
Thanks kpatz, your advise got me set up exactly the way i wnated

Status
Not open for further replies.

Replies
14
Views
2K
Replies
6
Views
7K
Replies
5
Views
2K
Replies
4
Views
4K
Replies
6
Views
4K