pic16f882 timer1 clock crystal

Status
Not open for further replies.
Trimmer cap, genius idea!

Now I just need to think of a good way to tune it accurately without wasting half my life
 
So I should avoid a breadboard? Using a 10pf on one leg and 33 pf on another I got accurate time for about an hour...

hi Boo,
Use a epoxy perf pcb with a simple trim cap say 3 to 30pF and the timing accuracy will be within the spec of the crystal and the associated caps.

If you use SRBP perf pcb, varnish the pcb copper area around the crystal and trimmer cap.
 
Bumping this thread for Pommie mostly.

I am now using a Dallas 32khz clock chip, so I now know it is a software problem. But WTH could be going wrong. I've been trying to get this stupid clock to work foreeeever now!!!!!!

I'll upload my code again maybe somebody can spot something!


Code:
;*************************************
; Author  : Mike Baird
; Program : Clock
; Date    : October 23rd,2009
;*************************************

	List	P=16F882
	#include	"P16F882.INC"
	__CONFIG	_CONFIG1,   _PWRTE_ON  & _WDT_OFF & _INTOSC & _BOR_OFF & _LVP_OFF & _CP_OFF & _MCLRE_OFF
	__CONFIG    _CONFIG2,	_IESO_OFF & _FCMEN_OFF
;*** Cblock ***

	CBLOCK	0x20		 
	d1									; 
	d2									;
	SecLow								;
	SecHigh								;
	MinLow								;
	MinHigh								;
	HourLow								;
	HourHigh							;
	MinL								;
	MinH								;
	HourL								;					
	HourH								;
	W_TEMP								;
	STATUS_TEMP							;
	X									;
	TEST								;
	ENDC

;*** Defines ***

#Define 	Bits 		PORTB,2
#Define 	Clock		PORTB,1
#Define 	Latch		PORTB,0
#Define 	MLow		PORTA,4
#Define 	MHigh		PORTA,3
#Define		HLow		PORTA,5
#Define 	HHigh		PORTA,7

;*** Macro ***

HC595 MACRO Var,Var1

	Local	Loop						; Local Label
	MOVLW	.8							; Transfer 8 bits
  	MOVWF	Var1						; Initializing counter

Loop	
	RLF 	Var,f						; Rotate "Var" one place to the left
	BTFSS	STATUS,C					; Is carry 1?
	BCF 	Bits						; If not set data line to 0
	BTFSC 	STATUS,C					; Is carry 0?
	BSF 	Bits						; If not set data line to 1

	BSF 	Clock						; Generate one clock
	BCF	 	Clock						;	

	DECFSZ 	Var1,f						; Has 8 bits been sent?
	GOTO	Loop						; If not, repeat

	BSF 	Latch						; If all 8 bits have been sent, set latch
	BCF 	Latch						;
	
	RLF 	Var,f						; Restore to Orginal
	ENDM


;*** START OF RAM ***
	ORG	0x000							; Start of program vector
	GOTO	Start						;
	ORG	0x004							; Interrupt vector
	GOTO 	ISR

Table:
	ADDWF	PCL
	RETLW 	b'00111111' 				; 0	    (3)
	RETLW 	b'00000110' 				; 1	    (4) 
	RETLW 	b'01011011' 				; 2	    (5)
	RETLW 	b'01001111' 				; 3	    (6)
	RETLW 	b'01100110' 				; 4	    (7)
	RETLW 	b'01101101' 				; 5	    (8)
	RETLW 	b'01111101' 				; 6	    (9)		
	RETLW 	b'00000111' 				; 7	    (10)
	RETLW 	b'01111111' 				; 8	    (11)
	RETLW 	b'01101111' 				; 9     (12)
	RETLW	b'00000000'					; Blank

;*** Interrupt Service Routine ***

ISR: 
	MOVWF 	W_TEMP						; 	
	SWAPF 	STATUS,W   					; Context Saving
	MOVWF 	STATUS_TEMP					; 					

	BCF 	PIR1,TMR1IF					; Clear Interupt Flag
	BSF 	TMR1H,7						; Reload the start up value into the timer


