# PIC18F4520 failed using internal oscillator at 1MHz

I am wishing to use the internal oscillator of the pic18f4520 at a frequency of 1Mhz , what I wish to achieve in the end is to use to control a servo.

#include p18cxxx.h
#include pwm.h
#include timers.h

#pragma config OSC = INTIO1
#pragma config MCLRE = ON           /* Set Master Clear */
#pragma config WDT = OFF            /* set watchdog timer off */
#pragma config LVP = OFF            /* Low Voltage Programming Off */
#pragma config DEBUG = OFF          /* Compile without extra Debug compile Code */
#pragma config PBADEN = OFF         /* Disable Analogue on PORTB */

void main() {
OSCCON = 0x42;
TRISC = 0X00;
PR2=152;  // period
T2CON = 0x06;  //prescale to 16
while(BusyADC( )); /* wait for completion */
CCP1CONbits.CCP1M = 0x0C;    //make the pin an output
CCP1CONbits.DC1B=0;
}


When I use an external oscillator, the pwm works fine but I can't get a 50Hz signal with a 20Mhz external oscillator, I want to use the PWM without the external oscillator just because it seems like a sweet trick to know.

I am very new to micro controllers and I apologize if I don't follow any protocols to explaining my problem but to repeat, the issue is setting up the internal oscillator to 1MHz, I read the data sheet and assigned OSSCON register the necessary value and to turn on the internal oscillator and to set it to 1MHZ.

The code doesn't compile and seems to be a bit iffy about me configuring the OSC to INTIO1 even though thats what the data sheet says to do when desiring to use the microcontroller's internal oscillator capabilities.

The program is in c18 compiler

For some reason the site blanks out words with "< > " and capitalizes anything in front of the "#" sign so please assume that everything is correct except in the include and pragma's except the pragma config OSC=INTIO1 which as mentioned did not allow successfull build.

• Wow "MHz" (correct), "MHZ" and "Mhz" all in one question. I'm no expert on micros but attention to detail is important I'm sure. I'm also sure someone will help you but not pedantic me!! – Andy aka May 17 '15 at 19:03
• please paste the compiler error – Vladimir Cravero May 17 '15 at 19:14
• The first thing I notice is that you don't have a main loop, your code just drops through the main function. That's always going to give strange results. – Roger Rowland May 17 '15 at 19:15
• I've added an answer because my comments were too long for comments. I will update this if you can show us the compiler error like Vladimir suggested. – David May 17 '15 at 20:13
• Hi , Andy Aka I am sorry about my MHZ ,Mhz and MHZ incorrectness, – Rashiid Sherif May 17 '15 at 21:30

A few observations. I'm using this datasheet as a reference.

### Oscillator selection

Your problem appears to be a conflict between the datasheet and the compiler documentation. Here we see the list of possible oscillator types (datasheet page 23):

However according to the PIC18 Configuration Settings Addendum the options are named differently in the C18 tool suite (page 131):

Setting OSC to INTIO7 will give an output of FOSC/4 (the instruction clock) on the OSC2 pin (RA6). This might not be desirable, for a fully internal clock you might want INTIO67 instead.

### Oscillator setup

You don't actually need to change OSCCON during initialisation if you want a 1Mhz output because that's the default. You can see this in the datasheet (page 30):

bit 6-4 IRCF2:IRCF0: Internal Oscillator Frequency Select bits

• 100 = 1 MHz(3)

3 - Default output frequency of INTOSC on Reset.

Additionally you should wait for the internal oscillator to be stable before continuing. You can do this by monitoring the IOFS bit of OSCCON. I'm not sure how C18 presents this register, but something like the following would work:

// Wait for the internal oscillator to be stable
while(!(OSCCON & 0b100));


Note you can also use either of these which are exactly equivalent. All are likely to compile to the same bit-test instruction (e.g. btfss):

while(OSCCONbits.IOFS == 0);
while(!OSCCONbits.IOFS);


### Lack of main loop

You have no main loop, as observed by Roger in the comments. Generally you would do your work in a look like:

void main() {
// Setup ports and internal features

// Main program
while(1) {
// Do your work here, which repeats forever
}

// Execution will never reach here
}


### Include syntax

PIC18F4520\pwm.c:1:Error [1026] malformed #include directive


This is because you need angle brackets around the #include directives, like so:

#include <p18cxxx.h>


Take a look at this Stackoverflow question for a thorough explanation on why.

• This is a neater way to check the IOFS bit: while (OSCCONbits.IOFS == 0) ; – Leon Heller May 17 '15 at 21:03
• Cheers, I wasn't sure how that worked in C18 but that's how I do it in XC8. Even neater is !OSCCONbits.IOFS :) – David May 17 '15 at 21:06
• Hi , where would I want to check for this bit? before my while(1) loop so as it only goes into the main loop once the oscillator has stabilized? – Rashiid Sherif May 17 '15 at 21:43
• Yes, that would be a good place. After you make any changes to the oscillator configuration or on startup / wake from sleep. – David May 17 '15 at 21:44
• Also , I have no idea how to configure my oscillator, C:\Users\Rashiid\Desktop\PWM TEST PIC18F4520\pwm.c:6:Error [1225] configuration value 'INTIO1' not recognized for configuration setting 'OSC' This is the error response to me trying to use INTIO2 #pragma config OSC = INTIO2 – Rashiid Sherif May 17 '15 at 21:46