PLL enabled HFINTOSC PIC18F

Thread Starter

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.:D 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
		
		movlw	0x10					; start loading pixels at RAM location x10	
		movwf	FSR0L,1
		movlw	0x50					; start loading pixels at RAM location x10
		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:

Thread Starter

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?
 

Thread Starter

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!:mad:

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
		
		movlw	0x10					; start loading pixels at RAM location x10	
		movwf	FSR0L,1
		movlw	0x50					; start loading pixels at RAM location x10
		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.
 

Thread Starter

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.
 

Thread Starter

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.
 
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.
 

Thread Starter

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
	

		movlw	0x10					; start loading pixels at RAM location x10	
		movwf	FSR0L,1
	        movlw	0x50					; start loading pixels at RAM location x10
		movwf	FSR0H,1
 

MMcLaren

Joined Feb 14, 2010
842
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...
 
Top