Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Tools
Old 27th October 2009, 08:31 PM   #1
Default pic16f882 timer1 clock crystal

Hey guys, I just can't seem to make it work!
It's running 1s faster than it should be every minute!!!

Here's my code, maybe you can spot something out!

32.768Khz Osc, Two 10pF caps.

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		PORTC,4
#Define 	MHigh		PORTC,5
#Define		HLow		PORTC,6
#Define 	HHigh		PORTC,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

;*** 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
	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		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

;	MOVLW 	b’00001111’ ; Configure for external clock, from pic16f88 datasheet
;	MOVWF 	T1CON ; Asynchronous operation, external oscillator

	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


	MOVLW	d'0'
	MOVWF	SecLow
	MOVLW	d'0'
	MOVWF	SecHigh
	MOVLW	d'0'
	MOVWF	MinLow
	MOVLW	d'0'
	MOVWF	MinHigh
	MOVLW	d'2'
	MOVWF	HourLow
	MOVLW	d'1'
	MOVWF	HourHigh

	CLRF	TEST


Main:
	Call 	TurnOffNumbers
	MOVF	MinLow,W
	Call 	Table
	MOVWF	MinL
	HC595 	MinL,X
	BSF		MLow	
	Call 	Delay

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

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

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

	GOTO 	Main

TurnOffNumbers:
	BCF 	MLow
	BCF 	MHigh
	BCF 	HLow
	BCF 	HHigh
	RETURN	

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

; *** 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
__________________
Mike
My website: www.ElectroBird.net
birdman0_o is online now  
Old 27th October 2009, 08:32 PM   #2
Default

It's a 4x7seg output display, I commented out the second registers so that I can compare seconds with a computer clock
__________________
Mike
My website: www.ElectroBird.net
birdman0_o is online now  
Old 27th October 2009, 11:55 PM   #3
Default

Hi,


Don't know the exact parameters of the 32k xtal you are using, but the ones I have used give good time, to seconds per week, when using 22, 27 or 33 pf.
Wp100 is offline  
Old 28th October 2009, 03:41 AM   #4
Default

Strip it down to the most basic code you can use to make a second. With a 32kHz xtal clocking TMR1 that's pretty easy, you set the TMR1 prescaler so it overflows (and makes an interrupt) every second.

Just get it to toggle a LED once a second at first. You can test that against your watch. Once you have that working and tested for accuracy you can fluff out the code to do minutes and hours etc.
Mr RB is offline  
Old 28th October 2009, 04:00 AM   #5
Default

Quote:
Originally Posted by Mr RB View Post
Strip it down to the most basic code you can use to make a second. With a 32kHz xtal clocking TMR1 that's pretty easy, you set the TMR1 prescaler so it overflows (and makes an interrupt) every second.
I'd like to see how you set the prescaler to 0.5!

On a more serious note, the code he is using is the example code from the 16F88 data sheet. I can't see why it would be inaccurate and think it must be hardware related.

Mike.
Pommie is offline  
Old 28th October 2009, 04:26 AM   #6
Default

Just had a look through the 16F88 data sheet and Microchip suggest 33pF caps with the LP crystal. Can you change your caps and make sure the crystal is as close as possible to the chip.

Mike.
Pommie is offline  
Old 28th October 2009, 04:40 AM   #7
Default

Ill give that a shot Pommie
__________________
Mike
My website: www.ElectroBird.net
birdman0_o is online now  
Old 28th October 2009, 04:56 AM   #8
Default

Tried with 33pf, 1 second error every 5 minutes
__________________
Mike
My website: www.ElectroBird.net
birdman0_o is online now  
Old 28th October 2009, 06:00 AM   #9
Default

Well, you got me curious and so I added a 32k crystal to a board I have with a 16F886 on it. I used 15pF capacitors and the following code,
Code:
#include <system.h>
#include "LCD.c"

#pragma DATA _CONFIG, _DEBUG_ON & _MCLRE_ON
                    & _CP_OFF & _PWRTE_OFF
                    & _WDT_OFF & _INTOSCIO
                    & _LVP_OFF

char PK2_Reserved @0x70;
unsigned char seconds,minutes,hours,oldseconds;

