CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Timer1 clock?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Sam_40



Joined: 07 Jan 2015
Posts: 127

View user's profile Send private message

Timer1 clock?
PostPosted: Sun Mar 22, 2015 1:25 pm     Reply with quote

Hello,
If I want to correctly define a PIC internal clock and TIMER1 external watch crystal clock, in the following code correct?

Code:
#use delay(clock=8000000)           // Use internal 8MHz
#define TIMER1_FREQUENCY (32768)    // Use watch crystal


Or do I need to do something else?

Thanks,
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Mar 22, 2015 1:38 pm     Reply with quote

The #use delay() is used by the compiler to calculate software delay loops
in delay_ms and delay_us. It's also used to calculate register settings
for peripherals when you specify a baudrate.

The compiler doesn't care about the frequency of Timer1 at all.
Any #define statement for that is for your own use.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Sun Mar 22, 2015 1:38 pm     Reply with quote

Repeat fifteen times _you need to tell us the PIC_. The settings differ according to the chip involved, but what you have, would not work on any chip. Yo are not telling the compiler to use the internal oscillator, and you are not setting up timer1.
Sam_40



Joined: 07 Jan 2015
Posts: 127

View user's profile Send private message

PostPosted: Sun Mar 22, 2015 2:05 pm     Reply with quote

My apologies Ttelmah,
Yes you did tell me a few times to define the chip Smile Please forgive me! it is 18F2685. I am still working on the timer RTC clock thingy Smile after a few days it lost 8 seconds, I checked the crystal with scope and it shows to be exact 32768Hz, When first I ran the project I notice the 33pF or 27pF caps (as per the PIC datasheet) throw off the crystal by a lot so I just used 12.5pf as the datasheet for the crystal. I have a good ground plan and the crystal and the caps for it are very close to the PIC and away from all other traces! I have a solid 5VDC and the PCB is in room temp. My though was maybe a code error or PIC problem.

However this question is just for my own info.
How to correctly define a PIC internal clock and TIMER1 external watch crystal clock?

PCM programmer,
Thanks for your reply, So you are saying that the PIC does not care about the TIMER1 or any other timer it would be how the TIMER is set. So in my situation how do I need to tell the PIC to run at 8MHz?

Best regards,
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Mar 22, 2015 2:12 pm     Reply with quote

#use delay() also tells the PIC how to setup the internal oscillator.
When you specify 8 MHz, the compiler programs OSCCON with the
correct settings for an 8 MHz internal oscillator.

The Timer1 oscillator will only run at 50 KHz max, according to the
18F2685 data sheet. It's basically only intended to run at 32 KHz.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Sun Mar 22, 2015 2:43 pm     Reply with quote

On the capacitors, these depend on the crystal, and the tracks you use.

Basically the crystal sees as it's loading, the capacitance of one track, paralleled with the pin capacitance, and one added capacitor, _in series_ with the same on the other pin. This is meant to match the load capacitance the crystal requires.
The load capacitance seen by the crystal, _is not_ the value of the capacitors used.
The values given in the PIC data sheet, are to give the correct load capacitance _for the crystal they specify_, with the short tracks laid out as described in their application note for this layout.
A crystal, that specifies a 12.5pF load capacitance will need capacitors like 18pF.

18pF+3pF(pin capacitance)+5pF(track capacitance) = 26pF

2*26pF capacitors _in series_ gives 13pF seen by the crystal.

Change the crystal, change the track layout, and the capacitors needed _will_ change.

Your comment 'good ground plane', worries me.
The crystal area is one place where you must be very careful of the ground plane. _Not_ running it round the crystal tracks. If you have a ground plane round the crystal tracks, and the track capacitance will shoot up. Read the Microchip data sheet about how to layout the ground round the clock tracks. Every different type of crystal, will have a different specified load capacitance.

Then I have to ask what sort of error you are seeing?. A typical 32768Hz crystal, will have an accuracy of only about 2 seconds a day _if loaded correctly_. Getting better than this requires a lot of work.
Sam_40



Joined: 07 Jan 2015
Posts: 127

View user's profile Send private message

PostPosted: Sun Mar 22, 2015 2:53 pm     Reply with quote

Well in about 5 days, my RTC is off by 8 seconds, I did follow the microchip guide as far as the ground ring around the crystal and the ground plane.

I may change the caps to 18pF and see!


Would you do me a favor and just write a test program to show me how you or PCM programmer would define the PIC internal oscillator and how to set up TIMER1 crystal? Just so I use it as standard from now on.

