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

Clock / PLL on 18F4550

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
amcfall



Joined: 20 Oct 2005
Posts: 44

View user's profile Send private message

Clock / PLL on 18F4550
PostPosted: Thu Jun 01, 2006 7:50 am     Reply with quote

OK, I'm quite confused here. I'm setting up a project with a 18F4550 and can't figure out why I'm gertting the wrong frequency (haven't even gotten to the USB portion yet).

Looking at fig 2-1 in the manual (clock diagram), I had decided on the following setup:

4Mhz crystal
XTPLL mode
PLL1 (no prescaler, 4Mhz input)
CPUDIV4 (to get 24Mhz from the 96Mhz PLL)

When I use the XT fuse and set the clock for 4Mhz, everything works as expected. When I attempt to use XTPLL and set the clock for 24Mhz I get longer durations than expected on the buzzer pin. I scoped it it looked like the clock was running slower than calculated. I changed the clock speed to 16Mhz and timing is correct (RS232 works also). So, somehow it's running at 16 instead of 24. I figure I'm doing somehting wrong, but I'm not sure what (haven't messed with PLL before).

The following code works, but the clock is set for 16 and I expected 24 to be the corect setting.

Code:


   #include <18F4550.h>
   #device adc=8
   #FUSES NOWDT                    //No Watch Dog Timer
   #FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
//   #FUSES XT
   #FUSES XTPLL                    //Crystal/Resonator with PLL enabled
   #FUSES NOPROTECT                //Code not protected from reading
   #FUSES BROWNOUT_NOSL            //Brownout enabled during operation, disabled during SLEEP
   #FUSES BROWNOUT                 //Reset when brownout detected
   #FUSES BORV20                   //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                   //Internal External Switch Over mode disabled
   #FUSES NOFCMEN                  //Fail-safe clock monitor disabled
   #FUSES NOPBADEN                 //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 NOMCLR                     //Master Clear pin enabled
   #FUSES LPT1OSC                  //Timer1 configured for low-power operation
   #FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
   #FUSES PLL1                     //No PLL PreScaler
   #FUSES CPUDIV4
   #FUSES USBDIV
   #use delay(clock=16000000)

#DEFINE BUZZER PIN_C2   

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)


void main(void) {
   unsigned int16 buzzy=0;
   delay_ms(100);
   printf("\r\n\npower on\n\r\n\r");
   for (buzzy=0;buzzy<10000;buzzy++)
      {
      output_high(BUZZER);
      delay_us(500);
      output_low(BUZZER);
      delay_us(500);
      }

   delay_ms(1000);
   printf("\r\n\ndone beeping\n\r\n\r");
   while(1);
      delay_cycles(1);
}




Thanks,

Avery

EDIT: Compiler 3.236
amcfall



Joined: 20 Oct 2005
Posts: 44

View user's profile Send private message

PostPosted: Thu Jun 01, 2006 8:06 am     Reply with quote

The more I dig the more confused I am. Here's what MPLAB says my fuses are, under CPU system clock postscaler:

[Osc1/Osc2 src: /4] [96Mhz PLL src: /6]

the 1/6 postscaler would jive with the 16Mhz clock, so I must be reading this completely wrong.

Avery
amcfall



Joined: 20 Oct 2005
Posts: 44

View user's profile Send private message

PostPosted: Thu Jun 01, 2006 9:03 am     Reply with quote

CPUDIV4 gives
[Osc1/Osc2 src: /4] [96Mhz PLL src: /6]

CPUDIV3 gives
[Osc1/Osc2 src: /3] [96Mhz PLL src: /4]

So there's some relation between these things I don't get. Can anyone tell me where I should have seen this in the data sheet? I had assumed that CPUDIV4 (which says system clock by 4 in fuses.txt) meant divide PLL by four, which must be wrong.

Sorry if I'm just talking to myself, going crazy here...

Avery
andrewg



Joined: 17 Aug 2005
Posts: 316
Location: Perth, Western Australia

View user's profile Send private message Visit poster's website

PostPosted: Sat Jun 03, 2006 1:20 am     Reply with quote

Figure 2.1 "Clock diagram" in the datasheet gives a good overview for how the clocks are done.

Yes, CPUDIV divides differently depending on if you're using the PLL or not. All shown in the diagram.
_________________
Andrew
rberek



Joined: 10 Jan 2005
Posts: 207
Location: Ottawa, Canada

View user's profile Send private message

PostPosted: Sat Jun 03, 2006 5:47 am     Reply with quote

CCS only has 4 fuse settings, CPUDIV1-4. Therefore picking CPUDIV4 would probably selects configuration bits CPUDIV1 = 1 and CPUDIV0 = 1.

I'd then expect the fuse setting CPUDIV3 to select config bits CPUDIV1 =1 and CPUDIV0 = 0, which should give you what you want as you suspect already.
amcfall



Joined: 20 Oct 2005
Posts: 44

View user's profile Send private message

PostPosted: Sat Jun 03, 2006 9:05 am     Reply with quote

rberek wrote:
CCS only has 4 fuse settings, CPUDIV1-4. Therefore picking CPUDIV4 would probably selects configuration bits CPUDIV1 = 1 and CPUDIV0 = 1.

I'd then expect the fuse setting CPUDIV3 to select config bits CPUDIV1 =1 and CPUDIV0 = 0, which should give you what you want as you suspect already.


Yup, it looks like:

CPUDIV2 System Clock by 2

actually loads a value of 2 into the register... Not an actual divisor of 2. I feel stupid for spending so long on sucvh a simple problem. I was hung up on the description in fudses.tct where is says system clock by 2.

Thanks

Avery
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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