View previous topic :: View next topic |
Author |
Message |
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
PLL, INTRC_IO on PIC16F1847 SOLVED |
Posted: Sat Sep 17, 2016 3:52 am |
|
|
Hi
Trying to work with internal oscillator and PLL on PIC16F1847
CCS PCM C Compiler, Version 5.062, xxxxx
MPLAB v8.92
CCS fuses for PLL:
Quote: | PLL_SW, 4X HW PLL disabled, 4X PLL enabled/disabled in software
PLL, 4X HW PLL enabled |
In the data sheet:
Quote: | The SPLLEN bit in the OSCCON register must be
set to enable the 4xPLL, or the PLLEN bit of the
Configuration Word 2 must be programmed to a ‘1’.
When using the PLLEN bit of the
Configuration Word 2, the 4xPLL cannot
be disabled by software and the 8 MHz
HFINTOSC option will no longer be
available. |
Using external clock the below fuses configuration makes PLL Enable in MPLB configure window: Code: | #FUSES ECH
//#FUSES PLL_SW
#FUSES NOIESO
//or
#FUSES ECH
#FUSES PLL
#FUSES NOIESO |
Using internal oscillator the below fuses makes PLL Disabled in MPLAB configure window: Code: | #FUSES INTRC_IO
#FUSES PLL
#FUSES NOIESO
#use delay(internal=32M)
#use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,stream=PORT1,errors) |
And in the LST file:
Code: | Configuration Fuses:
Word 1: 0FDC INTRC_IO WDT PUT MCLR NOPROTECT NOCPD BROWNOUT NOCLKOUT NOIESO NOFCMEN
Word 2: 1AFF NOWRT PLL_SW STVREN BORV25 NODEBUG NOLVP |
BUT using internal oscillator & fuses as above, including "PLL" the control LED blinks correct,
the serial communication works correct, pwm to an AC motor works correct. To my knowledge, I don't have any place I am enabling PLL in the software.
Best wishes
Joe
Last edited by gjs_rsdi on Sat Sep 17, 2016 6:03 pm; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Sat Sep 17, 2016 7:53 am |
|
|
I don't have that PIC so I can't say for certain....
Without seeing your program I can't tell, but the fuse PLL_SW is enabled...
The compiler may default to 'enable' based on the fuse being enabled ??
Jay |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Sat Sep 17, 2016 8:27 am |
|
|
Thanks for the answer Jay
The complete fuses:
Code: | #include <16F1847.h>
#device ADC=10
#FUSES WDT //Watch Dog Timer
#FUSES PUT //Power Up Timer
#FUSES MCLR //Master Clear pin enabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPD //No EE protection
#FUSES BROWNOUT //Reset when brownout detected
//#FUSES ECH //external clock
#FUSES INTRC_IO //internal oscillator
//#FUSES HS //crystal oscillator
#FUSES PLL
#FUSES NOCLKOUT //I/O function on OSC2for internal oscillator & external clock
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOWRT //Program memory not write protected
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES BORV25 //Brownout reset at 2.5V
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
//#use delay(clock=32M) //external clock or crystal oscillator
#use delay(internal=32M) //internal oscilator
#use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,stream=PORT1,errors) |
Main:
Code: | void main()
{
setup_wdt(WDT_128MS);//~128 ms reset
port_b_pullups(0xFF);
setup_adc_ports(sAN4);
setup_adc(ADC_CLOCK_DIV_32);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);//65.5 ms overflow
setup_timer_2(T2_DIV_BY_16,130,2);//262 us overflow, 524 us interrupt, 2000Hz
setup_ccp1(CCP_PWM);
set_pwm1_duty(zoomp);
setup_vref(VREF_ON);
enable_interrupts(INT_TIMER1);
disable_interrupts(INT_TBE);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(TRUE)
{
restart_wdt();
ADC();
FUNCTIONS();
}
} |
The fuses from LST:
Code: | Configuration Fuses:
Word 1: 0FDC INTRC_IO WDT PUT MCLR NOPROTECT NOCPD BROWNOUT NOCLKOUT NOIESO NOFCMEN
Word 2: 1AFF NOWRT PLL_SW STVREN BORV25 NODEBUG NOLVP |
Even in the fuses PLL is enabled, the configuration is PLL_SW.
I am sure the controller works at 32MHz, otherwise the led was not blinking correct, the communication to the PC will not work correct and the pwm will not work correct
That's strange!!!
EDITED:
The only way to enable PLL is to change to external:
Code: | //#use delay(internal=32MHz)
#use delay(clock=32MHz) |
In the CCS wizard if choosing internal, can't chose different CPU Clock Speed than Clock Speed. With Crystal or Clock can chose Clock speed 8MHz and CPU Clock Speed 32MHz and then it enables PLL
Best wishes
Joe |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Sep 17, 2016 10:35 am |
|
|
My testing shows this puts the PIC into 32 MHz internal osc PLL mode:
Code: | #include <16LF1847.h>
#fuses INTRC_IO, NOWDT
#use delay(internal=32MHZ) |
This puts it into 8 MHz internal oscillator mode:
Code: | #include <16LF1847.h>
#fuses INTRC_IO, NOWDT
#use delay(internal=8MHZ) |
The .LST file for the loop in the test program is shown below. This
produces a negative pulse on Pin B0 which is 125 ns long, and a high
time of 375 ns. This was observed with an oscilloscope.
Code: | .................... while(TRUE)
.................... {
.................... RB0 = 0; // Low for 125 ns
0012: BCF LATB.LATB0
.................... RB0 = 1;
0013: BSF LATB.LATB0
0014: GOTO 012
.................... }
|
We know that at 32 MHz the instruction clock is 8 MHz, so the instruction
cycle period is 125 ns. The BCF instruction sets RB0 low for one
instruction cycle, and we see a 125 ns negative pulse. Therefore we
are running at 32 MHz. There is no crystal attached to the PIC.
Therefore it's running on the internal oscillator.
Test program. Compiled with vs. 5.062. I couldn't find my 16F1847, so
I used an LF part.
Code: |
#include <16LF1847.h>
#fuses INTRC_IO, NOWDT
#use delay(internal=32MHZ)
#use fast_io(b)
#byte LATB = getenv("SFR:LATB")
#bit RB0 = LATB.0
//==========================
void main()
{
output_drive(PIN_B0);
RB0 = 0;
while(TRUE)
{
RB0 = 0; // Low for 125 ns
RB0 = 1;
}
} |
|
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Sat Sep 17, 2016 3:55 pm |
|
|
Thanks for the answer PCM programmer
I have an oscilloscope that can't test too high frequency and I have ready board so I wrote the test program below.
1. Led blinks every second
2. It outputs serial to a terminal on the PC and I enabled time stamp, get message every 2 seconds on internal oscillator
Also in my test program PLL works with internal oscillator:
Code: | #include <16F1847.h>
#device ADC=10
#FUSES PUT //Power Up Timer
#fuses INTRC_IO
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES BORV25 //Brownout reset at 2.5V
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
//#use delay(clock=32MHz,oscillator=8MHz)
#use delay(internal=32MHZ)
#use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,stream=PORT1,errors)
#define flashled PIN_A0
int ms50cnt=0;
int ms2000cnt=0;
int scomtxwords=0;
#INT_TIMER1
void TIMER1_isr(void)
{
set_timer1(15536);//65.5 ms overflow
ms50cnt++;
}
#INT_TBE
void TBE_isr(void)
{
switch(scomtxwords)
{
case 0:
{
putc(85);
scomtxwords++;
}
break;
case 1:
{
putc(170);
scomtxwords++;
}
break;
case 2:
{
putc(255);
scomtxwords=0;
disable_interrupts(INT_TBE);
}
}
}
void main()
{
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //65.5 ms overflow
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_TBE);
enable_interrupts(GLOBAL);
while(TRUE)
{
if(ms50cnt>=10)
{
output_toggle(flashled);
ms50cnt=0;
ms2000cnt++;
if(ms2000cnt>=4)
{
ms2000cnt=0;
enable_interrupts(INT_TBE);
}
}
}
}
|
But:
1. The configuration bytes shows PLL_SW with #use delay(internal=32MHZ) and PLL with #use delay(clock=32MHz,oscillator=8MHz)
Code: | Configuration Fuses:
Word 1: 0FC4 INTRC_IO NOWDT PUT MCLR NOPROTECT NOCPD BROWNOUT NOCLKOUT NOIESO NOFCMEN
Word 2: 1AFF NOWRT PLL_SW STVREN BORV25 NODEBUG NOLVP |
Code: | Configuration Fuses:
Word 1: 0FC7 ECH NOWDT PUT MCLR NOPROTECT NOCPD BROWNOUT NOCLKOUT NOIESO NOFCMEN
Word 2: 1BFF NOWRT PLL STVREN BORV25 NODEBUG NOLVP |
2. In MPLAB Configuration bits window 4x PLL Disabled with #use delay(internal=32MHZ)
3. In the CCS wizard can't enable the PLL on internal clock as I mentioned in my previous post
Can it be a compiler bug?
Best wishes
Joe |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Sep 17, 2016 4:04 pm |
|
|
I don't have the CCS IDE and therefore can't use the Wizard
and I don't have much interest in it. Just being truthful. |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Sat Sep 17, 2016 4:55 pm |
|
|
Thanks for the answer PCM programmer
Using the CCS IDE just for the wizard, more easy for me with a new controller (so many options and fuses) and to test certain things regarding what can/can't be done.
But as I wrote the Configuration fuses is PLL_SW but enabled (the frequency correct) and in MPLAB Configuration bits window 4x PLL Disabled with #use delay(internal=32MHZ) it is confusing
Best wishes
Joe |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Sat Sep 17, 2016 5:23 pm |
|
|
Made a test program for PIC18F26K22
With Code: | #use delay(internal=64MHZ) |
LED blinks OK, serial com OK
MPLAB Configuration bits written:
Quote: | Oscillator used directly |
But in LST:
Code: | Configuration Fuses:
Word 1: 2800 INTRC_IO NOPLLEN PRIMARY NOFCMEN NOIESO
Word 2: 3C06 PUT BROWNOUT BORV29 NOWDT WDT32768
Word 3: B500 CCP2C1 NOPBADEN CCP3B5 NOHFOFST TIMER3C0 CCP2B5 MCLR
Word 4: 0081 STVREN NOLVP NOXINST NODEBUG
Word 5: C00F NOPROTECT NOCPB NOCPD
Word 6: E00F NOWRT NOWRTC NOWRTB NOWRTD
Word 7: 400F NOEBTR NOEBTRB |
So also here like the PLL not used, but in the data sheet diagram can see clearly that to get 64MHz (32MHz in the case of 16F1847) the INTOSC go true 4xPLL
Best wishes
Joe |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Sep 17, 2016 5:40 pm |
|
|
There is more than one way to turn on the PLL. It can be done in
software. Not just the fuses.
Here's your test program:
Code: | #include <18F87K22.h>
#use delay(internal=64MHZ))
//======================================
void main(void)
{
while(TRUE);
} |
Look in the .LST file. It's setting up the PIC to use the 16 MHz and the
4x PLL, giving 64 MHz as Fosc:
Code: | ...... void main(void)
00004: CLRF TBLPTRU
00006: BCF RCON.IPEN
00008: MOVLW 70 // 111 = HF-INTOSC output freq. is used (16 MHz)
0000A: MOVWF OSCCON
0000C: MOVLW 40 // Set PLLEN bit = TRUE
0000E: MOVWF OSCTUNE
00010: CLRF OSCCON2 |
Look at the PIC data sheet to see the details of the OSCCON, OSCTUNE,
etc., registers. |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Sat Sep 17, 2016 6:02 pm |
|
|
Thanks PCM programmer
Everything clear now
Can see that also in the 16F1847 LST
Still will be nice to see that also in the software and the config bytes, less confusing (for me in any case)
Best wishes
Joe |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Sep 19, 2016 6:54 am |
|
|
The reason they use the software selection to enable it, is that they have to....
Read the paragraph before in the data sheet. The internal oscillator, after reset, is always set to the 500KHz mode. (5.2.2.5 in the data sheet). This speed doesn't feed to the PLL. So they have to reprogram the oscillator to get the 32Mhz selection. |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Mon Sep 19, 2016 10:29 pm |
|
|
I understand that Ttelmah, I read the data sheet and PCM programmer teach me where to check to see if PLL enabled or not.
I am just saying again:
Quote: | Still will be nice to see that also in the software and the config bytes, less confusing (for me in any case) |
Including in MPLAB and maybe some explanation in the CCS help file
Best wishes
Joe |
|
|
|