![]() | ![]() | ![]() |
| |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
![]() |
| | Tools |
| | #1 |
|
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 | |
| |
| | #2 |
|
It's a 4x7seg output display, I commented out the second registers so that I can compare seconds with a computer clock | |
| |
| | #3 |
|
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. | |
| |
| | #4 |
|
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. | |
| |
| | #5 | |
| Quote:
![]() ![]() 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. | ||
| |
| | #6 |
|
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. | |
| |
| | #7 |
|
Ill give that a shot Pommie | |
| |
| | #8 |
|
Tried with 33pf, 1 second error every 5 minutes | |
| |
| | #9 |
|
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;
}
}
}
}
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. | |
| |
| | #10 |
| 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. | |
| |
| | #11 |
| | |
| |
| | #12 |
|
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 | |
| |
| | #13 |
|
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? | |
| |
| | #14 |
|
No but would a Logic analyzer suffice?
| |
| |
| | #15 |
|
Sounds like a breadboard setup to me... Oscillator crystal layout is extremely important...
| |
| |
|
| 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 |