Author Topic: confusing clocks  (Read 7178 times)

0 Members and 1 Guest are viewing this topic.

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
confusing clocks
« on: June 03, 2016, 11:05:41 am »
http://ww1.microchip.com/downloads/en/devicedoc/39632c.pdf page 26

I bought the 18f2550 thinking it's just a regular pic chip, but it turns out that it's mainly used for usb applications, although that is useful, but it's not what I need right now, all I need is to run the damn thing knowing what clock speed i'm using, and the datasheet is so focused on settings clock for usb.

It's just that i'm not certain, and one thing I've learned in this field, is that if you're not 100% sure of everything, things will go bad.

I understand the OSCCON (OSCCON<6:4>  == IRCF2:IRCF0) settings for prescaling the internal 8MHz oscillator, but I don't understand the rest of them.

I'm trying to get a 16MHz external clock source to be transformed to a 1MHz frequency clock.


what do the PLLDIV and CPUDIV do exactly ? and what are the differences between them ? Can I use both of them at the same time ?


EDIT : Just wanted to add that I do not want to use the internal oscillator.
« Last Edit: June 03, 2016, 12:17:27 pm by MAD MACRO »
 

Offline rs20

  • Super Contributor
  • ***
  • Posts: 2318
  • Country: au
Re: confusing clocks
« Reply #1 on: June 03, 2016, 11:27:47 am »
Page 24 tells you the full story. PLLDIV and CPUDIV do what they say on that diagram. I was going to write a detailed explanation here, but I'd just be verbally describing the diagram!

With this chip, it is impossible to derive 1 MHz CPU clock from 16 MHz primary or secondary oscillators (at least, not without ignoring the "(4 MHz Input only)" warning on that one particular PLL there). Unless there's further dividers elsewhere. You can, however, use the internal oscillator with OSCCON<6:4> = 100, having some fun with manipulating the tuning bits.

If you're thinking this seems odd, this seems unusual to me too. The PLL in my ARM dev board is vastly more versatile than this.

You could also use a simple binary counter chip to divide by 16 for you.

EDIT: Just an additional note to clarify: You expressed a frustration that Table 2-3 only showed clocked configuration "for USB". Just to make it absolutely clear, Table 2-3 is an exhaustive list of all possible clock/oscillator configurations, whether you want USB or not (excepting those with input clock frequencies other than 4/8/12/16/20/24/40/48 MHz, for which use of the PLL is banned and you're restricted to the /1, /2, /3 and /4 options set by CPUDIV) (and except internal oscillator options.)
« Last Edit: June 03, 2016, 11:48:12 am by rs20 »
 

Offline uncle_bob

  • Supporter
  • ****
  • Posts: 2441
  • Country: us
Re: confusing clocks
« Reply #2 on: June 03, 2016, 11:37:48 am »
Hi

This is a PIC, so the "cpu clock" and the "instruction execution speed" are two different things. If you are after a 1 us execution speed, you need something other than a 1 MHz CPU clock ...

Not saying this is an issue in this case, just mentioning it since it is a VERY common thing to trip over.

Bob
 
The following users thanked this post: MAD MACRO

Offline ealex

  • Frequent Contributor
  • **
  • Posts: 313
  • Country: ro
Re: confusing clocks
« Reply #3 on: June 03, 2016, 11:40:36 am »
Hello

I'm not used to PIC cpu's but the clock tree is quite readable:
PLLDIV is used to set the proper PLL refference value - the PLL module must see only 4MHz at it's input
If you are not using the PLL it will not affect your clock settings.

The CPUDIV seems to change 2 different dividers - the one connected to the "Oscillator Postscaler" and the one connected to the "PLL Postscaler".

You can select the "Primary Clock" source via "FOSC3:FOSC0" and use that to choose the peripheral clock.

If you want to use the internal oscillator then you will connect via "INTOSC Postscaler" and set OSCCON<6:4> to "100"

With your 16MHz XTAL you can only obtain a 4MHz clock - divide by 4.

If you want to use an external XTAL you can either use a 4MHz crystal if the Primary Oscillator can use it, set CPUDIV to '11' ( /4 ), set  FOSC3:FOSC0 to 0 to choose Primary clock from "Oscillator Postscaler" then set the main mux to Primary Clock

If it can't oscillate that low, you should be able to make an external oscillator 4 / 3 / 2 /1MHz with some TTL gates and feed that signal via OSC1 or OSC2 pins - read the datasheet for this
 
The following users thanked this post: MAD MACRO

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: confusing clocks
« Reply #4 on: June 03, 2016, 11:55:35 am »
Hello,


You can select the "Primary Clock" source via "FOSC3:FOSC0" and use that to choose the peripheral clock.
FOSC configuration is simple
Code: [Select]
;     FOSC = XT_XT         XT oscillator (XT)
;     FOSC = XTPLL_XT      XT oscillator, PLL enabled (XTPLL)
;     FOSC = ECIO_EC       EC oscillator, port function on RA6 (ECIO)
;     FOSC = EC_EC         EC oscillator, CLKO function on RA6 (EC)
;     FOSC = ECPLLIO_EC    EC oscillator, PLL enabled, port function on RA6 (ECPIO)
;     FOSC = ECPLL_EC      EC oscillator, PLL enabled, CLKO function on RA6 (ECPLL)
;     FOSC = INTOSCIO_EC   Internal oscillator, port function on RA6, EC used by USB (INTIO)
;     FOSC = INTOSC_EC     Internal oscillator, CLKO function on RA6, EC used by USB (INTCKO)
;     FOSC = INTOSC_XT     Internal oscillator, XT used by USB (INTXT)
;     FOSC = INTOSC_HS     Internal oscillator, HS oscillator used by USB (INTHS)
;     FOSC = HS            HS oscillator (HS)
;     FOSC = HSPLL_HS      HS oscillator, PLL enabled (HSPLL)

I use  FOSC = HS       for external high speed oscillator clock source.

With your 16MHz XTAL you can only obtain a 4MHz clock - divide by 4.
this is bad news for me.

If you want to use an external XTAL you can either use a 4MHz crystal if the Primary Oscillator can use it, set CPUDIV to '11' ( /4 ), set  FOSC3:FOSC0 to 0 to choose Primary clock from "Oscillator Postscaler" then set the main mux to Primary Clock

If it can't oscillate that low, you should be able to make an external oscillator 4 / 3 / 2 /1MHz with some TTL gates and feed that signal via OSC1 or OSC2 pins - read the datasheet for this
I only have 20MHz, 16MHz and 12MHz oscillators, so I can't test this right now.


thanks for your reply :)




