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 support@ccsinfo.com

Using external crystal oscillators as clock source
Goto page Previous  1, 2, 3
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kgng97ccs



Joined: 02 Apr 2022
Posts: 97

View user's profile Send private message

PostPosted: Wed Jun 29, 2022 2:30 am     Reply with quote

I am using the PIC18LF46K22, CCS PCWHD compiler v5.078, and MPLAB IDE v8.92.

I tried to check whether a 16-MHz crystal connected across OSC1 and OSC2 is being used by the MCU, by printing out the OSCCON register value.

Here is the relevant part of the code:
Code:
#include "18LF46K22.h"

#fuses PUT    /* enable power-up timer */
#fuses NOBROWNOUT    /* no brownout reset */
#fuses NOWDT    /* no watchdog timer */
#fuses MCLR    /* enable master clear pin */
#fuses HSH    /* use external crystal across OSC1 and OSC2 pins as system clock source */
#fuses FCMEN    /* enable fail-safe clock monitor */
#fuses IESO    /* enable internal/external oscillator switchover mode */

#define FOSC_Hz 16000000    /* system clock frequency */
#define MCU_eosc_xtal_Hz 16000000    /* frequency of external crystal */

#use delay(xtal=MCU_eosc_xtal_Hz, clock=FOSC_Hz)

void main()
{
   ...
   
   setup_oscillator(osc_16MHz | osc_normal);
   ...

   /* Delay for external crystal oscillator to stabilize;
      1,024 crystal oscillations = 64 us */
   delay_us(128);

   printf("OSCCON = %X\n", getenv("SFR:OSCCON"));
   ...
}

Result:
OSCCON = 0xD3 (binary 11010011)

The Oscillator Start-up Time-out Status bit (OSTS, bit 3) remains at zero, suggesting that the MCU is not running from the external crystal oscillator.

Is there something not right with the code?

I will appreciate any comments or suggestions. Thank you.

Correction:
The above printf statement for OSSCON is not correct. See Ttelmah’s post below, dated July 1, 2022.


Last edited by kgng97ccs on Fri Jul 01, 2022 11:02 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Wed Jun 29, 2022 3:01 am     Reply with quote

First one, get rid of the setup_oscillator line. Then see what happens.

You don't want or need this.

However bit obvious question is how your oscillator is wired. What capacitors
you have on it, what the crystal actually is (manufacturer) etc. etc?.
It will drop back if the primary fails.

Then you don't need your clock=statement. Just

#use delay(xtal=MCU_eosc_xtal_Hz)

This automatically sets the clock to 16MHz.
kgng97ccs



Joined: 02 Apr 2022
Posts: 97

View user's profile Send private message

PostPosted: Thu Jun 30, 2022 4:46 am     Reply with quote

Thank you, Ttelmah.

I tried these combinations:
Code:
/* Combination 1 */
#use delay(xtal=MCU_eosc_xtal_Hz)
...
setup_oscillator(osc_16MHz | osc_normal);

/* Combination 2 */
#use delay(xtal=MCU_eosc_xtal_Hz)
...
// No setup_oscillator

They both gave the same OSCCON value as before (bit 3 = 0).

The 16-MHz crystal (part no. ABM8-16.000MHZ-D1X-T) is connected to two 18-pf capacitors (C1 and C2, no Rs resistor, Figure 2-6, page 33 of PIC18LF46K22 datasheet).

As these parts have already been assembled on a PCB and it is difficult to access the OSC1 and OSC2 pins for testing, I tried running the program (loaded into the MCU, as before) by changing the FCMEN and IESO fuse settings:
Code:
/* Setting 1 */
#fuses NOFCMEN
#fuses NOIESO
#use delay(xtal=MCU_eosc_xtal_Hz)

setup_oscillator(osc_16MHz | osc_normal);

/* Setting 2 */
#fuses NOFCMEN
#fuses NOIESO
#use delay(xtal=MCU_eosc_xtal_Hz)

// No setup_oscillator