;*** Code Insert ***
	INCF	SecLow

	MOVF	SecLow,W
	SUBLW	.10
	BTFSS	STATUS,Z
	GOTO	Exit
	CLRF	SecLow

	INCF	SecHigh
	MOVF	SecHigh,W
	SUBLW	.6
	BTFSS	STATUS,Z
	GOTO	Exit
	CLRF	SecHigh

	INCF	MinLow
	MOVF	MinLow,W
	SUBLW	.10
	BTFSS	STATUS,Z
	GOTO	Exit

	CLRF	MinLow
	INCF	MinHigh
	MOVF	MinHigh,W
	SUBLW	.6
	BTFSS	STATUS,Z
	GOTO	Exit	

	CLRF	MinHigh
	INCF	HourLow

	BTFSS	TEST,1
	GOTO	TwoHours

	MOVF	HourLow,W
	SUBLW	.10
	BTFSS	STATUS,Z
	GOTO	Exit
	GOTO	$+5

TwoHours
	MOVF	HourLow,W
	SUBLW	.3
	BTFSS	STATUS,Z
	GOTO	Exit

	BTFSC	TEST,1
	GOTO	One
Blank
	MOVLW	.1
	MOVWF	HourLow
	MOVLW	.10
	MOVWF	HourHigh		
	BSF		TEST,1
	GOTO	Exit
One
	CLRF	HourLow
	MOVLW	.1
	MOVWF	HourHigh
	BCF		TEST,1
	
;*** End of Insert ***

Exit
	MOVF	MinHigh,W
	ADDLW	0x30
	Call	Send
	MOVF	MinLow,W
	ADDLW	0x30
	Call	Send

	MOVLW	':'
	Call	Send
	MOVF	SecHigh,W
	ADDLW	0x30
	Call	Send
	MOVF	SecLow,W
	ADDLW	0x30
	Call	Send

	SWAPF 	STATUS_TEMP,W				; Restore Status and W	
	MOVWF	STATUS						;
	SWAPF 	W_TEMP,F					;
	SWAPF 	W_TEMP,W					;
	RETFIE								;

;*** End of ISR ***

Start

	CLRF	PORTA						; PortA all low
	CLRF	PORTB						; PortB all low
	
	BSF		STATUS,RP0					; Bank 1
	CLRF	TRISA						; PortA all output except MCLR
	CLRF	TRISB						; Move to PortB
	CLRF	TRISC

	BSF		TRISC,0						; Osc inputs
	BSF		TRISC,1
	BSF		TRISC,7
	BSF		TRISC,6
	BSF		PIR1,TMR1IE
	BCF		STATUS,RP0					; Bank 0		
	BANKSEL	ANSEL
	CLRF	ANSEL
	CLRF	ANSELH
	BANKSEL	PORTA

;*** Timer1 set up ***

	BCF		T1CON,6
	BCF 	T1CON,4            			; 1,2,4,8 prescaler  
	BCF 	T1CON,5            			; 
	BSF 	INTCON,6					; Enable all unmasked interrupts
	BSF 	INTCON,7           			; Enable Global interrupts
	BSF		TMR1H,7							; Load a start up value into the timer
	BCF		T1CON,T1OSCEN	;3			; Timer1 External Clock Input Synchronization Control bit
	BSF		T1CON,T1SYNC	;2			; Sync to external clock
	BSF		T1CON,TMR1CS	;1			; External clock from pin RB6/T1OSO/T1CKI/PGC (on the rising edge)
	BCF 	PIR1,0             			; Reset interupt flag
	BSF 	T1CON,0			;0			; Start the timer

;*** UART Set Up ***
	BANKSEL	BAUDCTL
	MOVLW	b'00000000'
	MOVWF	BAUDCTL	
	BANKSEL	SPBRG
	MOVLW 	0x19       				 	; 0x19 = 9600 BPS (0x0C = 19200 BPS) 
	MOVWF 	SPBRG						; Baud Rate Generator Store Location
	MOVLW	b'10100100'
	MOVWF	TXSTA
	BCF		STATUS,RP0					; Bank 0
	BSF		RCSTA,SPEN					; Serial Port Enable bit
	BSF		RCSTA,CREN					; Continuous Receive Enable bit

;***
;	CALL	Receive
;	SUBLW	0x30
	MOVLW	.0
	MOVWF	HourHigh

;	CALL	Receive
;	SUBLW	0x30
	MOVLW	.0
	MOVWF	HourLow

;	CALL	Receive
;	SUBLW	0x30
	MOVLW	.0
	MOVWF	MinHigh

;	CALL	Receive
;	SUBLW	0x30
	MOVLW	.0
	MOVWF	MinLow

;	CALL	Receive
;	SUBLW	0x30
	MOVLW	.0
	MOVWF	SecHigh

;	CALL	Receive
;	SUBLW	0x30
	MOVLW	.0
	MOVWF	SecLow


	CLRF	TEST


