  | 
	  | 
		 
	 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		
			kgng97ccs
 
 
  Joined: 02 Apr 2022 Posts: 103
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Wed Jun 29, 2022 2:30 am     | 
				     | 
			 
			
				
  | 
			 
			
				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: 19967
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Wed Jun 29, 2022 3:01 am     | 
				     | 
			 
			
				
  | 
			 
			
				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: 103
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Jun 30, 2022 4:46 am     | 
				     | 
			 
			
				
  | 
			 
			
				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: 9589 Location: Greensville,Ontario 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Jun 30, 2022 5:59 am     | 
				     | 
			 
			
				
  | 
			 
			
				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: 19967
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Jun 30, 2022 7:32 am     | 
				     | 
			 
			
				
  | 
			 
			
				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: 9589 Location: Greensville,Ontario 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Jun 30, 2022 7:35 am     | 
				     | 
			 
			
				
  | 
			 
			
				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: 19967
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Jun 30, 2022 10:16 am     | 
				     | 
			 
			
				
  | 
			 
			
				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: 103
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Fri Jul 01, 2022 12:27 am     | 
				     | 
			 
			
				
  | 
			 
			
				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: 19967
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Fri Jul 01, 2022 12:41 am     | 
				     | 
			 
			
				
  | 
			 
			
				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: 103
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Fri Jul 01, 2022 1:21 am     | 
				     | 
			 
			
				
  | 
			 
			
				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: 103
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Fri Jul 01, 2022 3:02 am     | 
				     | 
			 
			
				
  | 
			 
			
				| 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: 9589 Location: Greensville,Ontario 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Fri Jul 01, 2022 4:55 am     | 
				     | 
			 
			
				
  | 
			 
			
				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
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Fri Jul 01, 2022 8:21 am     | 
				     | 
			 
			
				
  | 
			 
			
				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. | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
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
  
		 |