this has been repeated, so I have to mention it, I do not want to use the internal oscillator.


« Last Edit: June 03, 2016, 12:19:58 pm by MAD MACRO »
 

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: confusing clocks
« Reply #5 on: June 03, 2016, 11:57:30 am »
Hi

This is a PIC, so the "cpu clock" and the "instruction execution speed" are two different things. If you are after a 1 us execution speed, you need something other than a 1 MHz CPU clock ...

Not saying this is an issue in this case, just mentioning it since it is a VERY common thing to trip over.

Bob

I understand it's the instruction execution speed in pic is 1 instruction per 4 cpu cycles, right ?

so, if my final clock speed is 4MHz , this line is correct ?
Code: [Select]
#define _XTAL_FREQ 4000000
 

Offline uncle_bob

  • Supporter
  • ****
  • Posts: 2441
  • Country: us
Re: confusing clocks
« Reply #6 on: June 03, 2016, 12:06:46 pm »
Hi

This is a PIC, so the "cpu clock" and the "instruction execution speed" are two different things. If you are after a 1 us execution speed, you need something other than a 1 MHz CPU clock ...

Not saying this is an issue in this case, just mentioning it since it is a VERY common thing to trip over.

Bob




I understand it's the instruction execution speed in pic is 1 instruction per 4 cpu cycles, right ?

so, if my final clock speed is 4MHz , this line is correct ?
Code: [Select]
#define _XTAL_FREQ 4000000


Hi

Yes, for a "1 MHz" instruction rate, you want a 4 MHz CPU clock.

=====

It's really rare to see an application that has a *low* instruction rate requirement. About the only one I can think of off the top of my head it timing. There, your loops are all so weird that it quickly becomes a "don't bother" sort of thing. Peripheral clocks don't go through quite the same process. If that is the concern, we may be focusing in the wrong area ...

Bob
 

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: confusing clocks
« Reply #7 on: June 03, 2016, 12:16:36 pm »
Hi

This is a PIC, so the "cpu clock" and the "instruction execution speed" are two different things. If you are after a 1 us execution speed, you need something other than a 1 MHz CPU clock ...