Main:

	Call 	TurnOffNumbers
	MOVF	SecLow,W
	Call 	Table
	MOVWF	MinL
	HC595 	MinL,X
	BSF		MLow	
	Call 	Delay

	Call 	TurnOffNumbers
	MOVF	SecHigh,W
	Call 	Table
	MOVWF	MinH 
	HC595	MinH,X
	BSF		MHigh
	Call	Delay

	Call 	TurnOffNumbers
 	MOVF	MinLow,W
	Call 	Table
	MOVWF	HourL
	HC595 	HourL,X
	BSF		HLow
	Call 	Delay

	Call 	TurnOffNumbers
 	MOVF	MinHigh,W
	Call 	Table
	MOVWF	HourH
	HC595 	HourH,X
	BSF		HHigh
	Call 	Delay

	GOTO 	Main

TurnOffNumbers:
	BCF 	MLow
	BCF 	MHigh
	BCF 	HLow
	BCF 	HHigh
	RETURN	

;*** Receive ***

Receive: 
	BTFSS 	PIR1,RCIF 					; P1R1 is set when byte is recieved
	GOTO 	Receive						;
	MOVF 	RCREG,W 					; Move received data into W
	RETURN

;*** Send ***

Send:
	MOVWF 	TXREG 						; Load W into TXREG
	BSF 	STATUS,RP0 					; RAM Page 1
Wait:
	btfss 	TXSTA,TRMT 					; Transmission is complete when High
	GOTO 	Wait						;
	BCF 	STATUS,RP0 					; RAM Page 0
	RETURN


; *** Delay ***
Delay	
	MOVLW	d'6'
	MOVWF	d1
D1	MOVLW	d'20'
	MOVWF	d2
	
D2	DECFSZ	d2,F
	GOTO	D2
	DECFSZ	d1,F
	GOTO	D1
	RETURN

;***

	END

;*********************************************************8
; Table
;		    					    (f) Left Top = bit5
;		    __   (a) Top    = bit0 	(b) Righ Top = bit1   
;		   |__|  (g) Middle = bit6  (e) Left Bot = bit4
;		   |__|  (d) Bottom = bit3	(c) Righ Bot = bit2
;
;  = b'00000000'
;0 = b'00111111'
;1 = b'00000110'
;2 = b'01011011'
;3 = b'01001111'
;4 = b'01100110'  
;5 = b'01101101'  
;6 = b'01111101'  			
;7 = b'00001111'  
;8 = b'01111111'  
;9 = b'01101111'  
;
; That's all folks!
;*************************************
 
Wow i think that might just be it, i'll try it out when I get home. I wonder why it worked at all before?
 
Ignore what I said earlier, I was at school and didn't have access to the data sheet.

I have set you code running on my hardware and I'll see how it is in an hour. See attached, I'll post another in an hour.

Edit, I fixed the set time bit and deleted the seven segment stuff.

Mike.
 

Attachments

  • boo.png
    57.9 KB · Views: 241
Last edited:
Bad news, it kept perfect time and so it's not software.

This is the exact code I used. I changed the config and got rid of the seven segment stuff but I can't see how that would effect anything.
Code:
;*************************************  
; Author  : Mike Baird 
; Program : Clock 
; Date    : October 23rd,2009  
;*************************************  

		list	P=16F886
		#include "P16F886.INC"
	;	__config _CONFIG1, _PWRTE_ON  & _WDT_OFF & _INTOSC & _BOR_OFF & _LVP_OFF & _CP_OFF & _MCLRE_ON
	;	__config _CONFIG2, _IESO_OFF & _FCMEN_OFF

	__CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
	__CONFIG    _CONFIG2, _WRT_OFF & _BOR21V


;*** Cblock ***

		cblock	0x20		 
		d1			; 
		d2			;
		SecLow			;
		SecHigh			;
		MinLow			;
		MinHigh			;
		HourLow			;
		HourHigh 		;
		MinL			;
		MinH			;
		HourL			;
		HourH			;
		W_TEMP			;
		STATUS_TEMP 		;
		X			;
		TEST			;
		endc

		org	0x000		; Start of program vector
		goto	Start		;
		org	0x004		; Interrupt vector
		goto	ISR

