PDA

View Full Version : Osctune



Charles Linquis
- 2nd April 2010, 06:12
I can't seem to find any reference as to the range of the OSCTUNE register. That is, if I vary the value from 01111 to 10000, approximately how far does the frequency shift?

My goal is to find the frequency error of a chip, calculate the correct OSCTUNE value in one step and write the new value.

I realize that it won't be perfect. Close is good enough. I can try it myself tomorrow, but does anyone know the answer?

Charles Linquis
- 2nd April 2010, 15:22
Now that I have had a chance to test it in the lab, I have an answer:

First, I used an 18F8723 with

OSCCON = $62 ; 4Mhz, INT osc.
OSCTUNE.6 = 0 ; PLL disabled

Adjusting OSCTUNE[4:0] from %01111 to %10000 changed the
frequency from 4.507 Mhz to 3.440 Mhz.

The change was nearly linear. With each count giving about .8% frequency change.

Acetronics2
- 2nd April 2010, 17:58
Hi, Charles



4.5.2 OSCTUNE REGISTER
The internal oscillator’s output has been calibrated at the
factory but can be adjusted in the application. This is
done by writing to the OSCTUNE register (Register 4-1).
The tuning sensitivity is constant throughout the tuning
range. The OSCTUNE register has a tuning range of
±12.5%.


from the 16F88 Datasheet ...

Alain

Heckler
- 2nd April 2010, 17:59
Hey Charles,
Nice work answering your own question;)

Would you please explain how you tested the osc freq? Could you share your test code?

I would like to learn more about this.

I usually base my projects around the following 3 PIC's, as they share the same basic pinout...
8pin - 12F683
14pin - 16F688
20pin - 16F690

I would like to learn how to set/test the osctune register. I would also like to know how to read a new chip to view the osctune register as set from the factory.

Thanks
Dwight

rmteo
- 2nd April 2010, 18:08
These parameters vary from device to device - eg. while the 8723 has 5 frequency tuning bits, others (such as a 46K20) have 6 bits.

Charles Linquis
- 3rd April 2010, 03:11
Alain, I guess some datasheets have more information than others. I haven't used any 16F parts for years, so I never considered looking there.

Heckler, I used a frequency counter connected to CLKOUT.



You can write to OSCTUNE at any time.

In my case, I needed all devices to run very close to 4Mhz, so -

After programming, the first thing the PIC (in my case, an 18F2221) looks for is for a pin to go low (the pin is connected to a pushbutton). A LED connected to another pin is flashed in a particular pattern. This indicates it is in the CALIBRATION mode.

Another PIC (actually an 18F8722 development board used as a "calibrator") is connected to another pin on the 18F2221. The "calibrator" board sends out a precise 30ms low (using pulsout), followed by a 1 second high, followed by another 30ms low followed by a 1 second high....

The '2221 looks for the 30ms low and times it, (using pulsin). If the pulse appears shorter or longer than 30ms to the '2221, it divides the difference by 24 and increments or decrements a variable and writes that variable both to the the OSCTUNE register and to EEPROM. The LED is flashed in a pattern that indicates calibration was successful. Another EEPROM cell is written with $AA to indicate the calibration process was successful. This cell is checked on power up. If it is $AA the entire calibration process is bypassed.

On power up, the calibration value in the EEPROM is read and loaded into OSCTUNE.

I have found very few '2221s that were more than 1% off. They are remarkably temperature-stable as well.



On power up, the EEPROM

Acetronics2
- 3rd April 2010, 09:27
Would you please explain how you tested the osc freq? Could you share your test code?

I would like to learn more about this.

I usually base my projects around the following 3 PIC's, as they share the same basic pinout...
8pin - 12F683
14pin - 16F688
20pin - 16F690

I would like to learn how to set/test the osctune register. I would also like to know how to read a new chip to view the osctune register as set from the factory.

Thanks
Dwight

Hi, Dwight

I do not think you can tune OSCTUNE without a good time reference in one hand ...

What I do here is use my R/C set ... transmitter neutral is a precise 1500µs positive pulse ... and I also built a precise pulse meter ...

so, I just use the PULSOUT command to output a 1500µs pulse and trim OSCTUNE to get the good value on the meter.
Ok, I should write a small program and a board to make it automatically ( need 1 ref signal Pic, a thermostated enclosure ...etc,etc )... hoping I won't erase the EEPROM on the " live " programming !!!

