Yes it is a watch crystal only driving timer1. The MCU run on internal oscillator. The series resistance of a watch crystal is quite high. On the order of several Kohms, typical around 40Kohm. It is important, that care be taken to limit the drive to the crystal. Only a fraction of a mA of crystal current will damage this unit, causing it to stop oscillation.Maybe obvious for someone, but why R1 on the crystal? I have not seen that before.
Is the crystal recycled from a watch?
void lcd_format_and_send(void)
{ char timestr[3];
//lcd_clear();
lcd_goto(0x00);
lcd_puts("Klokken : ");
utoa(timestr, hour, 10);
if (hour<10)lcd_puts("0");
lcd_puts(timestr);
lcd_puts(":");
utoa(timestr, minut, 10);
if (minut<10)lcd_puts("0");
lcd_puts(timestr);
lcd_puts(":");
utoa(timestr, sec, 10);
if (sec<10)lcd_puts("0");
lcd_puts(timestr);
}
Please show your code that you use to setup the timer. The problem is most likely in there.That way i can time it ex by stopwatch, 10 sec and the circiut counts to 40. sec.
Please show your code that you use to setup the timer. The problem is most likely in there.
#include <htc.h>
//#include <stdio.h>
#include <stdlib.h>
#include "lcd.h"
__CONFIG (FCMEN_ON & IESO_OFF & BOREN_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON & WDTE_OFF & FOSC_INTOSC);//XT
__CONFIG (LVP_ON & LPBOR_OFF & BOREN_ON & STVREN_ON & WRT_OFF);
#define LED RC0
#define _XTAL_FREQ 4000000
//global defs
volatile unsigned char week_day;
volatile unsigned char hour, minut, sec;
volatile bit timer_tick;
volatile bit blink;
const char * const day_of_week_names[] = {"Monday feels so bad",
"Tuesday feel better",
"Wednesday don't go ",
"Thursday goes slow ",
"Friday on my mind ",
"Saturday Night Live",
"Sunday be sporty "
};
static void interrupt
isr(void) // Here is interrupt function - the name is
// unimportant.
{
if(TMR1IF)
{// Was this a timer overflow?
TMR1IF=0;//Clear interrupt flag, ready for next
TMR1H=0x80;
//If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
timer_tick=1;
}//we are done here
}
void setup(void)
{
IRCF0=1;
IRCF1=0;
IRCF2=1;
IRCF3=1;//4MHz clock speed
//REGISTER 5-1: OSCCON: OSCILLATOR CONTROL REGISTER
// bit 6-3 IRCF<3:0>: Internal Oscillator Frequency Select bits
//1111 = 16MHz
//1110 = 8MHz
//1101 = 4MHz
//1100 = 2MHz
//1011 = 1MHz
//1010 = 500 kHz(1)
//1001 = 250 kHz(1)
//1000 = 125 kHz(1)
//0111 = 500 kHz (default upon Reset)
//0110 = 250 kHz
//0101 = 125 kHz
//0100 = 62.5 kHz
//001x = 31.25 kHz
//000x = 31kHz LF
TRISA0=0;
TRISC=0b01111000;//RC0-RC2 out,RC3-RC6 in,RC7 out
TRISB=0; //All port B output
GIE = 0; // Global interrupt disable just in case
ANSELA=0;
ANSELB=0;
ANSELC=0;//turn off all analog functions
//timer1 settings
TMR1H=0x80;
TMR1L=0;
//T1CON=0b00000110;//used during debug
T1CON=0b10001100;
// See datasheet REGISTER 19-1: T1CON: TIMER 1 CONTROL REGISTER
// TMR1CS<1:0> T1CKPS<1:0> T1OSCEN !T1SYNC TMR1ON
//bit 7-6 TMR1CS<1:0>: Timer1 Clock Source Select bits
//11 =Timer1 clock source is Capacitive Sensing Oscillator (CAPOSC)
//10 =Timer1 clock source is pin or oscillator:
//If T1OSCEN = 0:
//External clock from T1CKI pin (on the rising edge)
// T1OSCEN = 0:
//Crystal oscillator on SOSCI/SOSCO pins
//01 =Timer1 clock source is system clock (FOSC)
//00 =Timer1 clock source is instruction clock (FOSC/4)
//bit 5-4 T1CKPS<1:0>: Timer1 Input Clock Prescale Select bits
//11 = 1:8 Prescale value
//10 = 1:4 Prescale value
//01 = 1:2 Prescale value
//00 = 1:1 Prescale value
//bit 3 T1OSCEN: LP Oscillator Enable Control bit
//1 = Dedicated Timer1 oscillator circuit enabled
//0 = Dedicated Timer1 oscillator circuit disabled
//bit 2 T1SYNC: Timer1 Synchronization Control bit
//1 = Do not synchronize asynchronous clock input
//0 = Synchronize asynchronous clock input with system clock (FOSC)
//bit 1 Unimplemented: Read as 0
//bit 0 TMR1ON: Timer1 On bit
//1 = Enables Timer1
//0 = Stops Timer1 and clears Timer1 gate flip-flop
TMR1GE=0;
//T1GCON: TIMER1 GATE CONTROL REGISTER
//bit 7 TMR1GE: Timer1 Gate Enable bit
//If TMR1ON = 0:
//This bit is ignored
//If TMR1ON = 1:
//1 = Timer1 counting is controlled by the Timer1 gate function
//0 = Timer1 counts regardless of Timer1 gate function
//Timer1 Interrupt prepare
TMR1IE=1;// PIE1 register
PEIE=1; //INTCON register
PIR1=0; // Clear all bits PERIPHERAL INTERRUPT REQUEST REGISTER 1
//todo now in order to generate interrupt GEI=1 and TMR1ON=1
//setup LCD
lcd_init();
lcd_goto(0); // select first line
//set the globals
week_day=4;
timer_tick=0;
blink=0;
//other misc settings
timer_tick=0;//clear the tick
}
void lcd_format_and_send(void)
{ char timestr[3];
//lcd_clear();
lcd_goto(0x00);
lcd_puts("Klokken : ");
utoa(timestr, hour, 10);
if (hour<10)lcd_puts("0");
lcd_puts(timestr);
lcd_puts(":");
utoa(timestr, minut, 10);
if (minut<10)lcd_puts("0");
lcd_puts(timestr);
lcd_puts(":");
utoa(timestr, sec, 10);
if (sec<10)lcd_puts("0");
lcd_puts(timestr);
// else lcd_puts("Next LED will be on ");
//lcd_goto(0x40); // Select second line
//lcd_puts("day of week ");
//lcd_putch(week_day+48);
// lcd_puts(day_of_week_names[week_day]);
// lcd_goto(0x00);
}
void main (void)
{ setup();
GIE=1;
TMR1ON=1;
while (1)
{
if (timer_tick)
{
sec++;
if (sec==60)
{
sec=0;
minut++;
if (minut>=60)
{ minut=0;
hour++;
if (hour>=24)
{ hour=0;
}
}
}
lcd_format_and_send();//send time to LCD
timer_tick=0;
//timer_tick=1;//just for debug
}// end if (timer_tick) Memo to my self put all this in sub function
}//end while endless loop
}//End main
I understood from the OP that the MCU is running with the XTAL. It is just running 4X faster than expected. More than likely it is timer initialization but I just do not have time right now to look at it.Let us do some basic checking. Do you have a LEDs connected on your board? I will first suggest a simple program running on the internal oscillator. Then just using the __delay_ms function to switch on and off a LED. This will check that the MCU is running on the clock speed we expect.
if(TMR1IF)
{// Was this a timer overflow?
TMR1IF=0;//Clear interrupt flag, ready for next
TMR1H=0x80;
//If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
T1CON=0b10101100;
T1CON=0b10001100;
First then you post something like this. You must also post something that explian your changes. It could be as easy as using copy and paste from the datasheetWhen i satinstead ofRich (BB code):T1CON=0b10101100;
i get a slower speed,Rich (BB code):T1CON=0b10001100;
takes now 40 real seconds to count 60 sec in chip.
if i change the TMR1H=0x80 to TMR1=0x80
i get a slower speed
80 real seconds to count to 60 sec in chip.
Why ??
#include <htc.h>
//#include <stdio.h>
#include <stdlib.h>
#include "lcd.h"
__CONFIG (CLKOUTEN_OFF & FCMEN_ON & IESO_OFF & BOREN_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON & WDTE_OFF & FOSC_XT);//INTOSC);//XT
__CONFIG (LVP_ON & LPBOR_OFF & BOREN_ON & STVREN_ON & WRT_OFF);
#define LED RC0
#define _XTAL_FREQ 4000000
//global defs
volatile unsigned char week_day;
volatile unsigned char hour, minut, sec;
volatile bit timer_tick;
volatile bit blink;
const char * const day_of_week_names[] = {"Monday feels so bad",
"Tuesday feel better",
"Wednesday don't go ",
"Thursday goes slow ",
"Friday on my mind ",
"Saturday Night Live",
"Sunday be sporty "
};
static void interrupt
isr(void) // Here is interrupt function - the name is
// unimportant.
{
if(TMR1IF)
{// Was this a timer overflow?
TMR1IF=0;//Clear interrupt flag, ready for next
TMR1H=0x80;
TMR1L=0;
//If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
timer_tick=1;
}//we are done here
}
void setup(void)
{
IRCF0=1;
IRCF1=0;
IRCF2=1;
IRCF3=1;//4MHz clock speed
//REGISTER 5-1: OSCCON: OSCILLATOR CONTROL REGISTER
// bit 6-3 IRCF<3:0>: Internal Oscillator Frequency Select bits
//1111 = 16MHz
//1110 = 8MHz
//1101 = 4MHz
//1100 = 2MHz
//1011 = 1MHz
//1010 = 500 kHz(1)
//1001 = 250 kHz(1)
//1000 = 125 kHz(1)
//0111 = 500 kHz (default upon Reset)
//0110 = 250 kHz
//0101 = 125 kHz
//0100 = 62.5 kHz
//001x = 31.25 kHz
//000x = 31kHz LF
TRISA0=0;
TRISC=0b01111000;//RC0-RC2 out,RC3-RC6 in,RC7 out
TRISB=0; //All port B output
GIE = 0; // Global interrupt disable just in case
ANSELA=0;
ANSELB=0;
ANSELC=0;//turn off all analog functions
//timer1 settings
TMR1H=0x80;
TMR1L=0;
//T1CON=0b00000110;//used during debug
T1CON=0b10101100;
// T1CON=0b10001100; //*4 speed
// See datasheet REGISTER 19-1: T1CON: TIMER 1 CONTROL REGISTER
// TMR1CS<1:0> T1CKPS<1:0> T1OSCEN !T1SYNC TMR1ON
//bit 7-6 TMR1CS<1:0>: Timer1 Clock Source Select bits
//11 =Timer1 clock source is Capacitive Sensing Oscillator (CAPOSC)
//10 =Timer1 clock source is pin or oscillator:
//If T1OSCEN = 0:
//External clock from T1CKI pin (on the rising edge)
// T1OSCEN = 0:
//Crystal oscillator on SOSCI/SOSCO pins
//01 =Timer1 clock source is system clock (FOSC)
//00 =Timer1 clock source is instruction clock (FOSC/4)
//bit 5-4 T1CKPS<1:0>: Timer1 Input Clock Prescale Select bits
//11 = 1:8 Prescale value
//10 = 1:4 Prescale value
//01 = 1:2 Prescale value
//00 = 1:1 Prescale value
//bit 3 T1OSCEN: LP Oscillator Enable Control bit
//1 = Dedicated Timer1 oscillator circuit enabled
//0 = Dedicated Timer1 oscillator circuit disabled
//bit 2 T1SYNC: Timer1 Synchronization Control bit
//1 = Do not synchronize asynchronous clock input
//0 = Synchronize asynchronous clock input with system clock (FOSC)
//bit 1 Unimplemented: Read as 0
//bit 0 TMR1ON: Timer1 On bit
//1 = Enables Timer1
//0 = Stops Timer1 and clears Timer1 gate flip-flop
TMR1GE=0;
//T1GCON: TIMER1 GATE CONTROL REGISTER
//bit 7 TMR1GE: Timer1 Gate Enable bit
//If TMR1ON = 0:
//This bit is ignored
//If TMR1ON = 1:
//1 = Timer1 counting is controlled by the Timer1 gate function
//0 = Timer1 counts regardless of Timer1 gate function
//Timer1 Interrupt prepare
TMR1IE=1;// PIE1 register
PEIE=1; //INTCON register
PIR1=0; // Clear all bits PERIPHERAL INTERRUPT REQUEST REGISTER 1
//todo now in order to generate interrupt GEI=1 and TMR1ON=1
//setup LCD
lcd_init();
lcd_goto(0); // select first line
//set the globals
week_day=4;
timer_tick=0;
blink=0;
//other misc settings
timer_tick=0;//clear the tick
}
void lcd_format_and_send(void)
{ char timestr[3];
//lcd_clear();
lcd_goto(0x00);
lcd_puts("Klokken : ");
utoa(timestr, hour, 10);
if (hour<10)lcd_puts("0");
lcd_puts(timestr);
lcd_puts(":");
utoa(timestr, minut, 10);
if (minut<10)lcd_puts("0");
lcd_puts(timestr);
lcd_puts(":");
utoa(timestr, sec, 10);
if (sec<10)lcd_puts("0");
lcd_puts(timestr);
// else lcd_puts("Next LED will be on ");
//lcd_goto(0x40); // Select second line
//lcd_puts("day of week ");
//lcd_putch(week_day+48);
// lcd_puts(day_of_week_names[week_day]);
// lcd_goto(0x00);
}
void main (void)
{ setup();
GIE=1;
TMR1ON=1;
while (1)
{
if (timer_tick)
{
sec++;
if (sec==60)
{
sec=0;
minut++;
if (minut>=60)
{ minut=0;
hour++;
if (hour>=24)
{ hour=0;
}
}
}
lcd_format_and_send();//send time to LCD
timer_tick=0;
//timer_tick=1;//just for debug
}// end if (timer_tick) Memo to my self put all this in sub function
}//end while endless loop
}//End main
Not that I think it matters, but in your void setup() you haveOk, try to remember another time,
Here is the complete code, that do not run at right speed.
Rich (BB code):#include <htc.h> //#include <stdio.h> #include <stdlib.h> #include "lcd.h" __CONFIG (CLKOUTEN_OFF & FCMEN_ON & IESO_OFF & BOREN_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON & WDTE_OFF & FOSC_XT);//INTOSC);//XT __CONFIG (LVP_ON & LPBOR_OFF & BOREN_ON & STVREN_ON & WRT_OFF); #define LED RC0 #define _XTAL_FREQ 4000000 //global defs volatile unsigned char week_day; volatile unsigned char hour, minut, sec; volatile bit timer_tick; volatile bit blink; const char * const day_of_week_names[] = {"Monday feels so bad", "Tuesday feel better", "Wednesday don't go ", "Thursday goes slow ", "Friday on my mind ", "Saturday Night Live", "Sunday be sporty " }; static void interrupt isr(void) // Here is interrupt function - the name is // unimportant. { if(TMR1IF) {// Was this a timer overflow? TMR1IF=0;//Clear interrupt flag, ready for next TMR1H=0x80; TMR1L=0; //If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second timer_tick=1; }//we are done here } void setup(void) { IRCF0=1; IRCF1=0; IRCF2=1; IRCF3=1;//4MHz clock speed //REGISTER 5-1: OSCCON: OSCILLATOR CONTROL REGISTER // bit 6-3 IRCF<3:0>: Internal Oscillator Frequency Select bits //1111 = 16MHz //1110 = 8MHz //1101 = 4MHz //1100 = 2MHz //1011 = 1MHz //1010 = 500 kHz(1) //1001 = 250 kHz(1) //1000 = 125 kHz(1) //0111 = 500 kHz (default upon Reset) //0110 = 250 kHz //0101 = 125 kHz //0100 = 62.5 kHz //001x = 31.25 kHz //000x = 31kHz LF TRISA0=0; TRISC=0b01111000;//RC0-RC2 out,RC3-RC6 in,RC7 out TRISB=0; //All port B output GIE = 0; // Global interrupt disable just in case ANSELA=0; ANSELB=0; ANSELC=0;//turn off all analog functions //timer1 settings TMR1H=0x80; TMR1L=0; //T1CON=0b00000110;//used during debug T1CON=0b10101100; // T1CON=0b10001100; //*4 speed // See datasheet REGISTER 19-1: T1CON: TIMER 1 CONTROL REGISTER // TMR1CS<1:0> T1CKPS<1:0> T1OSCEN !T1SYNC TMR1ON //bit 7-6 TMR1CS<1:0>: Timer1 Clock Source Select bits //11 =Timer1 clock source is Capacitive Sensing Oscillator (CAPOSC) //10 =Timer1 clock source is pin or oscillator: //If T1OSCEN = 0: //External clock from T1CKI pin (on the rising edge) // T1OSCEN = 0: //Crystal oscillator on SOSCI/SOSCO pins //01 =Timer1 clock source is system clock (FOSC) //00 =Timer1 clock source is instruction clock (FOSC/4) //bit 5-4 T1CKPS<1:0>: Timer1 Input Clock Prescale Select bits //11 = 1:8 Prescale value //10 = 1:4 Prescale value //01 = 1:2 Prescale value //00 = 1:1 Prescale value //bit 3 T1OSCEN: LP Oscillator Enable Control bit //1 = Dedicated Timer1 oscillator circuit enabled //0 = Dedicated Timer1 oscillator circuit disabled //bit 2 T1SYNC: Timer1 Synchronization Control bit //1 = Do not synchronize asynchronous clock input //0 = Synchronize asynchronous clock input with system clock (FOSC) //bit 1 Unimplemented: Read as 0 //bit 0 TMR1ON: Timer1 On bit //1 = Enables Timer1 //0 = Stops Timer1 and clears Timer1 gate flip-flop TMR1GE=0; //T1GCON: TIMER1 GATE CONTROL REGISTER //bit 7 TMR1GE: Timer1 Gate Enable bit //If TMR1ON = 0: //This bit is ignored //If TMR1ON = 1: //1 = Timer1 counting is controlled by the Timer1 gate function //0 = Timer1 counts regardless of Timer1 gate function //Timer1 Interrupt prepare TMR1IE=1;// PIE1 register PEIE=1; //INTCON register PIR1=0; // Clear all bits PERIPHERAL INTERRUPT REQUEST REGISTER 1 //todo now in order to generate interrupt GEI=1 and TMR1ON=1 //setup LCD lcd_init(); lcd_goto(0); // select first line //set the globals week_day=4; timer_tick=0; blink=0; //other misc settings timer_tick=0;//clear the tick } void lcd_format_and_send(void) { char timestr[3]; //lcd_clear(); lcd_goto(0x00); lcd_puts("Klokken : "); utoa(timestr, hour, 10); if (hour<10)lcd_puts("0"); lcd_puts(timestr); lcd_puts(":"); utoa(timestr, minut, 10); if (minut<10)lcd_puts("0"); lcd_puts(timestr); lcd_puts(":"); utoa(timestr, sec, 10); if (sec<10)lcd_puts("0"); lcd_puts(timestr); // else lcd_puts("Next LED will be on "); //lcd_goto(0x40); // Select second line //lcd_puts("day of week "); //lcd_putch(week_day+48); // lcd_puts(day_of_week_names[week_day]); // lcd_goto(0x00); } void main (void) { setup(); GIE=1; TMR1ON=1; while (1) { if (timer_tick) { sec++; if (sec==60) { sec=0; minut++; if (minut>=60) { minut=0; hour++; if (hour>=24) { hour=0; } } } lcd_format_and_send();//send time to LCD timer_tick=0; //timer_tick=1;//just for debug }// end if (timer_tick) Memo to my self put all this in sub function }//end while endless loop }//End main
TRISA0=0;
T1CKPS1 = 0; // bits 5-4 Prescaler Rate Select bits
T1CKPS0 = 0;
T1OSCEN = 1; // bit 3 Timer1 Oscillator Enable Control: bit 1=on
T1SYNC = 1; // bit 2 Timer1 External Clock Input Synchronization Control bit: 1=Do not synchronize external clock input
T1CONbits.TMR1CS = 0; // bit 1 Timer1 Clock Source Select bit: 0=Internal clock (FOSC/4) / 1 = External clock from pin T1CKI (on the rising edge)
TMR1IP = 0; // Timer1 is low priority interrupt
TMR1IE = 1; // Enable interrupts for Timer 1
TMR1CS1=1; //CLOCK SOURCE SELECTIONS
TMR1CS0=1;
//11 =Timer1 clock source is Capacitive Sensing Oscillator (CAPOSC)
//10 =Timer1 clock source is pin or oscillator:
//If T1OSCEN = 0:
//External clock from T1CKI pin (on the rising edge)
//If T1OSCEN = 1:
//Crystal oscillator on SOSCI/SOSCO pins
//01 =Timer1 clock source is system clock (FOSC)
//00 =Timer1 clock source is instruction clock (FOSC/4)
// <1:0>: Timer1 Input Clock Prescale Select bits
T1CKPS1=0;
T1CKPS0=0;
//11 = 1:8 Prescale value
//10 = 1:4 Prescale value
//01 = 1:2 Prescale value
//00 = 1:1 Prescale value
T1OSCEN=1;//LP Oscillator Enable Control bit
//1 = Dedicated Timer1 oscillator circuit enabled
//0 = Dedicated Timer1 oscillator circuit disabled
nT1SYNC=1; //: Timer1 Synchronization Control bit
TMR1ON=0;//: Timer1 On bit
TMR1H = 0x80; // preset for timer1 MSB register
TMR1L = 0x00; // preset for timer1 LSB register