Table:
		addwf	PCL
		retlw	b'00111111'	; 0	    (3)
		retlw	b'00000110'	; 1	    (4) 
		retlw	b'01011011'	; 2	    (5)
		retlw	b'01001111'	; 3	    (6)
		retlw	b'01100110'	; 4	    (7)
		retlw	b'01101101'	; 5	    (8)
		retlw	b'01111101'	; 6	    (9)
		retlw	b'00000111'	; 7	    (10)
		retlw	b'01111111'	; 8	    (11)
		retlw	b'01101111'	; 9     (12)
		retlw	b'00000000'	; Blank

;*** Interrupt Service Routine ***  

ISR:			 
		movwf	W_TEMP		; 
		swapf	STATUS,W	; Context Saving
		movwf	STATUS_TEMP	; 

		bcf	PIR1,TMR1IF	; Clear Interupt Flag
		bsf	TMR1H,7		; Reload the start up value into the timer


;*** Code Insert *** 
		incf	SecLow
		movf	SecLow,W
		sublw	.10
		btfss	STATUS,Z
		goto	Exit
		clrf	SecLow

		incf	SecHigh
		movf	SecHigh,W
		sublw	.6
		btfss	STATUS,Z
		goto	Exit
		clrf	SecHigh

		incf	MinLow
		movf	MinLow,W
		sublw	.10
		btfss	STATUS,Z
		goto	Exit

		clrf	MinLow
		incf	MinHigh
		movf	MinHigh,W
		sublw	.6
		btfss	STATUS,Z
		goto	Exit

		clrf	MinHigh
		incf	HourLow

		btfss	TEST,1
		goto	TwoHours

		movf	HourLow,W
		sublw	.10
		btfss	STATUS,Z
		goto	Exit
		goto	$+5

TwoHours
		movf	HourLow,W
		sublw	.3
		btfss	STATUS,Z
		goto	Exit

		btfsc	TEST,1
		goto	One
Blank
		movlw	.1
		movwf	HourLow
		movlw	.10
		movwf	HourHigh
		bsf	TEST,1
		goto	Exit
One
		clrf	HourLow
		movlw	.1
		movwf	HourHigh
		bcf	TEST,1

;*** End of Insert *** 

Exit
		movf	HourHigh,W
		addlw	0x30
		call	Send
		movf	HourLow,W
		addlw	0x30
		call	Send

		movlw	':'
		call	Send
		movf	MinHigh,W
		addlw	0x30
		call	Send
		movf	MinLow,W
		addlw	0x30
		call	Send

		movlw	':'
		call	Send
		movf	SecHigh,W
		addlw	0x30
		call	Send
		movf	SecLow,W
		addlw	0x30
		call	Send

		movlw	0x0d
		call	Send
		movlw	0x0a
		call	Send

		swapf	STATUS_TEMP,W	; Restore Status and W
		movwf	STATUS		;
		swapf	W_TEMP,F	;
		swapf	W_TEMP,W	;
		retfie			;

;*** End of ISR *** 

Start

		clrf	PORTA		; PortA all low
		clrf	PORTB		; PortB all low

		bsf	STATUS,RP0	; Bank 1
		clrf	TRISA		; PortA all output except MCLR
		clrf	TRISB		; Move to PortB
		clrf	TRISC

		bsf	TRISC,0		; Osc inputs
		bsf	TRISC,1
		bsf	TRISC,7
		bsf	TRISC,6
		bsf	PIR1,TMR1IE
		bcf	STATUS,RP0	; Bank 0
		banksel	ANSEL
		clrf	ANSEL
		clrf	ANSELH
		banksel	PORTA

;*** Timer1 set up *** 

		bcf	T1CON,6
		bcf	T1CON,4		; 1,2,4,8 prescaler  
		bcf	T1CON,5		; 
		bsf	INTCON,6	; Enable all unmasked interrupts
		bsf	INTCON,7	; Enable Global interrupts
		bsf	TMR1H,7		; Load a start up value into the timer
		bsf	T1CON,T1OSCEN	;3			; Timer1 External Clock Input Synchronization Control bit
		bsf	T1CON,T1SYNC	;2			; Sync to external clock
		bsf	T1CON,TMR1CS	;1			; External clock from pin RB6/T1OSO/T1CKI/PGC (on the rising edge)
		bcf	PIR1,0		; Reset interupt flag
		bsf	T1CON,0		;0			; Start the timer

;*** UART Set Up *** 
		banksel	BAUDCTL
		movlw	b'00000000'
		movwf	BAUDCTL
		banksel	SPBRG
		movlw	0x19		; 0x19 = 9600 BPS (0x0C = 19200 BPS) 
		movwf	SPBRG		; Baud Rate Generator Store Location
		movlw	b'10100100'
		movwf	TXSTA
		bcf	STATUS,RP0	; Bank 0
		bsf	RCSTA,SPEN	; Serial Port Enable bit
		bsf	RCSTA,CREN	; Continuous Receive Enable bit

