|
|
View previous topic :: View next topic |
Author |
Message |
Simões Guest
|
PIC18F2620 Oscillator configuration |
Posted: Wed Jun 10, 2009 11:46 am |
|
|
This is my first post here.
I have read thousands of posts about setting oscillators and still have a problem.
Currently, I use the most basic program possible to eliminate possible errors.
I am using a PIC18F2620, configured with internal oscillator.
The hardware has no problem and everything is working.
The problems arose when I realized that the microcontroller was running out of time to run some interruptions.
I see the settings of the oscillator and not discovered the error.
This is the basic code created.
main.h
Code: |
#include <18F2620.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
//#FUSES INTRC_IO //Internal RC Osc
//#FUSES LP
#FUSES INTRC
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOIESO //Internal External Switch Over mode DISabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV21 //Brownout reset at 2.1V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES NOLPT1OSC //Timer1 NOT configured for low-power operation
#FUSES NOMCLR //Master Clear pin used for I/O
#BYTE OSCTUNE = 0xF9B
#BYTE OSCCON = 0xFD3
#BYTE CONFIG1H = 0X300001
#use delay(clock=32000000)
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
|
main.c
Code: |
#include "main.h"
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_oscillator(OSC_8MHZ|OSC_NORMAL|OSC_PLL_ON);
// setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_PLL_ON);
// CONFIG1H=0X08;
// OSCTUNE=0XC0;
// OSCCON=0X70;
delay_ms(100);
printf("start\n\r");
printf("OSCTUNE = %X\n\rOSCCON = %X\n\rCONFIG1H = %X\n\r", OSCTUNE, OSCCON, CONFIG1H );
// TODO: USER CODE!!
while(1)
{
output_toggle(PIN_B1);
}
}
|
In this example, the instruction output_toggle (PIN_B1) is to generate a square wave with a frequency of 1Mhz.
For the serial port to receive data, I need to define "delay" to a frequency of 32 MHz
The results of printf are:
OSCTUNE = 40
OSCCON = 7C
CONFIG1H = 00
If I choose the other clock setting
(OSC_8MHZ | OSC_INTRC | OSC_PLL_ON)
I get a square wave with frequency of 250 kHz. The result of the printf keeps the same.
But should not be the correct configuration to select the internal oscillator? Should not have a different value in printf?
The last attempt was to force the values of individual records.
One of the records that will never change it was the CONFIG1H. It seems that the micro is always set to LP.
In short, I do not know the actual frequency that the microcontroller is working. More than that, if it really is working to 32Mhz, it should not have a wave output with a higher frequency? output_toogle takes 16 clock cycles to execute?
All help is welcome. Need to put this microcontroller to work to its maximum frequency to perform all the code in time.
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 10, 2009 11:58 am |
|
|
That's not a simple test program. See my post in this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=38761
Also, you should not test the speed of a loop, without a delay statement
in it. Unless you look at the .LST file and count the instruction cycles,
you will have no way to know the correct speed. Again, look at my
test program in the link above. |
|
|
simoes
Joined: 10 Jun 2009 Posts: 7 Location: Cuernavaca, México
|
|
Posted: Wed Jun 10, 2009 12:44 pm |
|
|
Ok, you are right.
Tried the program that you recommend and only added "# fuses NOMCLR".
The truth is that the output waveform has the correct frequency.
Can I assume that is working to 32Mhz?
Again, I deleted the delay_ms() routine and now I have a waveform with a 1.335MHz frequency.
The .lst show me this:
Code: |
.................... while(1)
.................... {
.................... output_high(PIN_B1);
00028: BCF F93.1
0002A: BSF F8A.1
.................... output_low(PIN_B1);
0002C: BCF F93.1
0002E: BCF F8A.1
.................... }
00030: BRA 0028
....................
.................... }
|
If I do 1.335 * 5 = 6.7 Mhz
I also try this:
Code: |
#include <18F2620.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#FUSES NOMCLR //Master Clear pin used for I/O
#use delay(clock=8000000)
//====================================
void main()
{
setup_oscillator(OSC_8MHZ | OSC_PLL_ON);
while(1)
{
output_high(PIN_B1);
output_low(PIN_B1);
}
}
|
And is the same result.
Suppose that the maximum frequency should be 8Mhz . . .
Do not think I'm obsessed with the value of the frequency, but there must be a way to show its true value.
I want to understand how to configure the various modes of oscillator.
And it seems not very well explained in the datasheet.
Thanks for the quick reply. _________________ Faculdade de Engenharia da Universidade do Porto.
Instituto Tecnológico y de Estudios Superiores de Monterrey.
Visita-me em: asimoes.myweblive.net |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 10, 2009 1:34 pm |
|
|
Apparently you want to measure the internal oscillator frequency.
Here's how to do it:
Change the fuse from INTRC_IO to INTRC. This will allow the "Clock Out"
signal to go out on the CLKO pin of the PIC. Use this program:
Code: |
#include <18F2620.H>
#fuses INTRC, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=32000000)
//===============================
void main()
{
while(1);
}
|
Look at the OSC2/CLKO pin with an oscilloscope. You should see 8 MHz.
The signal will be 1/4 of the internal oscillator frequency. 32 / 4 = 8. |
|
|
simoes
Joined: 10 Jun 2009 Posts: 7 Location: Cuernavaca, México
|
|
Posted: Wed Jun 10, 2009 2:15 pm |
|
|
Ok I have a wave of 8Mhz in the output.
Yes, I can conclude that I am working to 32MHz.
Thanks for the help.
I think my problem was the choice of "OSC_INTRC" or "OSC_NORMAL".
In this case, we don't put anything, what is the "default" value used?
One more time, thanks for help. _________________ Faculdade de Engenharia da Universidade do Porto.
Instituto Tecnológico y de Estudios Superiores de Monterrey.
Visita-me em: asimoes.myweblive.net |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 10, 2009 2:26 pm |
|
|
If you have a modern version of the compiler, and if everything is
working correctly with it, then you don't even need a setup_oscillator()
statement. The compiler will look at your fuses and the #use delay()
frequency and it will set up everything correctly.
Regarding the setup_oscillator() settings:
The OSC_INTRC setting will force the PIC to use the Internal Oscillator.
If you use OSC_NORMAL, the PIC will use the oscillator that is specified
in your #fuses statement. So if your #fuses are set to INTRC or
INTRC_IO, and you use OSC_NORMAL, the PIC will use the internal
oscillator. If your #fuses are set to HS, the PIC will use that setting.
My philosophy is to do as little as possible. If the compiler sets the
oscillator correctly by reading the #fuses and #use delay() statement,
then let the compiler do it. Don't add a setup_oscillator() statement
when it's not necessary. |
|
|
simoes
Joined: 10 Jun 2009 Posts: 7 Location: Cuernavaca, México
|
|
Posted: Wed Jun 10, 2009 2:39 pm |
|
|
Got it.
I thought that the fuses are not enough.
I thought that the records OSCCON, OSCTUNE and CONFIG1H were written with the instruction setup_oscillator (...).
Doubt resolved!
Ps: sorry my bad english :( _________________ Faculdade de Engenharia da Universidade do Porto.
Instituto Tecnológico y de Estudios Superiores de Monterrey.
Visita-me em: asimoes.myweblive.net |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|