# PLL enabled HFINTOSC PIC18F

#### peter_morley

Joined Mar 12, 2011
179
I am calculating that I am only getting 16MHz signal because when I implement a 4 instruction loop I get a frequency on PORTA of about 1MHz. I know each instruction takes 4 cycles so 4*4*1Mhz comes out to 16MHz. Yeah I can do math! Well I am trying to enable the PLL bit so I can multiple that signal by 4, creating a 64MHz monster signal. I have enabled the PLL bit by this instruction bsf OSCTUNE,6. I am still not getting the 64MHz signal though.
Rich (BB code):
CONFIG FOSC = INTIO7, FCMEN = OFF, IESO = ON, PWRT = OFF, BOREN = OFF
CONFIG BORV = 18, WDTEN = OFF, WDTPS = 1, MCLRE = ON, HFOFST = ON
CONFIG LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC, STVREN = OFF
CONFIG LVP = OFF,  XINST = OFF, CP0 = OFF, CP1 = OFF, CP2 = OFF
CONFIG CP3 = OFF, CPB = OFF, CPD = OFF, WRT0 = OFF, WRT1 = OFF
CONFIG WRT2 = OFF, WRT3 = OFF, WRTB = OFF, WRTC = OFF, WRTD = OFF
CONFIG EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF
CONFIG EBTRB = OFF

START
movlw	0x09
movwf	PLCounter

movlw	0x06
movwf	ExtraCounter

movlb	B'00001111'
clrf 	PORTA
comf	PORTA
movlw 	0xE0 					; Configure I/O
movwf 	ANSEL 					; for digital inputs
movlw 	0xC0 					; Value used to
movwf 	TRISA 					; Set RA<5:0> as outputs

clrf	OSCCON
bsf		OSCCON,1
bsf		OSCCON,4
bsf		OSCCON,5
bsf		OSCCON,6
bsf		OSCTUNE,6

movwf	FSR0L,1
movwf	FSR0H,1
Freq
comf	PORTA
comf	PORTA
goto	Freq
END

#### CraigHB

Joined Aug 12, 2011
127
With the internal 8MHz RC oscillator without PLL, you'll get an instruction rate of 2MIPS. Since it takes 2 instruction cycles to oscillate a port pin, the highest frequency you could get out of a single port pin would be 1MHz, but also, it takes 2 instruction cycles for the program counter to jump. The output would not be perfectly square and the overall frequency would be lower.

If you enable PLL, you can increase instruction execution speed to 8MIPS, an increase by a factor of 4, but even so, ouptut is going to be impacted by anything else the code is doing. To generate a signal while doing other code tasks, you'd have to use an IRQ which would greatly reduce maximum frequency output. Typically, you'd use the PWM module or OCM module to avoid code execution dependancies, albeit at a lower frequency.

For an 18F, you can enable PLL with the following assembly instruction;

bsf OSCTUNE, PLLEN

Don't know if it matters, but keep in mind you'll increase MCU power consumption proportionally as you increase instruction speed.

I believe it's possible to output oscillator frequency on one of the pins through the FOSC config setting. In that case, you'd be able to get a higher code independant frequency output on one of the pins.

Not sure about the limit on the 18F series, I think some of the newer ones are higher, but you can get much higher instruction execution rates with the 24F series since the instruction clock for those is Fosc/2 instead of Fosc/4.

Last edited:

#### peter_morley

Joined Mar 12, 2011
179
Thanks Craig,

I already had the PLLEN bit set but its still not functioning properly. To oscillate PORTA i need actually 4 instruction cycles due to the goto command. So I actually have an internal frequency of 16MHz and each period takes 16 cycles = 4 instruction cycles. Do you know if my config words are set up correctly?

#### peter_morley

Joined Mar 12, 2011
179
With this code I have an oscillator frequency of 32MHz because I am getting porta oscillations of 2Mhz. I don't know how I got it from 16Hz to 32Hz but its making me mad that I can't do this knowing what I'm doing. blah help please!

Rich (BB code):
     CONFIG FOSC = INTIO7, IESO = OFF, FCMEN = OFF, PWRT = OFF, BOREN = OFF
CONFIG BORV = 18, WDTEN = OFF, WDTPS = 1, MCLRE = ON, HFOFST = ON
CONFIG LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC, STVREN = OFF
CONFIG LVP = OFF,  XINST = OFF, CP0 = OFF, CP1 = OFF, CP2 = OFF
CONFIG CP3 = OFF, CPB = OFF, CPD = OFF, WRT0 = OFF, WRT1 = OFF
CONFIG WRT2 = OFF, WRT3 = OFF, WRTB = OFF, WRTC = OFF, WRTD = OFF
CONFIG EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF
CONFIG EBTRB = OFF

;------------------------------------------------------------------------------
;
; VARIABLE DEFINITIONS
;
;------------------------------------------------------------------------------
CBLOCK 0x000 ; Sample GPR variable register allocations
PLCounter
ExtraCounter
ENDC

