Configuring PIC Microcontroller for 16 MHz Internal Oscillator Operation

Thread Starter

MTech1

Joined Feb 15, 2023
161
I'm currently going through the datasheet of the PIC18F45K22. I would like my microcontroller to run at a speed of 16 MHz using the internal oscillator, as I don't have an external crystal oscillator. I am using MPLAB IDE.

However, I'm a bit confused about whether I should be configuring the configuration registers or the oscillator registers to achieve this.

Could you please provide help on which registers I need to configure to ensure that the microcontroller operates at a speed of 16 MHz using the internal oscillator?

Edit : I have edited clock frequency in a post . before I asked for 20 MHz and now I am asking for 16 MHz
 
Last edited:

BobTPH

Joined Jun 5, 2013
8,664
You can't. The internal oscillator is 16 MHz, with a divider to get 8, 4, 2, 1 or 0.5 MHz. Then it can be multiplied by 4 with a PLL, giving you 64, 32, 16, 8, 4, and 2 MHz. There is no way to get 20 MHz without using a crystal or external oscillator.
 

Thread Starter

MTech1

Joined Feb 15, 2023
161
You can't. The internal oscillator is 16 MHz, with a divider to get 8, 4, 2, 1 or 0.5 MHz. Then it can be multiplied by 4 with a PLL, giving you 64, 32, 16, 8, 4, and 2 MHz. There is no way to get 20 MHz without using a crystal or external oscillator.
I'm looking to configure my PIC microcontroller to run at a clock speed of 16 MHz using the internal oscillator. Could you please provide the settings ( configuration bits or oscillator register or both two )I need to adjust to achieve this?

Thank you
 

BobTPH

Joined Jun 5, 2013
8,664
The default configuration should select the internal oscillator. Just set the divider to 1 to get 16MHz.

I am not going to go through and tell you the exact settings, you need to learn how to read the datasheet and determine them yourself.

If you don’t understand something, I will be happy to answer your questions.
 

Thread Starter

MTech1

Joined Feb 15, 2023
161
If you don’t understand something, I will be happy to answer your questions.
I'm currently facing some confusion regarding the register settings for achieving a 16 MHz clock speed. Specifically, I'm looking at the 'IRCF<2:0>' bits (bit 6-4) in the 'CONFIG1H' register, which control the Internal RC Oscillator Frequency Select.

According to the information I found, setting these bits to '111' important for frequency of 16 MHz. However, I'm uncertain about other related settings such as 'IESO,' 'FCMEN,' 'PRICLKEN,' and 'PLLCFG' in the same 'CONFIG1H' register, as well as 'FOSC<3:0>'.
 

hexreader

Joined Apr 16, 2011
581
This simple test code works for me:

Code:
// simple pin - test program for PIC18F45K22 with 16MHz internal oscillator

// PIC18F45K22 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1H
#pragma config FOSC = INTIO7    // Oscillator Selection bits (Internal oscillator block, CLKOUT function on OSC2)
#pragma config PLLCFG = OFF     // 4X PLL Enable (Oscillator used directly)
#pragma config PRICLKEN = OFF   // Primary clock enable bit (Primary clock can be disabled by software)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRTEN = OFF     // Power-up Timer Enable bit (Power up timer disabled)
#pragma config BOREN = SBORDIS  // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 190       // Brown Out Reset Voltage bits (VBOR set to 1.90 V nominal)

// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config CCP2MX = PORTC1  // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<5:0> pins are configured as digital I/O on Reset)
#pragma config CCP3MX = PORTB5  // P3A/CCP3 Mux bit (P3A/CCP3 input/output is multiplexed with RB5)
#pragma config HFOFST = ON      // HFINTOSC Fast Start-up (HFINTOSC output and ready status are not delayed by the oscillator stable status)
#pragma config T3CMX = PORTC0   // Timer3 Clock input mux bit (T3CKI is on RC0)
#pragma config P2BMX = PORTD2   // ECCP2 B output mux bit (P2B is on RD2)
#pragma config MCLRE = EXTMCLR  // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON         // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled if MCLRE is also 1)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection Block 0 (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF        // Code Protection Block 1 (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF        // Code Protection Block 2 (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF        // Code Protection Block 3 (Block 3 (006000-007FFFh) not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF       // Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF       // Write Protection Block 2 (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF       // Write Protection Block 3 (Block 3 (006000-007FFFh) not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection Block 2 (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection Block 3 (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)

#define _XTAL_FREQ 16000000

#include <xc.h>

void main(void){

    OSCCON = 0x72;                  // internal oscillator 16MHz

    ANSELA = 0;                     // PORT A Digital
    LATA = 0;                       // all low
    TRISA = 0;                      // all outputs
    ANSELB = 0;
    LATB = 0;
    TRISB = 0;
    ANSELC = 0;
    LATC = 0;
    TRISC = 0;
    ANSELD = 0;
    LATD = 0;
    TRISD = 0;
    ANSELE = 0;
    LATE = 0;
    TRISE = 0;

   
    while(1){
        LATA = 0x55;
        LATB = 0x55;
        LATC = 0x55;
        LATD = 0x55;
        LATE = 0x55;
        __delay_ms(500);
        LATA = 0xAA;
        LATB = 0xAA;
        LATC = 0xAA;
        LATD = 0xAA;
        LATE = 0xAA;
        __delay_ms(500);
    }
}
 
Last edited:

liaifat85

Joined Sep 12, 2023
48
I'm currently going through the datasheet of the PIC18F45K22. I would like my microcontroller to run at a speed of 16 MHz using the internal oscillator, as I don't have an external crystal oscillator. I am using MPLAB IDE.

However, I'm a bit confused about whether I should be configuring the configuration registers or the oscillator registers to achieve this.

Could you please provide help on which registers I need to configure to ensure that the microcontroller operates at a speed of 16 MHz using the internal oscillator?

Edit : I have edited clock frequency in a post . before I asked for 20 MHz and now I am asking for 16 MHz
In miKro C it is quite simple. You can configure the microcontroller's speed just by going to the 'project settings'.
 

BobTPH

Joined Jun 5, 2013
8,664
I'm currently facing some confusion regarding the register settings for achieving a 16 MHz clock speed. Specifically, I'm looking at the 'IRCF<2:0>' bits (bit 6-4) in the 'CONFIG1H' register, which control the Internal RC Oscillator Frequency Select.

According to the information I found, setting these bits to '111' important for frequency of 16 MHz. However, I'm uncertain about other related settings such as 'IESO,' 'FCMEN,' 'PRICLKEN,' and 'PLLCFG' in the same 'CONFIG1H' register, as well as 'FOSC<3:0>'.
Where did you find that information? Perhaps you should look in the datasheet for the PIC18F45K22. This is the configuration word for the clock. The clock selection filed is called FOSC and is 4 bits, at the low end of the byte, bits 3:0. The correct setting of FOSC is 1000 to use the internal oscillator.

PIC18F45k22 datasheet

Look at section 24.2. I tried to cut and paste here, but it does not handle it well.


Anyway, just use what @hexreader gave you.
 

Thread Starter

MTech1

Joined Feb 15, 2023
161
This simple test code works for me:
#pragma config FOSC = INTIO7
I'm particularly interested in understanding line number 8 of the code. you are assigning 'INTIO7,' but I'm unsure where this idea is coming from in the datasheet . I had initially thought that configuring the 'CONFIG1H' register settings was sufficient to achieve a 16 MHz clock speed. Could you please clarify the role of 'INTIO7' and whether it's necessary to set both the 'CONFIG' register and 'OSCCON' register for a 16 MHz clock?
 

BobTPH

Joined Jun 5, 2013
8,664
I'm particularly interested in understanding line number 8 of the code. you are assigning 'INTIO7,' but I'm unsure where this idea is coming from in the datasheet . I had initially thought that configuring the 'CONFIG1H' register settings was sufficient to achieve a 16 MHz clock speed. Could you please clarify the role of 'INTIO7' and whether it's necessary to set both the 'CONFIG' register and 'OSCCON' register for a 16 MHz clock?
It is not in the datasheet. You would have to look in the header file for pic18f45ka22.
You are right. This is quite confusing.

I think it is software malpractice to have the chip default to external oscillator as it does. This means no one gets the chip to run on their first try, unless they are using a working example. And what you have to know to do what @hexreader did is not trivial.
 

hexreader

Joined Apr 16, 2011
581
#pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal oscillator block)
This setting allows both OSC pins RA6 and RA7 to be used as general purpose IO

#pragma config FOSC = INTIO7 // Oscillator Selection bits (Internal oscillator block, CLKOUT function on OSC2)
This setting puts out Fosc/4 (4MHz in this case) to RA6 pin. Handy for checking internal oscillator accuracy with a frequency counter

For an easy way to select Config bits:
From MPLAB X IDE select
- Production
- Set Configuration Bits
Choose you options
Click Generate source Code to Output button
Copy and paste the resulting text
 
Last edited:

Thread Starter

MTech1

Joined Feb 15, 2023
161
You are right. This is quite confusing.
MPLABX for 16MHz Osc out (64MHz system clock) on the K22 series (46K22 here)
View attachment 306980
View attachment 306984
View attachment 306981
View attachment 306982
It is rather confusing because of the many options.
nice work spook
I noticed that you are using the MCC feature of MPLAB to configure your system. I see various configuration settings in my interface. What are option needs to select for 16 Mhz

1699439929576.png

1699439999917.png


I also observed that you are using a DSO to check if your microcontroller is operating at the correct speed by connecting a probe. Could you please explain how you perform this test and where you are connecting the probe?
 

Thread Starter

MTech1

Joined Feb 15, 2023
161
#pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal oscillator block)
This setting allows both OSC pins RA6 and RA7 to be used as general purpose IO
Can you please explain how the #pragma directive works and How it actually work in code you posted ? I think it should be perform in pre-processing stage
 

nsaspook

Joined Aug 27, 2009
12,796
nice work spook
I noticed that you are using the MCC feature of MPLAB to configure your system. I see various configuration settings in my interface. What are option needs to select for 16 Mhz

View attachment 307023

View attachment 307024


I also observed that you are using a DSO to check if your microcontroller is operating at the correct speed by connecting a probe. Could you please explain how you perform this test and where you are connecting the probe?
Look at my screenshot for 16MHz menu selections. The scope prone is on the osc output pin that's a menu option on my screenshot.

Read the mcc and osc configuration info for your chip.
 

hexreader

Joined Apr 16, 2011
581
Can you please explain how the #pragma directive works and How it actually work in code you posted ? I think it should be perform in pre-processing stage
I am just an amateur coder, so my understanding is poor. I simply copy what others have done over the years and read the appropriate datasheet(s) carefully

Check out MPLAB® XC8 C Compiler User’s Guide DS50002053G section 2.5.14
If you want to know more - I am probably the wrong person to ask
 

Thread Starter

MTech1

Joined Feb 15, 2023
161
Look at my screenshot for 16MHz menu selections. The scope prone is on the osc output pin that's a menu option on my screenshot.
I've noticed that one of the probes is connected to the oscillator output pin, but I'm not sure about the other one's connection. My guess is that it might be connected to the ground on the board. Could you confirm the setup?
 
Top