In both cases, the lst file did show the NOFCMEN and NOIESO fuses, and the program seemed to run properly, as I was able to see the PWM signals (PWM setup at https://www.ccsinfo.com/forum/viewtopic.php?t=59810).

Can this confirm that the MCU is actually running from the crystal oscillator?
temtronic



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

View user's profile Send private message

PostPosted: Thu Jun 30, 2022 5:59 am     Reply with quote

curious,
I decode the OSCCON to say the PIC is using the internal oscillator and running at 4MHz.

Can you please post a complete '1Hz LED' program ? Just posting 'parts' is hard to see the whole picture.
thanks
jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Thu Jun 30, 2022 7:32 am     Reply with quote

Key thing to do is check the OSCFIF bit.
If this is set, then the primary oscillator has failed. Probably implies
something is wrong with the crystal or the wiring.

You need to understand load capacitance.

The crystal has a rated load capacitance.
The capacitance it 'sees' as it's load is the capacitance of the tracks
and pins, in parallel with each of the external capacitors.

Cl=((C1 x C2) / (C1 + C2)) + Cstray

Typical stray capacitance is perhaps 3pF for the pins, and 5pF for the
tracks. So by pure luck, the two 18pF capacitors will give about 17pF
for Cl (assuming that the tracks for the pins are not long). However if
you are using something like a breadboard, this itself probably produces
more capacitance than is required....
Also some of the PIC oscillators, when using crystals this fast, will not
start without a load resistor across the crystal (perhaps 2MR).

So check OSCFIF, and if this is set, you then need to investigate why
your oscillator is not starting.
temtronic



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

View user's profile Send private message

PostPosted: Thu Jun 30, 2022 7:35 am     Reply with quote

If a real PCB, it HAS to be clean ! ANY 'flux' or 'debris' WILL affect the circuit... BTDT... usually it'll run but not at the correct frequency.
I used to use toothbrush and cleaner to be 100% sure what 'looks clean' WAS clean.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Thu Jun 30, 2022 10:16 am     Reply with quote

Absolutely.
And, as I've mentioned before I had a whole batch of crystals where the
case sealing was not correct. When the boards were washed after
production the, cleaner entered the case. Result some that were way
off frequency and more that wouldn't start at all.
Test the OSC fail interrupt bit and if this is setting, investigate what what
is wrong.
kgng97ccs



Joined: 02 Apr 2022
Posts: 97

View user's profile Send private message

PostPosted: Fri Jul 01, 2022 12:27 am     Reply with quote

Thank you, Jay and Ttelmah.

The PCBA is a sample board. As you suggested, I cleaned the crystal area, with methylated spirit and a toothbrush, and tested the program again.

For the capacitors, the hardware engineer explained that calculations were carried out and manufacturer’s recommendations were considered before he decided on 18 pf, but that he will investigate if the crystal oscillator is indeed not working.

I did not show it earlier, but we did put in code to light up an LED for one second before the "while (true)" loop just to see whether the program did start when we burned the code into the MCU. I have now added two printf statements: one for the OSCFIF bit, and one for the MCU FOSC.

The code goes like this:
Code:
#include "18LF46K22.h"

#fuses PUT   /* enable power-up timer */
#fuses NOBROWNOUT   /* no brownout reset */
#fuses NOWDT   /* no watchdog timer */
#fuses MCLR      /* enable master clear pin */
#fuses HSH      /* use external crystal across OSC1 and OSC2 pins */
#fuses NOFCMEN   /* disable fail-safe clock monitor */
#fuses NOIESO      /* disable internal/external oscillator switchover mode */

#define MCU_eosc_xtal_Hz 16000000    /* frequency of external crystal */
#define LED1 pin_D4

#bit OSCFIF=getenv("bit:OSCFIF")

#use delay(xtal=MCU_eosc_xtal_Hz)

#use pwm(PWM1, timer=4, frequency=125kHz, duty=50, pwm_off, stream=PWM1_LF1)
#use pwm(PWM3, timer=4, frequency=125kHz, duty=50, pwm_off, stream=PWM3_LF2)
#use pwm(PWM4, timer=2, frequency=38kHz, duty=25, pwm_off, stream=PWM4_IR1)
#use pwm(PWM5, timer=6, frequency=38kHz, duty=25, pwm_off, stream=PWM5_IR2)
...

void main()
{
   ...

   /* setup_oscillator(osc_16MHz | osc_normal); */
   ...
   
   /* Delay for external crystal oscillator to stabilize;
      1,024 crystal oscillations = 64 us */
   delay_us(128);
   
   printf("OSCCON = %X\n", getenv("SFR:OSCCON"));
   printf("OSCFIF = %X\n", OSCFIF);
   printf("CLOCK = %Lu\n", getenv("CLOCK"));
   ...
   
   output_low(LED1);   /* Low state will set LED input in circuit to high */
   delay_ms(1000);
   output_high(LED1);
   ...

   while (true)
   {
      ...      /* for sending PWM signals */
   }
}

Results:
1. The LED did light up.
2. OSCCON = 0xD3 (binary 11010011), the same as before. Jay, I also noticed that bits 6-4 (101) point to an internal RC oscillator frequency of 4 MHz.
3. OSCFIF = 0x00 (not set!)
4. CLOCK = 16000000 (16 MHz, as specified in “#use delay” directive)
5. All the four PWMs worked. The logic analyzer was able to capture all the PWM signals, and the signal frequencies (38 kHz and 125 kHz) were correct. See https://www.ccsinfo.com/forum/viewtopic.php?t=59810.
6. The lst file (at the bottom), again, did show the NOFCMEN NOIESO configuration fuses.

Would these results collectively suggest that the MCU was really running from the external oscillator, even though the OSCCON value does not look right?

Correction:
The above printf statement for OSSCON is not correct. See Ttelmah’s post below, dated July 1, 2022.


Last edited by kgng97ccs on Fri Jul 01, 2022 11:03 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Fri Jul 01, 2022 12:41 am     Reply with quote

There is a simple 'glaring' fault....

You are not reading OSCCON. What it is printing is the low 8 bits of the
address of the OSCCON register. 0xFD3.
You are not doing a #byte declaration, instead you are using the return
from getenv, which is the address, not the contents.....

You need:

printf("OSCCON = %X\n", *(getenv("SFR:OSCCON")));

Which then returns the _contents_ of the address returned by getenv.
kgng97ccs



Joined: 02 Apr 2022
Posts: 97

View user's profile Send private message

PostPosted: Fri Jul 01, 2022 1:21 am     Reply with quote

Thank you, Ttelmah, for catching this mistake!

The OSCCON now reads 0x38 (binary 00111000), in which bit 3 is set (=1), suggesting that the MCU is running from the crystal oscillator.

Thanks again.
kgng97ccs



Joined: 02 Apr 2022
Posts: 97

View user's profile Send private message

PostPosted: Fri Jul 01, 2022 3:02 am     Reply with quote

I put back the "setup_oscillator(osc_16MHz | osc_normal)", and the OSCCON reads 0x78 (binary 01111000), in which bit 3 is still 1, and bits 6-4 (111) correctly indicate the internal RC oscillator frequency setting of 16 MHz.
temtronic



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

View user's profile Send private message

PostPosted: Fri Jul 01, 2022 4:55 am     Reply with quote

I think you need
...
#use delay(external=16000000) ;

to tell the compiler to use the external xtal/2caps at 16MHz

setup_osc....(...) tells the compiler to use the INTERNAL rc osc

at least that's the way I read the manual, but then coffee isn't ready yet,
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 01, 2022 8:21 am     Reply with quote

temtronic, "external" is not a valid option for #use delay().
It does not compile. You get an error if you try.
Quote:
USE parameter value is out of range Unknown option: EXTERNAL
1 Errors, 0 Warnings.

He already is using the correct parameter which is 'xtal'.

Before posting, do what I do:
1. Read the PIC data sheet.
2. Read the CCS manual.
3. Do a test compilation.
4. If needed, do a hardware test.

When you have the correct answer, then post.

If you just post off the top of your head (ie. guessing), it just fills up the
forum with chaff that doesn't help the original poster.
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 Previous  1, 2, 3
Page 3 of 3

 
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