|
|
View previous topic :: View next topic |
Author |
Message |
Jakezilla3
Joined: 23 Feb 2009 Posts: 5
|
General Clock Question, how is it calculated? |
Posted: Mon Feb 23, 2009 4:20 pm |
|
|
Hi all, I am using a 18F4455, and have a question about the clock. I am using a USB bootloader and attached are a few of my includes.
Code: | #include <18F4455.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000) |
So, 20MHz comes in, PLLDIV=0b100, so becomes 20/5=4MHz. This in turn becomes 96MHz through the PLL scaler, /2 to get to the required 48MHz. This gets sent to USB Peripheral and everyone is happy.
HSPLL is also set so the 96MHz is sent to the PLL Postscaler. CPUDIV=0b10 so this is divided by 4, giving 24MHz "Primary Clock". My chip is running at a certifiable 12MHz confirmed by a simple pulse width experiment. This makes sens because the delay statement sets the clock to 48MHz, 48/4=12MHz and everywhere it says that the "main" clock is always divided by 4. So does't this 24MHz "Primary Clock" get cut in half somehow? I remember when wirewraping up my SBC using an Intel 80186 the clock was halved, so does the uController do the same thing but not talk about it anywhere? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 23, 2009 4:34 pm |
|
|
I have a question. If you want the PIC's CPU clock to run at 24 MHz,
why are setting the #use delay() statement to 48 MHz ? The #use delay
statement is what tells the compiler how to build the library code for
delay_us() and delay_ms(), as well as setting up the registers for
various peripherals. The #use delay() should always match the
actual CPU clock speed. |
|
|
Jakezilla3
Joined: 23 Feb 2009 Posts: 5
|
|
Posted: Mon Feb 23, 2009 5:03 pm |
|
|
You need to set it to 48MHz for USB communication, or so I thought. And I also thought that it takes that number and divides it by 4. So if you have a 20MHz external clock, and all the fuses set correctly, you put 20,000,000 in the delay statement, one clock tick is 1/(20MHz/4) = .2us |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 23, 2009 5:11 pm |
|
|
I took your fuse settings and made a test program. I don't have your PIC
but I have a related one. The LED blinks at 1 Hz. So the PIC is running
at 48 MHz with your settings.
Code: |
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
//==========================
void main()
{
while(1)
{
output_high(PIN_B0); // Blink LED
delay_ms(500);
output_low(PIN_B0);
delay_ms(500);
}
} |
|
|
|
Jakezilla3
Joined: 23 Feb 2009 Posts: 5
|
|
Posted: Mon Feb 23, 2009 6:08 pm |
|
|
I assume you have a 20MHz external clock? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 23, 2009 6:13 pm |
|
|
Yes. |
|
|
Jakezilla3
Joined: 23 Feb 2009 Posts: 5
|
|
Posted: Mon Feb 23, 2009 6:31 pm |
|
|
I am sorry if I am not explaining my problem/question very well.
From the help file Quote: | With an internal clock at 20mhz and with the T1_DIV_BY_8 mode, the timer will increment every 1.6us. |
So as I understand it, internal clock is 20MHz, that is divided by 4, then the T1_DIV_BY_8 divides it by 8 more, so 20/(4*8)=625kHz. 1/625kHz = 1.6us, the given value.
When using timers in my code with the settings int the OP, each timer tick is =0.0833333us, which extrapolated backwards through that same argument is -- internal clock = 48MHz, that is divided by 4 is 12MHz, so 1/12MHz is indeed .083333us
Where does this arbitrary divide by 4 take place? I don't see it in the diagram from the datasheet? |
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 24, 2009 3:55 am |
|
|
First thing.
The _#USE DELAY_ statement, is for the CPU, not the USB. The USB clock is separate from this.
Start with your external clock. 20MHz. Selecting HSPLL, says 'feed the CPU, from the clock coming from the USB PLL'. PLL5, says 'divide incoming clock by 5, to feed the USB PLL'. So you have 4MHz feeding this. The PLL performs a multiplication by 24, to give the USB master clock at 96MHz. Now, all the Microchip data sheet diagrams in a sense, slightly 'go wrong' at this point. This is divided by 2, to feed the USB system (as shown), but the feed to the CPU divider, also really comes off this 48MHz /2 output. CPUDIV1, then gives a CPU clock at 48MHz. Now this is 'Fosc' for the CPU. If you want to run the CPU at 24MHz, simply select CPUDIV2, and change the delay statement to match this. If you want to run at 20MHz, select 'HS', instead of 'HSPLL', and CPUDIV1, with a 20MHz DELAY statement. You can happily run the CPU, at almost any frequency you want (actually 'handling' the USB timings can become borderline, down at about 4MHz), even if you want using the RC clock. All that matters for USB, is that the external crystal, divided by the PLLx statement, gives 4Mhz.
The 'external clock', on the oscillator pins, is not the internal clock, with HSPLL selected. If you want to use the crystal frequency to run the CPU, use HS. The USB will still run OK.
Then if you now look at the timer diagram (Fig 12.1), note that it's clock, is either a separate external input, or "Fosc/4 internal clock". This is the 'extra' division by 4. In fact almost all the internal peripherals use this clock (commonly called the 'instruction' clock, since it corresponds to one instruction time).
Best Wishes |
|
|
Jakezilla3
Joined: 23 Feb 2009 Posts: 5
|
|
Posted: Tue Feb 24, 2009 1:57 pm |
|
|
Thank you so much for that excellent description! I knew that everything works but I just have a hard time accepting things happening behind the scenes unless I know how they are working.
So just a quick recap
external clock (OSC1) = 20MHz
internal clock (FOSC) = 48MHz
instruction clock (FOSC/4) = 12MHz |
|
|
|
|
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
|