Or, would you please check this code and tell me if I need to improve it!

Code:
#include <18F2685.h>
#use delay(clock=8000000)



#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV21                   //Brownout reset at 2.0V
#FUSES PUT                      //Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOIESO                   //NO Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES NOPBADEN                 //NO PORTB pins are configured as digital I/O on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOLPT1OSC                //Timer1 configured for higher power operation
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

/* Start of the RTC program */

#Byte TMR1H = 0xFCF                                            /* TIMER1 HIGH BYTE LOOK DATASHEET */
#Byte T1CON = 0xFCD                                            /* TIMER1 CONFIG REGISTER LOOK DATASHEET */

int sec=0;
int min=0;
int hour=0;
int1 flg=false;

 #int_TIMER1
 void TIMER1_isr()    // 2^16=  65536/2 = 32768 * 1/32.768Hz <--- (1sec)                     
 {
   
    bit_clear(T1CON,7);                                        /* Enable access to the individual bytes of
                           the timer register */

    Bit_Set(TMR1H,7);                                          /* Add 32768 to timer1 by setting high bit
                           or timer register */       

    Bit_Set(T1CON,7);                                          /* Disable access to the individual bytes
                           of the timer register. */

    output_toggle(PIN_B3);                                     /* To toggle the LED on PIN RB3 every 2
                           seconds (1 second ON next second OFF). */
    flg=true;
    if(flg==true)
    {
   
         if (++sec>59)
         {
            sec=0;
            if(++min>59)
            {
               min=0;
               hour++;
               if(++hour>23)
               {
                  hour=0;
               }
            }
         }
    }
    flg=false;
 }
/* End of the RTC program */


/* Start of main() */
void main()
{
   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_CLK_OUT);

   enable_interrupts(INT_TIMER1);                             

   enable_interrupts(GLOBAL);

   setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_PLL_ON);            /* internal 8MHZ crystal with PLL ON 8X4=32MHZ */

}

/* End of main() */



Thanks,
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Mar 22, 2015 4:20 pm     Reply with quote

couple of tips...
1) I like my comments to 'line up'. Makes it easier to read, old school

2) The internal 8Mhz oscillator is not an ultra precise 'clock'. Seeing a few seconds +- over time is 'normal'. This will vary from PIC to PIC, as well as temperature,humidity, layout, etc. You can buy better quality caps which will help, also do a 'time study' and add a 'correction factor'.

3) I put the fuses in a separate file ( project.fuz) and #include it. Again, makes the program easier to read.

cheers
Jay
Sam_40



Joined: 07 Jan 2015
Posts: 127

View user's profile Send private message

PostPosted: Sun Mar 22, 2015 4:32 pm     Reply with quote

Jay,
I promise, my code is separated as you suggested and as I would do with ANSI C. Beside comments, I usually write a text file to detail what is the sequence of operation and why I did every complex (to me) line so I can remember! I only posted like I did so it would be one program other than insert several .h and .c files.
beside that, do the code look OK as far as what I need it to do?

Edit: The 8M is only to run the PIC, The RTC should use the crystal at 32768!

Edit 2: On a side note: I like and I have been using Notepad++ (just my preference) for my C codes writing/editing since the stone age Smile . For some reason, when past the code here it takes it out off the nice and neat flavor Mad such as: too much whitespace, overlap comments, ...etc.
Thanks,
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Mar 22, 2015 11:45 pm     Reply with quote

The 18F4520 data sheet has an MPASM code example in this section:
Quote:

EXAMPLE 12-1: IMPLEMENTING A REAL-TIME CLOCK USING A TIMER1 INTERRUPT SERVICE

It shows a method of synchronizing your update of TMR1H to the Timer1
clock. You wait until bit 0 of the TMR1L register goes to a '1'. Then you
write to TMR1H. I implemented this method in the code below. The
interrupt occurs at a 1 Hz rate. The LED will turn on for 1 second, and
then off for 1 second, continuously.
Code:

#include <18F4520.h>
#fuses INTRC_IO, NOWDT, BROWNOUT
#use delay(clock=8M)
#use rs232(baud=9600, UART1, ERRORS)

#define LED_PIN  PIN_B0

#byte TMR1L = getenv("SFR:TMR1L")
#byte TMR1H = getenv("SFR:TMR1H")
#bit RD16 = getenv("BIT:RD16")

//----------------------------
#int_timer1
void timer1_isr(void)
{
// This code follows the Microchip example for updating
// TMR1H when using an asynchronous clock with Timer1.
// A watch crystal oscillator is asynchronous to the
// PIC's internal oscillator (or crystal oscillator).
//
while((TMR1L & 1));   // Wait in loop until TMR1L.0 = 0
while(!(TMR1L & 1));  // Wait in loop until TMR1L.0 = 1
TMR1H |= 0x80;  // Start Timer1 at 0x8000 + existing small count

output_toggle(LED_PIN);
}   

//====================================
void main()
{
output_low(LED_PIN);

setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1 | T1_CLK_OUT);
RD16 = 0; // Modify T1CON setup to allow r/w of TMR1H

delay_ms(250);  // Allow time for Timer1 osc to start-up.

set_timer1(0x8000);  // This makes it interrupt in 1 second
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);

while(TRUE);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Mon Mar 23, 2015 12:28 am     Reply with quote

5 seconds in 8 days, is 1 in 138240.

Standard watch crystals offer accuracies of 1 in 20000 to 50000.

You are already getting all you are going to get. Better crystals can go to 1 in 100000, but you have to switch to temperature regulation or compensation. TXCO compensated crystals for example. These get up to perhaps at best 1 in a million accuracy.

You are expecting too much from your crystal. A minute a month, is a typical watch/clock accuracy.
Sam_40



Joined: 07 Jan 2015
Posts: 127

View user's profile Send private message

PostPosted: Mon Mar 23, 2015 6:23 am     Reply with quote

PCM programmer,
Thank you very much for the prompt reply and help. You've done so much for me, I don't even know how to thank you. I appreciate it . You made it clear for me to understand.
Before I started, I wanted to translate the ASM example in my PIC datasheet (same as 18F4520). However and without me asking, you did that for me!
I will add my functions to the code you provided and I will run it and see.
I really think you should add the provided code to the library.

Thanks,





Ttelmah,
Thanks for the information.
Sam_40



Joined: 07 Jan 2015
Posts: 127

View user's profile Send private message

PostPosted: Fri Sep 04, 2015 9:43 am     Reply with quote

Hello Guys,
I am reply for 2 reasons Smile

1- I want to give a feedback about my project. Using PCM programmer code (thank you sir) along with the citizen CFS206 5ppm and following the guide of this microchip AN at this link

"http://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en520645http://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en520645"

yield a very accurate clock at room temp. I made 2 clocks, one using 2X16 LCD and one with 6X7 seg display. they both are within 5 sec in 4 months of testing!

2- I have two question related to this project:

2-1: using 18F2685, the RA6 (only output) and RA7 (only input) are special pins, they also used for the main OSC. what is the best approach so they will not be floating pins? In my test boards, I just left them floating! FYI: RA1-RA5 used as inputs! I want my project to run on very low power I am using LM3986MP-5.0 as LDO to regulate from 12V battery that get charged by solar panel. In my final project I want to save power as much as I can!

2-2: I want the CPU to go to deep sleep with only TIMER1 operating for the RTC. However I want the CPU to run (wake up) upon a press of any button (input) on pins RA1-RA4, then go back to sleep after 10sec of NO inputs! What is the best approach? a simple test program or flow chart would be great!

Thanks in advance,
Sam
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 04, 2015 11:07 am     Reply with quote

Quote:
1. Using 18F2685, the RA6 (only output) and RA7 (only input) are
special pins, they also used for the main OSC

Not true. If you use the INTRC_IO fuse, the PIC will use the internal
oscillator. Pins A6 and A7 will be general purpose i/o pins. Both pins
can be inputs or outputs.
Quote:
What is the best approach so they will not be floating pins ?

Assuming they are not connected to anything, just do this:
Code:

output_low(PIN_A6);
output_low(PIN_A7);


Quote:

However I want the CPU to run (wake up) upon a press of any button
(input) on pins RA1-RA4,

Those pins don't have any interrupt capability. Look at in the
18F2685 data sheet, in the Overview section. Find this subsection:
TABLE 1-2: PIC18F2682/2685 PINOUT I/O DESCRIPTIONS
Look at the PortB pins for External interrupts, or interrupt-on-change.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Fri Sep 04, 2015 1:34 pm     Reply with quote

As PCM programmer has said, you can't wake on those pins. There is an 'add on' though, you could, with a tiny bit of extra hardware. If you took the four signals you have feeding A1, to A4, and feed these into an external 4 input CMOS NAND gate (as well as the pins), the output of this could connect to B0 (/INT), and the chip could then wake when any of the pins drops.

With the low power consumption of a static CMOS gate, gives low power, and easy wake up. Perhaps worth considering.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group