Not saying this is an issue in this case, just mentioning it since it is a VERY common thing to trip over.

Bob




I understand it's the instruction execution speed in pic is 1 instruction per 4 cpu cycles, right ?

so, if my final clock speed is 4MHz , this line is correct ?
Code: [Select]
#define _XTAL_FREQ 4000000


Hi

Yes, for a "1 MHz" instruction rate, you want a 4 MHz CPU clock.

=====

It's really rare to see an application that has a *low* instruction rate requirement. About the only one I can think of off the top of my head it timing. There, your loops are all so weird that it quickly becomes a "don't bother" sort of thing. Peripheral clocks don't go through quite the same process. If that is the concern, we may be focusing in the wrong area ...

Bob

The reason I want 1MHz frequency, is for a self educational reasons, to understand the prescaling system more.
 

Offline uncle_bob

  • Supporter
  • ****
  • Posts: 2441
  • Country: us
Re: confusing clocks
« Reply #8 on: June 03, 2016, 12:21:46 pm »
Hi

This is a PIC, so the "cpu clock" and the "instruction execution speed" are two different things. If you are after a 1 us execution speed, you need something other than a 1 MHz CPU clock ...

Not saying this is an issue in this case, just mentioning it since it is a VERY common thing to trip over.

Bob




I understand it's the instruction execution speed in pic is 1 instruction per 4 cpu cycles, right ?

so, if my final clock speed is 4MHz , this line is correct ?
Code: [Select]
#define _XTAL_FREQ 4000000


Hi

Yes, for a "1 MHz" instruction rate, you want a 4 MHz CPU clock.

=====

It's really rare to see an application that has a *low* instruction rate requirement. About the only one I can think of off the top of my head it timing. There, your loops are all so weird that it quickly becomes a "don't bother" sort of thing. Peripheral clocks don't go through quite the same process. If that is the concern, we may be focusing in the wrong area ...

Bob

The reason I want 1MHz frequency, is for a self educational reasons, to understand the prescaling system more.

Hi

With a PIC, you can't always get any and every clock frequency. Some other MCU's are more flexible in this regard.  The PIC comes from a world of "faster it better" and does not offer the range of low speed options that others do. For most real world applications (other than low power) that's not a bit problem. Back in the 1980's it let them sell the chips for a lot less money that would have otherwise been the case. Today it's a relic of decisions made back in a long gone era.

Bob
 
The following users thanked this post: MAD MACRO

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: confusing clocks
« Reply #9 on: June 03, 2016, 01:45:34 pm »
Thanks bob :)

so, If I have an external oscillator of 16MHz frequency

and these too lines of codes.
Code: [Select]
#pragma config FOSC = HS // external high speed osc
#pragma config CPUDIV = OSC4_PLL6   // oscillator src clock: /4

I should have a 4MHz clock speed , right ?

Code: [Select]
#define _XTAL_FREQ 4000000
i'm using a delay of 10 seconds for led toggling and i'm getting a delay of about 2.1 seconds delay only.
 

Offline uncle_bob

  • Supporter
  • ****
  • Posts: 2441
  • Country: us
Re: confusing clocks
« Reply #10 on: June 03, 2016, 02:16:27 pm »
Thanks bob :)

so, If I have an external oscillator of 16MHz frequency

and these too lines of codes.
Code: [Select]
#pragma config FOSC = HS // external high speed osc
#pragma config CPUDIV = OSC4_PLL6   // oscillator src clock: /4

I should have a 4MHz clock speed , right ?

Code: [Select]
#define _XTAL_FREQ 4000000
i'm using a delay of 10 seconds for led toggling and i'm getting a delay of about 2.1 seconds delay only.


Hi

If you start from 16, divide by 4, you get a CPU clock of 4 MHz. That should give you an instruction execution of 1 us for most of them.

If the LED is blinking 5X to fast, you either are starting from 80 MHz (unlikely), or are not dividing by 4 (more likely), or there is a bug in your code (this sort of thing happens to the best of us ...).

Simple checks:

1) If you change the divide does the blink speed change?

2) If you take away the external clock does it stop blinking?

If it passes both of those tests, look for a bug in the code.

Bob
 
The following users thanked this post: MAD MACRO

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: confusing clocks
« Reply #11 on: June 03, 2016, 02:34:12 pm »
Thanks bob :)

so, If I have an external oscillator of 16MHz frequency