START
movlw	0x09
movwf	PLCounter

movlw	0x06
movwf	ExtraCounter

movlb	B'00001111'
clrf 	PORTA
comf	PORTA
movlw 	0xE0 					; Configure I/O
movwf 	ANSEL 					; for digital inputs
movlw 	0xC0 					; Value used to
movwf 	TRISA 					; Set RA<5:0> as outputs

movlw	0x70
movwf	OSCCON
movlw	0x40
movwf 	OSCTUNE

movwf	FSR0L,1
movwf	FSR0H,1
Freq
comf	PORTA
comf	PORTA
goto	Freq
END

#### CraigHB

Joined Aug 12, 2011
127
I would suggest using the MPLab SIM debugger. There's a stopwatch you can display. I use it a lot myself for code timing. It's identified as "StopWatch" in the Debugger drop down menu after you've selected the MPLab SIM debugger. Go to Debugger->Settings then select the Osc/Trace tap to set the clock speed. Then step through your program with the debugger to observe instruction timings. If I were to load your code and see what's happening, that is what I would do.

Hope that helps.

#### peter_morley

Joined Mar 12, 2011
179
Thanks again Craig.

I used the stop watch setting and everything is working as I expected. Still have a 32MHz signal. I have been looking on the internet and I see people have had similar problems. Can't find a good answer to my question.

#### peter_morley

Joined Mar 12, 2011
179
With this code I get a 16MHz clock...

Rich (BB code):
movlw	0x70
movwf	OSCCON
If I add this part I get 32MHz...

Rich (BB code):
bsf		OSCTUNE,6
So according to mathematics! I should be getting 4*16MHz = 64MHz...well I get 32MHz. The PLL bit should multiply the signal by 4...well its not.

#### nickelflipper

Joined Jun 2, 2010
280
With the config setting you should have internal clockout available on RA6. Can you measure that with an oscilloscope?, a DVM could load the output down too much.

An alternate method to check the clock is using the CCPx module and a PWM output. Here is some short code that accomplishes 16Mips (ie. 64Mhz clock) as shown with a 18f26k22 here. Notice how you can use ACCESS to move around in different memory banks, no need to use bsr values?

Also a good practice to write to the ports using the LATx registers, try that. Could be critical at very high clock rates.

#### peter_morley

Joined Mar 12, 2011
179
I just got it working by only changing one part of the config setting which is config FOSC = INTIO7. What a pain for something so small but at least I am getting somewhere. My problem now is changing the FSRL and FSRH registers. My FSRL register can be changed but I can't change the value in FSRH. One question I have is when FSRL gets to xFF does the carry roll over to FSRH when increasing FSRL by one. The 16 bit word would look like this after 0x0100?

Rich (BB code):
 	 CONFIG FOSC = INTIO7
;CONFIG FCMEN = OFF, IESO = OFF,PWRT = OFF, BOREN = OFF, BORV = 30
;CONFIG WDTEN = OFF, WDTPS = 32768,MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC,STVREN = ON, LVP = OFF
;CONFIG XINST = OFF,CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF,CPB = OFF, CPD = OFF
;CONFIG WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF,WRTB = OFF, WRTC = OFF, WRTD = OFF
;CONFIG EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF, EBTRB = OFF

#define		WHITE		B'00110111'
#define		BLACK		B'00110000'
#define		HLOW		B'00100000'
#define		VLOW		B'00000000'

RES_VECT  ORG     0x0000            ; processor reset vector
GOTO    START
;------------------------------------------------------------------------------
;
; VARIABLE DEFINITIONS
;
;------------------------------------------------------------------------------
CBLOCK 0x000 ; Sample GPR variable register allocations
PLCounter
ExtraCounter
ENDC

;------------------------------------------------------------------------------
; MAIN PROGRAM
;------------------------------------------------------------------------------

START
movlw	0x29
movwf	PLCounter

movlw	0x22
movwf	ExtraCounter

movlb	B'00001111'				; Bank Register Location
movlw	0x70					; load OSCCON value to make
movwf	OSCCON					; oscillator 16MHz
movlw	0x40					; enable PLL bit so
movwf	OSCTUNE					; oscillator is 4*16MHz = 64MHz!

clrf 	PORTA 					; initialize PORTA to 0
movlw 	0xE0 					; Configure I/O
movwf 	ANSEL 					; for digital inputs
movlw 	0xC0 					; Value used to
movwf 	TRISA 					; Set RA Pins 5,4,3,2,1 as outputs

movwf	FSR0L,1
movwf	FSR0H,1

#### MMcLaren

Joined Feb 14, 2010
853
One question I have is when FSRL gets to xFF does the carry roll over to FSRH when increasing FSRL by one?
Instead of incrementing FSR0L and FSR0H separately, use the POSTINC0 register (instead of INDF0) which will automatically increment the 16 bit FSR0 register pair...