Alain

PS: When leavin factory ... osctune is ... ZERO !!! ( see registers default values in the datasheet ... )

rsocor01
- 3rd April 2010, 10:19
Charles,

The next link might also be helpful for what you are doing. I thought about doing this oscillator calibration procedure for one of my projects, but since the chips come calibrated from the factory I gave up on the idea. Also, I didn't need that much accuracy.

http://melabs.com/resources/articles/osccal.htm

Robert

Charles Linquis
- 3rd April 2010, 17:26
The oscillators are close when they come from the factory, but I need 100% reliable communication at 19.2K baud, over the temperature range of -45 to 100C when running from a 4Mhz internal oscillator, and the supply voltage varying between 4.7 and 5.1V.

Now you see why I'm interested in frequency stability and calibration!

Amazingly, the 18F2221's (without calibration) are *usually* good enough to get this done.

rmteo
- 3rd April 2010, 17:42
The oscillators are close when they come from the factory, but I need 100% reliable communication at 19.2K baud, over the temperature range of -45 to 100C when running from a 4Mhz internal oscillator, and the supply voltage varying between 4.7 and 5.1V.
Why not use the AUTO-BAUD RATE DETECT feature - no calibration needed and automatic compensation for temperature/voltage variations? Also works with other oscillator modes (XT, HS, EC) besides IntOSC and high baud rates - I use it with speeds up to 230,400 baud.

Charles Linquis
- 3rd April 2010, 17:47
I see what you mean. I have never used that feature before. Time to try it!

languer
- 3rd April 2010, 17:49
So what you were looking for was not really to calibrate it, but to reduce the inherent error that occurs when using a close-enough (but not exact source) for the BAUD generator. This makes more sense (since the Oscillators are trimmed at the factory for 8MHz, before they leave the factory).

Note that 4MHz gives you 0.16% error on the 19,200 BAUD generator. On the other hand, 3.9936MHz is right on. So maybe this was the answer you were looking for through experimentation.

rmteo
- 3rd April 2010, 18:00
I see what you mean. I have never used that feature before. Time to try it!
Another neat thing about this feature is that you do not have to set a fixed baud rate in your firmware. I have used it (with IntOSC) to communicate at any standard speed from 2,400 to 230,400 baud. Auto-Baud detect is only available on devices that have an EUSART - most PIC18s (and some PIC16s) do.

Charles Linquis
- 3rd April 2010, 18:24
I'm assuming it will pick "odd" baud rates (like 18200 buad, which can result from off-frequency oscillator). I would need that.

And I always use the "better" chips. I figure that trying to save $2.00 by using a 16F rather than an 18F chip, and then spending a week overcoming its weaknesses is false economy.

rmteo
- 3rd April 2010, 19:02
The nice thing is that it doesn't matter if your PIC18 is off frequency or the sending device is off frequency - it just syncs both units to each other.

Charles Linquis
- 3rd April 2010, 19:48
In my case, I'll have to read the resultant SPBRG and use that to calculate the value for my DEBUGOUT command as well.