void main(void){
    while(!osccon.HTS);
    osccon=0x71;            //8 meg
    ansel=0;
    anselh=0;
    option_reg=0b00000000;  //wpu on
    InitLCD();
    hours=0;
    minutes=0;
    seconds=0;
    oldseconds=0;
    t1con=0b00001111;
    pie1.TMR1IE=1;
    intcon.PEIE=1;
    intcon.GIE=1;
    while(1){
        if(seconds!=oldseconds){
            oldseconds=seconds;
            SetPos(0,0);
            PutDecimal(hours);
            PutChar(':');
            PutDecimal(minutes);
            PutChar(':');
            PutDecimal(seconds);
        }
    }
}

void interrupt(void){
    if(pir1.TMR1IF){
        pir1.TMR1IF=0;
        tmr1h.7=1;
        if(++seconds==60){
            seconds=0;
            if(++minutes==60){
                minutes=0;
                if(++hours==24)
                    hours=0;
            }
        }
    }
}
It's now been running 15 minutes and appears to be keeping excellent time.

I know this is in C but it is using the hardware in an identical way to you. I highlighted the relevant bits.

Edit, now been running over 8 hours and still spot on.

Mike.

Last edited by Pommie; 28th October 2009 at 01:22 PM.
Pommie is offline  
Old 28th October 2009, 03:28 PM   #10
Default

Quote:
Originally Posted by Pommie View Post
I'd like to see how you set the prescaler to 0.5!
...
Mr Smarty Pants! You could tell I typed that in a hurry huh?

I remember whan I used a Dallas temp compensated 32kHz that i set it up to automatically TMR1 interrupt every second. Now I think about it the prescaler was set to 1:1 and I just set TMR1.F7 like in your examples.

The reason I posted that was because i thought his timer may have been right but there could be a bug in the seconds/minutes incrementing, that would be an obvious cause of a +1 sec per min error. Checking the seconds themselves for accuracy would separate the bug into either faulty timing or faulty seconds incrementing. Bugs like that can be a bit hard to catch in the simulator.
Mr RB is offline  
Old 28th October 2009, 03:39 PM   #11
Default

Quote:
Originally Posted by Mr RB View Post
Mr Smarty Pants! You could tell I typed that in a hurry huh?
Sorry, couldn't resist.

Mike.
Pommie is offline  
Old 28th October 2009, 04:41 PM   #12
Default

It must be a capacitor error. With 10pF, the timing was ~ 1s /Min. With 33pf it was ~1s/5min and with around 5 pf it was ~ 1 s/17 min.

This is much more frustrating then I wanted it to be
__________________
Mike
My website: www.ElectroBird.net
birdman0_o is online now  
Old 28th October 2009, 08:45 PM   #13
Default

Are you using a breadboard? The contact strips add a few pF of capacitance themselves. Try it without any caps and see what you get, if that's the case.

Do you have an oscilloscope so you can verify the crystal waveform with different caps?
kpatz is offline  
Old 28th October 2009, 11:08 PM   #14
Default

No but would a Logic analyzer suffice?
__________________
Mike
My website: www.ElectroBird.net
birdman0_o is online now  
Old 29th October 2009, 01:03 AM   #15
Default

Sounds like a breadboard setup to me... Oscillator crystal layout is extremely important...
Mike, K8LH is offline  
Reply

Tags
clock, crystal, pic, timer1

Thread Tools
Display Modes


Similar
Title Starter Forum Replies Latest
Clock with Timer1 PIC2PIC Micro Controllers 17 29th August 2009 01:28 PM
PIC clock cycles, instructions, and crystal frequency? Hank Fletcher Micro Controllers 4 7th June 2008 09:07 PM
Timer1 richb Micro Controllers 5 27th November 2006 11:44 PM
HELP: Connecting 4MHz crystal clock to PIC mr. mister Micro Controllers 3 21st April 2005 01:27 PM
Can I use a 24mhz or 19.968 mhz crystal clock oscillator ? xpembedded Micro Controllers 1 9th June 2004 10:48 PM



All times are GMT. The time now is 10:07 PM.


Electronic Circuits  |  Learning Electronics
eXTReMe Tracker