and these too lines of codes.
Code: [Select]
#pragma config FOSC = HS // external high speed osc
#pragma config CPUDIV = OSC4_PLL6   // oscillator src clock: /4

I should have a 4MHz clock speed , right ?

Code: [Select]
#define _XTAL_FREQ 4000000
i'm using a delay of 10 seconds for led toggling and i'm getting a delay of about 2.1 seconds delay only.


Hi

If you start from 16, divide by 4, you get a CPU clock of 4 MHz. That should give you an instruction execution of 1 us for most of them.

If the LED is blinking 5X to fast, you either are starting from 80 MHz (unlikely), or are not dividing by 4 (more likely), or there is a bug in your code (this sort of thing happens to the best of us ...).

Simple checks:

1) If you change the divide does the blink speed change?

2) If you take away the external clock does it stop blinking?

If it passes both of those tests, look for a bug in the code.

Bob


1) yes
2) yes

This is my code simplified as possible, tried it though.

Code: [Select]
#include <xc.h>

#define _XTAL_FREQ 4000000
//BEGIN CONFIG
#pragma config FOSC = HS
#pragma config CPUDIV = OSC4_PLL6
#pragma config WDT = OFF
#pragma config LVP = OFF   
#pragma config CPD = OFF 
//END CONFIG


/*miscellaneous*/
#define _BV(NUM)                (1 << NUM)
#define toggle(LAT,PIN)         LAT     ^=  _BV(PIN)
#define set_output(TRIS,PIN)    TRIS    &= ~_BV(PIN)
/*miscellaneous*/

void delay_10ms(unsigned char n)
{
    while (n-- != 0) __delay_ms(10);
}

int main()
{
    set_output(TRISC,0);
    while(1){   
        toggle(LATC,0);
        delay_10ms(1000);
    }
    return 0;
}
« Last Edit: June 03, 2016, 02:42:01 pm by MAD MACRO »
 

Offline uncle_bob

  • Supporter
  • ****
  • Posts: 2441
  • Country: us
Re: confusing clocks
« Reply #12 on: June 03, 2016, 02:43:35 pm »
Hi

I suspect that whatever compiler you are using is confused about how the clocks are set up.

Bob
 

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: confusing clocks
« Reply #13 on: June 03, 2016, 02:44:53 pm »
Hi

I suspect that whatever compiler you are using is confused about how the clocks are set up.

Bob

i'm using xc8, what do you mean confused ?
 

Offline uncle_bob

  • Supporter
  • ****
  • Posts: 2441
  • Country: us
Re: confusing clocks
« Reply #14 on: June 03, 2016, 02:47:58 pm »
Hi

I suspect that whatever compiler you are using is confused about how the clocks are set up.

Bob

i'm using xc8, what do you mean confused ?

Hi

You are using the delay 10 ms call for all of your timing. When you make a call like this in C, it goes off and looks up a bunch of defined "stuff' to figure out what to do to wait for that amount of time. The compiler sorts out all the various defines and runs a loop of some sort (or maybe does something else). If the defines that the compiler is using are not correct, the delay will be wrong.

Bob
 
The following users thanked this post: MAD MACRO

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: confusing clocks
« Reply #15 on: June 03, 2016, 03:02:18 pm »
Hi

I suspect that whatever compiler you are using is confused about how the clocks are set up.

Bob

i'm using xc8, what do you mean confused ?

Hi

You are using the delay 10 ms call for all of your timing. When you make a call like this in C, it goes off and looks up a bunch of defined "stuff' to figure out what to do to wait for that amount of time. The compiler sorts out all the various defines and runs a loop of some sort (or maybe does something else). If the defines that the compiler is using are not correct, the delay will be wrong.

Bob

So, I made my own definition like this, and used this one in the function
Code: [Select]
#define delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/1000)))
I get only 9.2 ms delay , but not 10.
 

Offline uncle_bob

  • Supporter
  • ****
  • Posts: 2441
  • Country: us
Re: confusing clocks
« Reply #16 on: June 03, 2016, 03:15:24 pm »
Hi

Take a look at the assembly output and see what it's really doing with your functions.

Bob
 

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: confusing clocks
« Reply #17 on: June 03, 2016, 03:17:22 pm »
Hi

Take a look at the assembly output and see what it's really doing with your functions.

Bob

I think this is the most relevant part of the asm code, I can't read assembly very well, it's like ancient black magic to me now.
Code: [Select]
_main:
;incstack = 0
opt stack 30
line 27