;***
		call	Receive
		addlw	0x100-0x30
		movwf	HourHigh
		call	Receive
		addlw	0x100-0x30
		movwf	HourLow
		call	Receive
		addlw	0x100-0x30
		movwf	MinHigh
		call	Receive
		addlw	0x100-0x30
		movwf	MinLow
		call	Receive
		addlw	0x100-0x30
		movwf	SecHigh
		call	Receive
		addlw	0x100-0x30
		movwf	SecLow
		clrf	TEST
Main:
		goto	Main

;*** Receive *** 

Receive:		 
		btfss	PIR1,RCIF	; P1R1 is set when byte is recieved
		goto	Receive		;
		movf	RCREG,W		; Move received data into W
		return

;*** Send ***

Send:
		movwf	TXREG		; Load W into TXREG
		bsf	STATUS,RP0	; RAM Page 1
Wait:
		btfss	TXSTA,TRMT	; Transmission is complete when High
		goto	Wait		;
		bcf	STATUS,RP0	; RAM Page 0
		return


; *** Delay ***
Delay
		movlw	d'6'
		movwf	d1
D1		movlw	d'20'
		movwf	d2

D2		decfsz	d2,F
		goto	D2
		decfsz	d1,F
		goto	D1
		return

;***

		end

;*********************************************************8  
; Table
;		    					    (f) Left Top = bit5  
;		    __   (a) Top    = bit0 	(b) Righ Top = bit1     
;		   |__|  (g) Middle = bit6  (e) Left Bot = bit4  
;		   |__|  (d) Bottom = bit3	(c) Righ Bot = bit2  
;
;  = b'00000000' 
;0 = b'00111111' 
;1 = b'00000110' 
;2 = b'01011011' 
;3 = b'01001111' 
;4 = b'01100110'   
;5 = b'01101101'   
;6 = b'01111101'  			  
;7 = b'00001111'   
;8 = b'01111111'   
;9 = b'01101111'   
;
; That's all folks! 
;*************************************

Edit, just for completeness I'll attach a pic of my crystal setup. As you can see it is quite rough.

Mike.
 

Attachments

  • boo.png
    52.7 KB · Views: 214
  • Boo.jpg
    38.2 KB · Views: 236
Last edited:
Hey Pommie, I fixed the bit, AND STILL NO LUCK! What information could I give you that would help us debug this???

It is off by ~3seconds per hour now...

Only difference is the cap accross mains, but I do not see how that would help...
 
You should rebuild your circuit. You either have a duff chip or a duff crystal. No way can a crystal be off by 0.1%.

Mike.
 
I left the code running. It still shows compliance.

Mike.
 

Attachments

  • Boo.png
    52.9 KB · Views: 202
Are you sure it's not an errant interrupt causing the real world hardware to differ from the simulation? You could be double triggering an interrupt causing a delay in the code during a timer overflow. Hardware prolly works fine, software prolly works fine, but you might be missing transients on I/O lines.
 
Alright, the problem has been solved!!!!

Let me take you through the steps of what I believe has I had gotten wrong.

1) Probably the most important detail is that I had not synchronized my timer1 with the oscillator T1SYNC bit. When looking at the data sheet I got "confused" or read too fast. I had set it to 1.

2) Equally important detail. After fixing the pic part, how do you know a clock works?? You compare it to another one! I created a program that sends the time from the pic to the computer via serial port and showed it on the screen right next to the PCs time. I was often mislead into believing that my clock was not working because over time it slowly advanced past the PC clock. After researching a bit a came across the program "AtomicClock" which syncs your computer with the atomic clock in Boulder,CO. While using the program I realized that over time my PC would fall behind, but the PIC would stay in sync!!!! I left the clock on overnight to wake up to seeing it was 33 seconds behind the computer and was . After running the atomic clock, I saw that my PC was 33 seconds behind!!!!!!

I can't describe how amazing it feels to finally be able to stamp "finished" on this clock

Thank you all so much Sam, Eric, Mike, 3v0, and Scead and anybody who I am forgetting
 
That's a really crappy PC real time clock unit then! I've had one like that though, there's a way you can alter windows settings to cause it to resync to an atomic clock frequently. I had to do this on mine, as it was 5+ minutes off per day.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…