I have a large network of connected devices. The Master (18F8723) polls the SLAVES (a bunch of 18F2221's). It sends out an 'Attention' byte, followed by the Slave's address, followed by a command and finally, a checksum.

The Slave uses the Receive part of it's EUSART so I can easily use interrupts
to grab the data. But when answering, the slave must 'speak' open-collector to avoid bus contention. I don't have room for an O.C. gate on the slave, so I can't use the Transmit part of the '2221's EUSART.

So, I use a different pin (not PORTC.6) to do the send. I use DEBUGOUT in order to get 19.2Kbaud with a 4MHz oscillator. And before you ask....
I modified PBPPIC18LIB to add a switch to DEBUGOUT that allows it to run in an open-collector mode.

It all works like a charm.

Heckler
- 4th April 2010, 00:10
Hey folks, I finally had a chance to grab a NEW PIC and read it to try and view this factory calibration value. But I can't seem to find it.

So as I stated earlier I have only 12F683, 16F688 & 16F690 chips. If I put a NEW pic in my programmer (pickit2 w/low pin count demo board) and then "read" the chip, all I see in the "Program Memory" window is "3FFF" in all memory locations. In the "EEPROM" window is "FF" in all locations.

Where do I look to find this "osccal" factory calibration value?
Are these chips just too "low end" to have this calibration value?

Why do I see "3FFF" in the program code area? This translates to 14 binary bits of "1". Why 14 bits? (the .pdf documentation says the 16F688 is an 8bit mcu)

Is it possible to view all the other "special function registers"? As I look at the .pdf it shows various values for the registers on power-up, and they are NOT all 1's.

HELP!!:(

Dwight

rmteo
- 4th April 2010, 00:41
1. None of the PIC's you mentioned have an OSCCAL register.
2. 8-bit PIC'ss have 8-bit data and either 12, 14 or 16 bit program words. The PIC's you have use 14-bit programs words.
3. When using a programmer, you can only see the program words (3FFF for unprogrammed locations) and EEPROM data (if present in device, FF is the erased state). You will not be able to see values of the SFR's unless you are using ICD.

Heckler
- 4th April 2010, 03:52
Thanks rmteo,

So is it correct to say that the PIC's I mentioned DO have the OSCTUNE register that the user can manually adjust to calibrate the oscillator. But they do not come from the factory with an OSCCAL value stored in memory.

How did you know that these chips do not come with this OSCAL value?

At what level DO the chips come with this calibration value?

Thanks again
Just trying to learn and understand:rolleyes:

Dwight

rmteo
- 4th April 2010, 04:04
Yes, all 3 of the PIC's you mentioned have an OSCTUNE register that allow you to adjust the frequency. As such, they do not have (or need) an OSCCAL.

The best place to get this info is from the device data sheet. Only the low end PIC10's (and some PIC12's) with 12-bit instruction words have the OSCCAL register. They also do not have an OSCTUNE register.

languer
- 4th April 2010, 05:55
How did you know that these chips do not come with this OSCAL value?
Read the datasheet - it's all there (no OSCCAL reg, but OSCTUNE reg).

Adding to rmteo's comments; none of the new chips (except the 10Fs) have OSCCAL. Reason is quite simple, they come trimmed from the factory; which makes their specs more tight than the ones with an OSCCAL reg. You can "tune" them if needed, but no real need to calibrate. If you place any of the newer chips on a frequency meter (one with a good reference); you'll notice they track pretty good. You only need to "tune" them if you need to track another free-running oscillator (read as if in RS232 clock/baud generator, etc), or want much better performance over temperature. The older chips with OSCCAL register were calibrated from the factory but their specs were looser and they could easily be erased (this was a big source of complaints).


At what level DO the chips come with this calibration value?
Older chips or lower end chips (10Fs) have the OSCCAL reg. You would much prefer the OSCTUNE register to the OSCCAL one (if given the choice).

Heckler
- 4th April 2010, 15:24
Thanks Languer,

That helps alot!! So the fact is that the chips that I am using are actually later generation chips with the OSCTUNE (and better quality internal oscillators).

I do have the datasheets and did do a search for both OSCCAL and OSCTUNE. I obviously found the latter not the former. I did not realize that OSCTUNE and OSCCAL were not the same thing, just stated differently, now I do.



Older chips or lower end chips (10Fs) have the OSCCAL reg. You would much prefer the OSCTUNE register to the OSCCAL one (if given the choice). This one statement helps a bunch.

If there has been one thing I have had to learn over the past year or so is to always check the datasheets. Then come here for more experienced help.
Thanks to all for your assistance.

Dwight
These PICS are like intricate puzzles just waiting for one to discover their secrets and MASTER their capabilities.

languer
- 5th April 2010, 01:19
I believe rmteo already answered the original question (use of auto-baud feature). I thought I add the Microchip AppNote which describes how to "auto-calibrate" the internal oscillator.

http://ww1.microchip.com/downloads/en/AppNotes/00244A.pdf

circuitpro
- 29th September 2010, 17:23
As long as I've been working with PICs and PBP, I am still intimidated when I see an ASSY program, and I am going to read this ApNote fully today. Do you incorporate this routine into your PBP program to run at some predefined interval? Another thing that concerns me is that it appears to use Timer1, and I want to use DT_INTs, including the elapsed timer routine. Will this clobber that? Can you tell me or show me how you incorporate this into a PBP program? (I am doing what Charles is, and need an accurate INTRC for a high speed uart.)

Thanks for any further enlightenment for getting this routine flying.

(I hope to use this with an 18F2420).

Charles Linquis
- 30th September 2010, 02:48
If you are building a PIC network, and need some pointers, I can give you some if you wish.

Unless you get really creative, you have to turn off interrupts while you send/receive in software.

circuitpro
- 30th September 2010, 04:26
I got a little rushed on this project, and didn't really consider some of the issues. I needed the space and ASSumed that the internal oscillator would be good enough. I dedicated the only hardware uart to a 9600 baud input because I need to use a DT-interrupt to receive the input character-by-character. Now I'm stuck trying to use DEBUG for a port that really needs to be faster than 9600. (Hence my earlier post inquiring as to how fast I could count on DEBUG to work). I should have either used a PIC with 2 uarts or gone ahead and plunked an oscillator down on the board. I MAY be able to use the prototypes using the internal oscillator, we'll know in a few days.

Charles Linquis
- 30th September 2010, 13:24
Don't be discouraged. I'm using an 18F8723 connected to any number of 18F2221s. The 2221's are remote sensors (temperature, humidity) and are very small. They couldn't generate any heat otherwise they would screw up the readings, so I run them on their internal oscillators at 4MHz to keep the power low. The sensors use the internal EUSART for receive, but have to shut the EUSART off to transmit, since I needed an open-collector transmitter, and the hardware (without an outboard FET, at least) is incapable of running open-collector. In order to meet my timing criteria, I needed to run 19.2Kbaud (for system timing reasons). Serout2 can't run 19.2 at 4Mhz, but DEBUGOUT does. The problem is - DEBUGOUT doesn't have an open-collector option, so I modified PBPPIC18.LIB to give me a debugout open-collector option. That works.

The sensors have a HSERIN interrupt running. When a character comes in, and there is an address match, the DEBUGOUT is invoked (it is also inside the ISR) and the response is sent. When not in the ISR, the PIC is continuously polling its temperature and humidity sensors.

The whole thing works very well, and has been tried with over 150' of cabling and 8 sensors.

Charles Linquis
- 1st October 2010, 04:03
Update:

I found a spool with 500' of Belden 8444 (unshielded, not twisted, 22Ga 4 conductor). I put a sensor at one end and hooked it to my PIC test board. It didn't work.

I lowered the Baud rate to 9600. It still didn't work. I lowered the pull-ups from 2.2K to 820 ohms. It worked perfectly! A scope showed the signals looked more than acceptable. This is driving directly from PIC pins.

circuitpro
- 1st October 2010, 04:46
Wow. Thats open-collector TTL, right? If you really needed more distance, you might try RS485. You can turn each driver off at the sensor when not transmitting, it's a great long-distance party line, and it likes 100-120 ohm hose. :)

Charles Linquis
- 1st October 2010, 13:29
The sensor is capable of RS-485, both half and full-duplex, and I have used that before. The sensor board (0.25" wide X 1.9" long) has stuffing options that allow all sorts of protocols - I2C,RS232,RS-485.

I have 8 or 10 different "Main" (or controller boards) already designed, any one of which that could control the sensor array. The particular feature set the customer wants, (SSH, SNMP, telnet, Real-Time Clock, Large event log) is on a board that doesn' t have an RS-485 chip. I don't want to design a new add on board at this time, so I'm going with the single-ended stuff. The customer will be using 30 sensors on 400' (total) of 4-wire cable. I think it will work!

retepsnikrep
- 15th February 2017, 08:38
18F2620 hserout baud rates off consistently.

I'm using hserout to send data to a PC running the old plx-daq excel data acquisition macro/control.
It's worked in the past but i haven't used it for a long time.

I have cranked up my pic speed to 32mhz using the PLL etc and that's confirmed by the simple flashing 1hz led trick.

I set the ESUART with data from PicMulticalc using 32mhz as osc speed.

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 51 ' 38400 Baud @ 32MHz, 0.16%
SPBRGH = 0
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator

The pic is transmitting data correctly but when checked with my logic probe I can see the baud rate is off.

At 38400 it is actually 40000
At 19200 it is 20000
At 9600 it is 10000

Seems very consistent and perhaps the windows serial port can't tolerate this error?

Do you thing this is a ESUART register setting problem or a wayward oscillator that needs OSCTUNE tweaking?

HenrikOlsson
- 15th February 2017, 12:01
I have a bunch of boards, all on a RS485 bus, all running the same code, and ONE board had to have its baudrate tweaked because it was off (I don't remember if I tweaked OSCTUNE or BAUDCON) so I'm leaning towards the oscillator not being quite where it should be.

Do you have another PIC of the same type to try with?

To verify if it's the oscillator, try generating a pulse with a known width and measure it.

/Henrik.

retepsnikrep
- 15th February 2017, 17:12
I tried another pic that produced exactly the same results

The pic is transmitting data correctly but when checked with my logic probe I can see the baud rate is off.

At 38400 it is actually 40000
At 19200 it is 20000
At 9600 it is 10000

richard
- 15th February 2017, 23:45
you're sending a start bit, 8 bits of data and a stop bit all encoded as one symbol ie 10 bits .
@say 9600 symbols per sec that yields a bit time of 10.4uS.
how and what are you measuring ?
logic probe ? do you mean logic analyser
have you left off the start or stop bit in your calcs ?
10 bits @ 10.4uS /bit = 9600 baud
9 bits @ 10.4uS /bit = 10000 baud

retepsnikrep
- 16th February 2017, 16:32
I'm measuring using Saleae Logic software.
It reports the values I mentioned when using autobaud to detect the rate.

https://www.saleae.com/downloads.

I used to have this working but the problem is I don't know if it is the transmitter Hserout or receiver plx-daq is not working?

The data looks correctly constructed with the logic analyser monitoring it.

My config for reference is

#CONFIG
__CONFIG _CONFIG1H, _OSC_INTIO67_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
__CONFIG _CONFIG2L, _PWRT_OFF_2L & _BOREN_OFF_2L & _BORV_3_2L
__CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
__CONFIG _CONFIG3H, _CCP2MX_PORTC_3H & _PBADEN_OFF_3H & _LPT1OSC_OFF_3H & _MCLRE_OFF_3H
__CONFIG _CONFIG4L, _STVREN_OFF_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
__CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L
__CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
__CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L
__CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
__CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
__CONFIG _CONFIG7H, _EBTRB_OFF_7H
#ENDCONFIG

DEFINE OSC 32 '32mhz Clock
OSCCON = %01110000 'Internal 32 mhz Osc and stable
OSCTUNE = %01000000 'Enable PLL 8mhz x 4
WDTCON = %00010101 'Set watchdog Timer for 1 second
CMCON = %00000111 'Comparators Off
CVRCON = %00000000 'CvRef Powered Down
CCP1CON= %00001100 'CCP1 Module PWM Mode
CCP2CON= %00000000 'CCP2 Module Disabled
HLVDCON= %00000000 'HLVCON Disabled
T1CON = %00110000 '$30 = Prescaler 1:8, TMR1 OFF
TRISA = %00001011 'SET PORTA0, A1 & A3 AS INPUTS, REST AS OUTPUTS
TRISB = %00000000 'SET PORTB AS OUTPUTS
TRISC = %10011000 'SET PORTC AS OUTPUTS EXCEPT PORT C3,C4 & C7
ADCON0 = %00000001 'SETUP ADC & ENABLE ADC MODULE on AN0
ADCON1 = %00001110 'SETUP ADC SET REFV to VDD & VSS AN0
ADCON2 = %00100010 'SETUP ADC FOSC/32 LEFT JUSTIFY TAD 8

DEFINE LCD_DREG PORTB 'PORTB is LCD data port
DEFINE LCD_DBIT 0 'PORTB.0 is the data LSB
DEFINE LCD_RSREG PORTC 'RS is connected to PORTC.0
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTC 'EN is connected to PORTC.1
DEFINE LCD_EBIT 1
DEFINE LCD_BITS 8 '8 lines of data are used
DEFINE LCD_LINES 4 'It is a 4-line display
DEFINE LCD_COMMANDUS 1500 'Use 1500uS command delay
DEFINE LCD_DATAUS 44 'Use 44uS data delay

DEFINE ADC_BITS 8 'Set number of bits in result
DEFINE ADC_CLOCK 3 'Set Clock source (3 = rc)
DEFINE ADC_SAMPLEUS 50 'Set sampling time in uS

DEFINE CCP1_REG PORTC 'HPWM channel 1 pin Port C Backlight PWM Driver
DEFINE CCP1_BIT 2 'HPWM channel 1 pin Bit 2

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 51 ' 38400 Baud @ 32MHz, 0.16%
SPBRGH = 0
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator

retepsnikrep
- 16th February 2017, 17:36
Closure on my problem. I found the reciever i was using wanted idle low data not idle high... Arrrggggg.. I was sure it was high..

Thanks for the advice. The transmitter was working correctly after all..