l616:
bcf (0+(0/8)+(c:3988)),c,(0)&7 ;volatile
line 29

l618:
movlw (01h)&0ffh
xorwf ((c:3979)),c ;volatile
line 30

l620:
movlw (0E8h)&0ffh

call _delay_10ms
goto l618
global start
goto start
opt stack 0
line 33
GLOBAL __end_of_main
__end_of_main:
signat _main,90
global _delay_10ms


not sure if this would be helpful, but a friend of mine(who works at the shop that I go to) told me once that the all chips and ICs that we have here are low quality and not as accurate as they're meant to be.
« Last Edit: June 03, 2016, 04:10:37 pm by MAD MACRO »
 

Online JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: confusing clocks
« Reply #18 on: June 03, 2016, 06:07:04 pm »
With a PIC, you can't always get any and every clock frequency. Some other MCU's are more flexible in this regard.

Like a dsPIC,PIC32 and  PIC12,16,18 that aren't ancient relics like a 18F2550

Anyway, to be of some use to the topic... :)
It is strange indeed that you get a much different delay time (a much lower one in this case)
what i'd try to do is to use an interrupt from a timer to get a precise delay and see if the clock is at the frequency it should be
« Last Edit: June 03, 2016, 06:13:43 pm by JPortici »
 
The following users thanked this post: MAD MACRO

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: confusing clocks
« Reply #19 on: June 03, 2016, 07:44:32 pm »
With a PIC, you can't always get any and every clock frequency. Some other MCU's are more flexible in this regard.

Like a dsPIC,PIC32 and  PIC12,16,18 that aren't ancient relics like a 18F2550

Anyway, to be of some use to the topic... :)
It is strange indeed that you get a much different delay time (a much lower one in this case)
what i'd try to do is to use an interrupt from a timer to get a precise delay and see if the clock is at the frequency it should be

well, thanks for the tip, well do, in post #15 i've mentioned that I've added my own definition of delay_ms() and it changed the results.

first mistake was a compiler's fault, and got that fixed, but it's still not accurate enough, from 10 seconds to 9.2 is not good enough.





Tried that, using timer0 interrupt.

loading results...
« Last Edit: June 03, 2016, 09:03:02 pm by MAD MACRO »
 

Offline uncle_bob

  • Supporter
  • ****
  • Posts: 2441
  • Country: us
Re: confusing clocks
« Reply #20 on: June 03, 2016, 10:17:08 pm »
With a PIC, you can't always get any and every clock frequency. Some other MCU's are more flexible in this regard.

Like a dsPIC,PIC32 and  PIC12,16,18 that aren't ancient relics like a 18F2550

Anyway, to be of some use to the topic... :)
It is strange indeed that you get a much different delay time (a much lower one in this case)
what i'd try to do is to use an interrupt from a timer to get a precise delay and see if the clock is at the frequency it should be

well, thanks for the tip, well do, in post #15 i've mentioned that I've added my own definition of delay_ms() and it changed the results.

first mistake was a compiler's fault, and got that fixed, but it's still not accurate enough, from 10 seconds to 9.2 is not good enough.





Tried that, using timer0 interrupt.

loading results...

Hi

What is the source of your 16 MHz clock?

Bob
 

Online JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: confusing clocks
« Reply #21 on: June 03, 2016, 11:37:07 pm »
But where are you using timer0? i don't see it

Anyway, I wouldn't use timer 0 for this purpose as it's harder to get a precise timing.
For this sort of tasks i use instead Timer2 and the likes: an interrupt is generated everytime the timer matches the period register, so the frequency between interrupts is exactly FCLK / (4 * PRESCALER * (PR2 + 1))

with timer 0 you either let it overflow at 255->0 or calculate the lenght of the interrupt routine and inside it you set the TMR0 value to get the interrupts spaced every XX ms
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: confusing clocks
« Reply #22 on: June 04, 2016, 05:45:12 pm »
please can we put uC questions in the right section ?
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: confusing clocks
« Reply #23 on: June 04, 2016, 07:26:54 pm »
Quote
I'm trying to get a 16MHz external clock source to be transformed to a 1MHz frequency clock.

The clock tree is pretty clear. To do what you need, you don't need PLL. So pick XT/HS/EC/ECIO, and then set CPUDIV to 4 -> 16Mhz / 4 = 4Mhz.

Done.
================================
https://dannyelectronics.wordpress.com/
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf