News:

Let's find out together what makes a PIC Tick!

Main Menu

PIC18F45K22 64Mhz

Started by JackB, Oct 31, 2024, 03:27 AM

Previous topic - Next topic

JackB

Hello everyone,

I don't know if I'm at the right forum to ask about a clock issue for the 18F45K22.

The PIC is setup to run at 64Mhz with the internal clock and according to a scope trace smallest pulse duration

is around ~ 260ns, witch config line need to be change to get a pulse less than 100ns

if anyone can help me for this issue I'll really appreciate.

Thanks to all
Device = 18F45K22         
Declare Xtal = 64

Config_Start
  FOSC = INTIO67     ; Internal oscillator block
  PLLCFG = On        ; Oscillator multiplied by 4
  PRICLKEN = On      ; Primary clock is always enabled
  FCMEN = OFF        ; Fail-Safe Clock Monitor disabled
  IESO = OFF         ; Oscillator Switchover mode disabled
  PWRTEN = OFF       ; Power up timer disabled
  BOREN = SBORDIS    ; Brown-out Reset enabled in hardware only (SBOREN is disabled)
  BORV = 190         ; VBOR set to 1.90 V nominal
  WDTEN = On         ; WDT is always enabled. SWDTEN bit has no effect
  WDTPS = 32768      ; 1:32768
  CCP2MX = PORTC1    ; CCP2 input/output is multiplexed with RC1
  PBADEN = OFF       ; PORTB<5:0> pins are configured as digital I/O on Reset
  CCP3MX = PORTB5    ; P3A/CCP3 input/output is multiplexed with RB5
  HFOFST = On        ; HFINTOSC output and ready status are not delayed by the oscillator stable status
  T3CMX = PORTC0     ; T3CKI is on RC0
  P2BMX = PORTD2     ; P2B is on RD2
  MCLRE = INTMCLR    ; RE3 input pin enabled; MCLR disabled
  STVREN = On        ; Stack full/underflow will cause Reset
  LVP = OFF          ; Single-Supply ICSP disabled
  XINST = OFF        ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
  Debug = OFF        ; Disabled
  Cp0 = OFF          ; Block 0 (000800-001FFFh) not code-protected
  CP1 = OFF          ; Block 1 (002000-003FFFh) not code-protected
  CP2 = OFF          ; Block 2 (004000-005FFFh) not code-protected
  CP3 = OFF          ; Block 3 (006000-007FFFh) not code-protected
  CPB = OFF          ; Boot block (000000-0007FFh) not code-protected
  CPD = OFF          ; Data EEPROM not code-protected
  WRT0 = OFF         ; Block 0 (000800-001FFFh) not write-protected
  WRT1 = OFF         ; Block 1 (002000-003FFFh) not write-protected
  WRT2 = OFF         ; Block 2 (004000-005FFFh) not write-protected
  WRT3 = OFF         ; Block 3 (006000-007FFFh) not write-protected
  WRTC = OFF         ; Configuration registers (300000-3000FFh) not write-protected
  WRTB = OFF         ; Boot Block (000000-0007FFh) not write-protected
  WRTD = OFF         ; Data EEPROM not write-protected
  EBTR0 = OFF        ; Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
  EBTR1 = OFF        ; Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
  EBTR2 = OFF        ; Block 2 (004000-005FFFh) not protected from table reads executed in other blocks
  EBTR3 = OFF        ; Block 3 (006000-007FFFh) not protected from table reads executed in other blocks
  EBTRB = OFF        ; Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End

ANSELA = 0          ;disable by compiler use only for analog
;CMCON0 = 7         ;disable by compiler use only For analog

TRISA = %00001000
TRISB = %00000000
TRISC = %00000000
TRISD = %00000000
TRISE = %00000000
OSCCON = $70

Do
LATA.0 = 1
@ NOP
LATA.1 = 0
;@ NOP
LATA.1 = 1
@ NOP
LATA.0 = 0
DelayUS 1
Loop


Gamboa

JackB,

Running at 64MHz a PIC18 takes 62.5ns to execute an instruction. It doesn't have enough time.
You need to go to faster devices.

Regards,
Gamboa
Long live for you

Stephen Moss

First, @Gamboa is correct about the execution time, so that could be an issue.
Second, is the NOP instruction. If it has to be there then at best you pulse would be 125ns (62.5 for the NOP + 62.5 for LATA.0 = instructions), so if it will run without it remove it.
Third, I have not looked myself but you may want to look at the difference in the assembler code between using LATA.0 = and just LATA = as I have a vague memory that manipulating a single bit may result in more instructions that just writing to the entire port. 

RGV250

#3
Hi,
I am not sure why you have the @ as that seems to be for word/dwords.

I wonder if you could just use
Do
LATA.0 = ~LATA.0
Loop

Bob

top204

#4
With an 18F, 8-bit device running at its maximum frequency of 64MHz, the most you will achieve, as you found out, is a 260ns pulse. This is because the clock to instruction ratio on the 8-bit devices is 4:1, so the minimum pulse time is 62.5ns, and that is without the overheads of a branch back to it.

So even with the most efficient method of coding such as shown below:

    Symbol MyPin = LATB.0
    PinLow MyPin
    Do
       Btg MyPin
    Loop

The pulse rate is 2.66666MHz, and that is using the Btg mnemonic that toggles a pin directly.

And the assembler code produced by the compiler could not actually be made more efficient:

F1_000052 equ $ ; in [TEST_18F25K20.BAS] Do
_lbl__2
F1_000053 equ $ ; in [TEST_18F25K20.BAS] btg MyPin
    btg LATB,0
F1_000054 equ $ ; in [TEST_18F25K20.BAS] Loop
    bra _lbl__2

Even if the device is over-clocked to its maximum of 88MHz, the pulse will be 3.66MHz.

For very fast pulse lengths, you will need to switch to a dsPIC33 or fast PIC24 device because they operate a lot faster and have a clock to instruction ratio of only 2:1. The dsPIC33CK devices operate at, upto, 200MHz and are very simple to use with the Positron24 compiler.

Bob... The '@' character at the beginning of a line signifies an assembler mnemonic follows, but assembler mnemonics are all supported at the high level, so it is not usually needed unless some complex mnemonic parameter format is used.

JackB


I really appreciate all the help

Thank you

top204

#6
If it is a 10MHz waveform you require, you can use one of the newer 8-bit devices with an NCO (Numerically Controlled Oscillator) peripheral. These will easily reach in the mega Hertz and do not block the running of code, and operate in the background.

Below is a code listing for an 'untested' template to operate the NCO peripheral at 10MHz on a PIC18F05Q41 device, and the output will come from pin PORTC.0:

'
'  /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\    \/\\\                                                /\\\          /\\\
'  \/\\\\\\\\\\\/        /\\\\\    /\\\\\\\\\\    /\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'    \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\    \/\\\        \/\\\        /\\\\\\\\\\
'      \/\\\    \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\    \/\\\ /\\  /\\\/////\\\
'      \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\  \//\\\\\\\\/\\
'        \///        \///    \/////    \//////////    \//////////      \/////        \/////    \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Untested template of the NCO peripheral generating a 10MHz pulse waveform.
'
' Written by Les Johnson for the Positron8 BASIC compiler.
' https://sites.google.com/view/rosetta-tech/home
'
    Device = 18F05Q41                          ' Tell the compiler what device to compile for
    Declare Xtal = 64                          ' Tell the compiler what frequency the device is operating at (in MHz)

'------------------------------------------------------------------------
' The main program starts here
'
Main:
    PinOutput PORTC.0                          ' Make the NCO peripheral's pin an output
    RC0PPS = PPS_Fn_NCO1                       ' Pin PORTC.0 is the output for the NCO peripheral   
    NCO_Init()                                 ' Initialise and start the NCO peripheral

'------------------------------------------------------------------------
' Setup the NCO peripheral to operate at 10MHz
' Input    : None
' Output   : None
' Notes    : Requires the device to be operating at 64MHz
'
Proc NCO_Init()
    NCO1CON = %00000000                        ' NCO disabled. Polarity is active_hi. FDC mode
    NCO1CLK = %00100000                        ' Clock source is FOSC. 2_clk
    NCO1ACCU = $00
    NCO1ACCH = $00
    NCO1ACCL = $00
    NCO1INCU = $05
    NCO1INCH = $00
    NCO1INCL = $00
    NCO1CONbits_EN = 1                          ' Enable the NCO peripheral
EndProc

'------------------------------------------------------------------------
' Setup the config fuses for the internal oscillator running at 64MHz on a PIC18F05Q41 device
'
Config_Start
    FEXTOSC = Off                               ' External Oscillator not enabled
    RSTOSC = HFINTOSC_64MHZ                     ' HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1
    CLKOUTEN = Off                              ' CLKOUT function is disabled
    PR1WAY = Off                                ' PRLOCKED bit can be set and cleared repeatedly
    CSWEN = On                                  ' Writing to NOSC and NDIV is allowed
    FCMEN = On                                  ' Fail-Safe Clock Monitor enabled
    FCMENP = On                                 ' Fail-Safe Clock Monitor enabled. Timer will flag FSCMP bit and OSFIF interrupt on EXTOSC failure
    FCMENS = On                                 ' Fail-Safe Clock Monitor enabled. Timer will flag FSCMP bit and OSFIF interrupt on SOSC failure
    MCLRE = EXTMCLR                             ' RE3 pin function is MCLR
    PWRTS = PWRT_OFF                            ' Power-up timer disabled
    MVECEN = Off                                ' Interrupt contoller does not use vector table to prioritze interrupts
    IVT1WAY = On                                ' IVTLOCKED bit can be cleared and set only once
    LPBOREN = On                                ' Low-Power BOR enabled
    BOREN = On                                  ' Brown-out Reset enabled according to SBOREN
    BORV = VBOR_1P9                             ' Brown-out Reset Voltage (VBOR) set to 1.9V
    ZCD = Off                                   ' ZCD can be enabled by setting the ZCDSEN bit of ZCDCON
    PPS1WAY = Off                               ' PPSLOCKED bit can be set and cleared repeatedly (subject to the unlock sequence)
    STVREN = On                                 ' Stack full/underflow will cause Reset
    LVP = Off                                   ' HV on MCLR/VPP must be used for programming
    XINST = Off                                 ' Extended Instruction Set disabled
    WDTCPS = WDTCPS_17                          ' WDT Divider ratio 1:4194304
    WDTE = Off                                  ' WDT Disabled; SWDTEN is ignored
    WDTCWS = WDTCWS_7                           ' WDT window always open (100%)
    WDTCCS = SC                                 ' WDT input clock Software Control
    BBSIZE = BBSIZE_512                         ' Boot Block size is 512 words
    BBEN = Off                                  ' Boot block disabled
    SAFEN = Off                                 ' Storage Area disabled
    Debug = Off                                 ' Background Debugger disabled
    WRTB = Off                                  ' Boot Block not Write protected
    WRTC = Off                                  ' Configuration registers not Write protected
    WRTD = Off                                  ' Data EEPROM not Write protected
    WRTSAF = Off                                ' SAF not Write Protected
    WRTAPP = Off                                ' Application Block not write protected
    Cp = Off                                    ' PFM and Data EEPROM code protection disabled
Config_End

JackB

Hello,

Reading the Microchips datasheet I found out by using

the "OSCTUNE = $40" I can get low as ~65ns.

Is there more benefit by not using this line ?

Pic: Channel 1

I'm learning everyday.

Thank to all for your kind support.



Config_Start
  FOSC = INTIO67     ; Internal oscillator block
  PLLCFG = On        ; Oscillator multiplied by 4
  PRICLKEN = On      ; Primary clock is always enabled
Config_End

ANSELA = 0          ;disable by compiler use only for analog
;CMCON0 = 7         ;disable by compiler use only For analog

TRISA = %00001000
TRISB = %00000000
TRISC = %00000000
TRISD = %00000000
TRISE = %00000000
OSCCON = $70
OSCTUNE = $40
Do
LATA.0 = 1
@ NOP
LATA.1 = 0
@ NOP
LATA.1 = 1
@ NOP
LATA.0 = 0
DelayUS 1
Loop


John Lawton

When you said in your original post
QuoteThe PIC is setup to run at 64Mhz with the internal clock
in fact it was only running at 16MHz because you had not enabled the PLL. Now you have set OSCTUNE.6 = 1 that is now correct.

You are running the PIC at it's maximum speed using the internal oscillator. You may be able to get more loop speed by using an external clock, i.e. overclocking the device, or as been suggested omitting the @ NOP statements

John



JackB

Thanks john for your help,

As a hobby for me to learn about uC, I really appreciate all the help on this subject.
I assumed with the Declare Xtal = 64 statement took care of it.
But when adding the OSCTUNE line, then the clock was finally running at 64Mhz
My guess also is that bit 5~0 on the OSCTUNE serve as OSC fine tuning, for different chip manufacturer.


Device = 18F45K22         
Declare Xtal = 64

Config_Start
  FOSC = INTIO67     ; Internal oscillator block
  PLLCFG = On        ; Oscillator multiplied by 4
  PRICLKEN = On      ; Primary clock is always enabled

John Lawton

The Declare Xtal = 64 only tells the compiler what the oscillator is intended to be, it doesn't set any of the oscillator configuration settings, that is down to you.

John

JackB

Right on,

on Positron8 Compiler User Manual
Declare
Syntax
p-416
"Inform the compiler what frequency oscillator is being used on the microcontroller"