PDA

View Full Version : PIC18s and Oscillator settings



cc1984
- 1st October 2011, 17:45
Ok, I have asked this question before: What is correct method to get a pic18 device set to an oscillator speed other the 4MHz? I have tried moving my configuration settings from the pbp file back to the include file, Changing all the occurances of OSC in pbppic18.lib file to XTAL, using DEFINE XTAL 32.

Does anyone else have this problem? Is there a PBP fix for this problem.

I can get the program to compile by:
1. Using the lib file to set the configuration fuses.
2. Using DEFINE OSC 32.
3. Keeping the original pbppic18.lib file.
After it successfully compiles, the pic does nothing.

I can also get it to compile by:
1. Set configuration fuses in the pbp file.
2. Replacing all occurances of OSC with XTAL in the pbppic18.lib file.
3. Using Define XTAL 32.
After in successfully compiles, the pic functions but serial communcations (serin2) are not functioning do to baud rate problems.

To "prove" the communcations problem was due to baud rate and not circuit or interconnection problems, I removed the osc definitions to ensure that the default of 4MHz was assumed by pbp. I change my PC based interface program to a lower baud rate (9600) and all communications worked correctly. However, I need a faster data transfer (38400).

Anybody got a solution to this problem. Any help would be appreciated.
CC

mackrackit
- 1st October 2011, 18:02
Probably not a good idea to be changing the *.lib files unless you REALLY know what you are doing.

Have you read this?
http://www.picbasic.co.uk/forum/showthread.php?t=543

cc1984
- 1st October 2011, 18:27
Yes, I have. I did make a backup copy of the file before I messed with it. Seems strange that others are not having this problem. Maybe the PIC18s are not that popular?
I just removed the DEFINE OSC setting and decided to let PBP assume that it was running at 4MHz. To get 38400 baud, I used 4800 in the code (SERIN2, rcx, 16572,....). It seems to communicate fine now. Problem is now I have to scale all my pauses, etc to get a my servo drive pulse delays correct. Thanks for the info.

mackrackit
- 1st October 2011, 18:38
Assuming your crystal or resonator is running at 32MHz, can you post your configs?
And I do not see the chip you are using.

cc1984
- 1st October 2011, 18:53
It's all working, but the code will be somewhat embarassing when I have to explain that I had to trick it into working. The chip is a 18F4515.
Configs:
'NOTE THAT CONFIGS ARE COMMENTED OUT IN THE 18F4515.INC FILE.
@ CONFIG OSC = INTIO67
@ CONFIG PBADEN=OFF
@ CONFIG MCLRE=ON
@ CONFIG WDT=OFF
@CONFIG STVREN=OFF
@CONFIG LVP=OFF

OSCILLATOR SETTINGS:

OSCCON=%01110000 'SET TO 8 MHZ
OSCTUNE=%11000000 'TURN ON PLL X4 FREQ NOW 32MHZ

cncmachineguy
- 1st October 2011, 19:06
PIC 18's are very popular, but they are a bit trickier to configure. Things to keep in mind:
PBP OSC setting does NOT set up the pic for you. It is just for the compilier to know how to set the delays like pause, serin/serout, i2cread/write, and so forth. To get the PIC to run at the speed YOU want, you will have to read the oscillator section for the PIC you are using to see what bits need to be set in what registor. The 18's are more to learn then the 16's.
There is no 1 answer for your question of how to set "it" up for 4mHz. We don't know what "it" is. We will help you, as dave is trying, but like Dave asked, what PIC are you using.

As for your first question in your first post, the answer is this. The correct procedure is to understand the oscillator section of the datasheet for the PIC you want to use. Ask plenty of questions to help with that understanding. Blink an LED at some speed (I like 1/2 second on then off) to verify things are correct. When they are, everything else will be easy. Some folks like to use "hello world" from the comm port for this part, for me that is harder. With that all I know if its right or wrong. With the LED, I can tell if it's too fast or too slow also. I consider the LED a bit easier for me and people who don't do this stuff everyday. Heres my blink, works on EVERY 8 bit PIC so I never have to modify it:


main:
high led
pause 500
low led
pause 500
goto main


Of course LED needs to be set before hand.

Posted at the same time, now I see the pic you have

cc1984
- 1st October 2011, 19:18
Here's the Code. Can you see what I am doing wrong. I also have the same problem on PIC18F4520 devices.


'************************************************* ***************
'* Name : PIC18F4515_WXR48BIT.BAS
'* Author : CHRIS CAUSEY
'* Notice :
'* :
'* Date : 01 Oct 2011
'* Version : 2.0 *
'* Notes : *
'* : *
'************************************************* ***************
'15feb-fixed dual assignments for pb3, assigned dacwr1 to pb5
' -changed led_red to led_data and assigned to pd2
'01Oct2011 - add a gain divisor to reduce the output level and added
' output of approximately 0.6V to the zero level %00001111
'pbp compiler has issues with 18 series chips
'The normal DEFINE for oscillator speed is DEFINE OSC 32. PBP has
'a problem with this because microchip changed the oscillator frequency
'definition from FOSC to OSC on these chips. The compiler is confused.
'The work around for this problem is to edit the pbp file for the 18 series chips.
'The edit is to replace all instances of OSC with XTAL and then identify the oscillator
'frequency -- DEFINE XTAL 32. The file which requires editing is in the pbp root dir-
'ectory - pbppic18.lib.
@ CONFIG OSC = INTIO67 ;config for internal osc
@ CONFIG PBADEN=OFF ;turn ofF port b analog inputs
@ CONFIG MCLRE=ON ;activate master clear
@ CONFIG WDT = OFF ;turn off watchdog timer
@ CONFIG STVREN = OFF ;turn off reset on overflow/underflow
@ CONFIG LVP = OFF ;turn off low voltage programming
'I AM TRICKING PBP INTO THINKING WE ARE OPERATING A 4MHZ, WHILE REALLY WORKING AT
'32MHZ. NO DEFINE OSC, PBP ASSUMES 4MHZ. SO THE FOLLOWING CHANGES WERE MADE, SERIAL
'COMM IS SET TO 4800 (38400/8). ALL PAUSE DURATIONS ARE MULTIPLIED BY 8.
' define XTAL 32
'DEFINE OSC 32
OSCCON = %01110000 'set internal oscillator to 8 mhz and select it as system clock
OSCTUNE= %11000000 'turn on pll frequency is now 32MHz
' OSCCON = %01100000 'set internal oscillator to 4 mhz and select it as system clock
' OSCTUNE= %00000000 'turn on pll frequency is now 32MHz

INTCON = %00000000 'turn off all interupt functions
ADCON0 = %00000000 'turn off adcs set to digital i/o
ADCON1 = %00001111 'turn off adcs set to digital i/o
TRISA = %00000000 'set port A to all outputs
TRISB = %00000000 'set port B to all outputs
TRISC = %10001011 'set port C
TRISD = %00000000 'set port D to all outputs
TRISE = %00000000 'set port E to all outputs
PORTA = %00000000 'set all outputs on port a to 0
PORTB = %00000000 'set outputs on port b to 0, except leds on 4&5
PORTD = %00000000 'set all outputs on port d to 0
PORTE = %00000000 'set all outputs on port e to 0
WDTCON = %00000000 'turn off wdt

while OSCCON.2=0
'wait for the oscillator stable bit to be set
pause 1
WEND
'port a is for dac data output
servo1 var PORTC.2 'servo drive pin
trigger1 var PORTB.4 'trigger #1
trigger2 var PORTB.3 'trigger #2
led_data VAR PORTD.2 'data status led
tcx var PORTC.6 'rs-232 output to simulation
rcx var PORTC.7 'rs-232 input from simulation
cts var PORTC.5 'control discrete to simulation
dacwr1 var PORTB.5 'dac latch control
i var word 'used for loop counts
cnt var byte 'use for the sweep angle counter
direction var bit 'used as flag for rotation direction
temp var byte 'temp variable
theta var byte 'antenna scan angle
level0 var bit 'flag to output default low value
thetaL1hi var word[180] 'array to hold level 1 output data (green/blue)
thetaL1mi var word[180] 'array to hold level 1 output data (green/blue)
thetaL1lo var word[180] 'array to hold level 1 output data (green/blue)
thetaL2hi var word[180] 'array to hold level 2 output data (yellow)
thetaL2mi var word[180] 'array to hold level 2 output data (yellow)
thetaL2lo var word[180] 'array to hold level 2 output data (yellow)
thetaL3hi var word[180] 'array to hold level 3 output data (green)
thetaL3mi var word[180] 'array to hold level 3 output data (green)
thetaL3lo var word[180] 'array to hold level 3 output data (green)
T1 var byte 'input of theta 100 multiplier
T2 var byte 'input of theta 10 multiplier
T3 VAR BYTE 'input of theta 1 adder
L11 var byte 'input of level 1 10000 multiplier
L12 var byte 'input of level 1 1000 multiplier
L13 var byte 'input of level 1 100 multiplier
L14 var byte 'input of level 1 10 multiplier
L15 var byte 'input of level 1 adder
L16 var byte 'input of level 1 10000 multiplier
L17 var byte 'input of level 1 1000 multiplier
L18 var byte 'input of level 1 100 multiplier
L19 var byte 'input of level 1 10 multiplier
L10 var byte 'input of level 1 adder
L1A var byte 'input of level 1 10000 multiplier
L1B var byte 'input of level 1 1000 multiplier
L1C var byte 'input of level 1 100 multiplier
L1D var byte 'input of level 1 10 multiplier
L1E var byte 'input of level 1 adder
L21 var byte
L22 var byte
L23 var byte
L24 var byte
L25 var byte
L26 var byte
L27 var byte
L28 var byte
L29 var byte
L20 var byte
L2A var byte
L2B var byte
L2C var byte
L2D var byte
L2E var byte
L31 var byte
L32 var byte
L33 var byte
L34 var byte
L35 var byte
L36 var byte
L37 var byte
L38 var byte
L39 var byte
L30 var byte
L3A var byte
L3B var byte
L3C var byte
L3D var byte
L3E var byte
holdval var word 'temp variable
stepdiv var byte 'used to define incremental servo travel
stepang var word 'used to define servo zero reference
Gain var byte 'variable to hold gain divisor to reduce output levels
GainMult var word 'variable to temporarily hold output level after gain

'define constants
stepdiv=10
stepang=600
Gain=2 'gain is a divisor, 2 gain = Output/2
PORTA=%00000000 'set video output to zero
dacwr1=0 'set dac control to load data
pauseus 80 'pause to settle
dacwr1=1 'latch data to output
for i=1 to 50 'set the servo to zero positon
servo1=1
pauseus 4800'600
servo1=0
pause 152'19
next i

trigger1=0 'turn off trigger transistor
trigger2=0
cnt=0 'set the sweep cnt to zero
direction=1 'start moving from 0-180
CTS=0 'set clear to send low

main_loop:
if cnt=180 then 'reverse direction if at 180 degrees
direction=0
endif
if cnt=0 then 'new scan
direction=1 'reverse direction if at 0 degrees
FOR I=1 TO 180 'get 180 sets of data
CTS=1 'set cts high to indicate ready
led_data=0 'turn on led to indicate waiting for data
'serin2 mode = 16390 ref pbp manual - equates to inverted, no parity, 38400 baud.
' serin2 rcx,16390,[T1,T2,T3,L11,L12,L13,L14,L15,L16,L17,L18,L19,L10,L 1A,L1B,L1C,L1D,L1E,L21,L22,L23,L24,L25,L26,L27,L28 ,L29,L20,L2A,L2B,L2C,L2D,L2E,L31,L32,L33,L34,L35,L 36,L37,L38,L39,L30,L3A,L3B,L3C,L3D,L3E]
serin2 rcx,16572,[T1,T2,T3,L11,L12,L13,L14,L15,L16,L17,L18,L19,L10,L 1A,L1B,L1C,L1D,L1E,L21,L22,L23,L24,L25,L26,L27,L28 ,L29,L20,L2A,L2B,L2C,L2D,L2E,L31,L32,L33,L34,L35,L 36,L37,L38,L39,L30,L3A,L3B,L3C,L3D,L3E]
CTS=0 'set cts low to indicate busy
T1=T1-48 'convert from ascii to dec value 1st value
T2=T2-48
T3=T3-48
theta=((100*T1)+(10*T2)+T3) 'create the angle theta
serout2 tcx,16572,[#THETA]
L11=L11-48 'convert level 1 data
L12=L12-48
L13=L13-48
L14=L14-48
L15=L15-48
thetal1hi[theta]=((10000*L11)+(1000*L12)+(100*L13)+(10*L14)+L15)
L16=L16-48 'convert level 1 data
L17=L17-48
L18=L18-48
L19=L19-48
L10=L10-48
thetal1mi[theta]=((10000*L16)+(1000*L17)+(100*L18)+(10*L19)+L10)
L1A=L1A-48 'convert level 1 data
L1B=L1B-48
L1C=L1C-48
L1D=L1D-48
L1E=L1E-48
thetal1lo[theta]=((10000*L1A)+(1000*L1B)+(100*L1C)+(10*L1D)+L1E)

L21=L21-48 'convert level 2 data
L22=L22-48
L23=L23-48
L24=L24-48
L25=L25-48
thetal2hi[theta]=((10000*L21)+(1000*L22)+(100*L23)+(10*L24)+L25)
L26=L26-48 'convert level 2 data
L27=L27-48
L28=L28-48
L29=L29-48
L20=L20-48
thetal2mi[theta]=((10000*L26)+(1000*L27)+(100*L28)+(10*L29)+L20)
L2A=L2A-48 'convert level 1 data
L2B=L2B-48
L2C=L2C-48
L2D=L2D-48
L2E=L2E-48
thetal2lo[theta]=((10000*L2A)+(1000*L2B)+(100*L2C)+(10*L2D)+L2E)

L31=L31-48 'convert level 3 data
L32=L32-48
L33=L33-48
L34=L34-48
L35=L35-48
thetal3hi[theta]=((10000*L31)+(1000*L32)+(100*L33)+(10*L34)+L35)
L36=L36-48 'convert level 3 data
L37=L37-48
L38=L38-48
L39=L39-48
L30=L30-48
thetal3mi[theta]=((10000*L36)+(1000*L37)+(100*L38)+(10*L39)+L30)
L3A=L3A-48 'convert level 1 data
L3B=L3B-48
L3C=L3C-48
L3D=L3D-48
L3E=L3E-48
thetal3lo[theta]=((10000*L3A)+(1000*L3B)+(100*L3C)+(10*L3D)+L3E)
led_data=1 'got data
next i
endif

'start sweep cycle

trigger1=1 'start trigger1
trigger2=1 'start trigger 2
pauseus 1 'hold trigger high for 5 us
trigger1=0 'turn off trigger pulse
trigger2=0
'start dac output for this transmission
for i=0 to 47 'check each bit
level0=1 'set level 0 flag to 1, if not changed level 0 will be output
if i<16 then
holdval=thetal1lo[cnt]
if (holdval>>i & 1)=1 then 'check each bit for level 1
gainmult=63/gain
PORTA=gainmult '%00111111 '63

level0=0 'if level 1 bit set, clear flag
endif
holdval=thetal2lo[cnt] 'check each bit for level 2
if (holdval>>I & 1)=1 then
gainmult=127/gain
PORTA=gainmult '%01111111 '127
level0=0 'if level 2 bit set, clear flag
endif
holdval=thetal3lo[cnt] 'check each bit for level 3
if (holdval>>I & 1)=1 then
gainmult=255/gain
PORTA=gainmult '%11111111 '255
level0=0 'if level 3 bit set, clear flag
eNDIF
if level0=1 then 'if level 0 flag still set, output level 0
PORTA=%00001111 '0000 '`0.6v
endif
endif
if i>15 and i<32 then
holdval=thetal1mi[cnt]
if (holdval>>(i-16) & 1)=1 then 'check each bit for level 1
gainmult=63/gain
PORTA=gainmult '%00111111 '63
level0=0 'if level 1 bit set, clear flag
endif
holdval=thetal2mi[cnt] 'check each bit for level 2
if (holdval>>(i-16) & 1)=1 then
gainmult=127/gain
PORTA=gainmult '%01111111 '127
level0=0 'if level 2 bit set, clear flag
endif
holdval=thetal3mi[cnt] 'check each bit for level 3
if (holdval>>(i-16) & 1)=1 then
gainmult=255/gain
PORTA=gainmult '%11111111 '255
level0=0 'if level 3 bit set, clear flag
eNDIF
if level0=1 then 'if level 0 flag still set, output level 0
PORTA=%00001111' ~0.6V0000 '0
endif
endif
if i>31 then
holdval=thetal1hi[cnt]
if (holdval>>(i-32) & 1)=1 then 'check each bit for level 1
gainmult=63/gain
PORTA=gainmult'%00111111 '63
level0=0 'if level 1 bit set, clear flag
endif
holdval=thetal2hi[cnt] 'check each bit for level 2
if (holdval>>(i-32) & 1)=1 then
gainmult=127/gain
PORTA=gainmult '%01111111 '127
level0=0 'if level 2 bit set, clear flag
endif
holdval=thetal3hi[cnt] 'check each bit for level 3
if (holdval>>(i-32) & 1)=1 then
gainmult=255/gain
PORTA=gainmult '%11111111 '255
level0=0 'if level 3 bit set, clear flag
eNDIF
if level0=1 then 'if level 0 flag still set, output level 0
PORTA=%00001111 '0000 ~0.6V '0
endif
endif

dacwr1=0 'set data to dac output
pauseus 1 'settling time
dacwr1=1 'latch data to output
'pauseus 104 '312 'hold for 16 grid counts
next i
if direction=1 then 'keep increasing until full 180 degree swing
cnt=cnt+1 'update the counter to move the pwm signal
endif
if direction=0 then 'keep decreasing until at zero
cnt=cnt-1
endif
for i=1 to 2 'move the servo 1 degree
servo1=1
pauseus (((stepang+(stepdiv*cnt)))*8)
servo1=0
pause 128'(16*8)
next i
goto main_loop
tryagain:
cnt=0
cts=0
goto main_loop
return
End

cncmachineguy
- 1st October 2011, 19:32
Well it sure appears your pic is configured correctly, I think. Do you have OSC in your code? what version of PBP are you using? I remember something about OSC messing with something in some of the 18's when using 2.6C, but don't know the fix or if it applies to the pic you are using, But there is a fix if thats what it is.

So do you think the pic is running at 32?

cc1984
- 1st October 2011, 19:45
I removed the DEFINE OSC so that the software thinks it is running at 4 MHz (default), but it is really running at 32MHz based on the OSCCON and OSCTUNE register settings. I think that it is actually running at this speed because my pc based interface program is set to a baud rate of 38400. So if my pic is running 8 times faster than the code thinks it is then I should set my serin2 to 4800 (38400/8=4800). Now the two will communicate correctly. However, if you noticed in the code where I have the following:
trigger1=1
trigger2=1
pauseus 1
trigger1=0
trigger2=0
When I measure the time that the triggers are actually on I am seeing about 12.6 microseconds. Looking in the pbp manual under the PAUSEUS command, I was expecting to see a pulse of about 2 usec. Not sure how long the instruction to change the state of a pin takes, but it seem like I should have better resoultion at 32 MHz.
Thoughts?

mackrackit
- 1st October 2011, 19:54
http://melabs.com/support/patches.htm#pbp
(http://melabs.com/support/patches.htm#pbp) Has a patch fixing baud rate accuracy for SERIN/SEROUT commands. Not sure if it will help here.

Byte_Butcher
- 1st October 2011, 21:32
I'm not familiar with the 18F4515, but this line looks odd to me...


@ CONFIG OSC = INTIO67 ;config for internal osc

INTIO67 ??

mackrackit
- 2nd October 2011, 01:28
From P18F4515.inc


;----- CONFIG1H Options --------------------------------------------------
_OSC_LP_1H EQU H'F0' ; LP oscillator
_OSC_XT_1H EQU H'F1' ; XT oscillator
_OSC_HS_1H EQU H'F2' ; HS oscillator
_OSC_RC_1H EQU H'F3' ; External RC oscillator, CLKO function on RA6
_OSC_EC_1H EQU H'F4' ; EC oscillator, CLKO function on RA6
_OSC_ECIO6_1H EQU H'F5' ; EC oscillator, port function on RA6
_OSC_HSPLL_1H EQU H'F6' ; HS oscillator, PLL enabled (Clock Frequency = 4 x FOSC1)
_OSC_RCIO6_1H EQU H'F7' ; External RC oscillator, port function on RA6
_OSC_INTIO67_1H EQU H'F8' ; Internal oscillator block, port function on RA6 and RA7
_OSC_INTIO7_1H EQU H'F9' ; Internal oscillator block, CLKO function on RA6, port function on RA7

cc1984
- 4th October 2011, 18:50
So that anyone who may also be having this problem, I am posting the fix (Provided by Mr. Darrel Taylor -- Thanks):

"With older versions of PicBasic Pro, you should not use the CONFIG (no underscores) directive in your code.
You can with PBP3, but it looks like you haven’t upgraded yet.

The 18F4515 uses the older __CONFIG directives.
Look in the P18F4515.inc file in the c:\program files\microchip\mpasm suite folder for the available options.
But I think you want …

ASM
__CONFIG _CONFIG1H, _OSC_INTIO67_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOREN_OFF_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H
__CONFIG _CONFIG3H, _CCP2MX_PORTC_3H & _PBADEN_OFF_3H & _LPT1OSC_OFF_3H & _MCLRE_ON_3H
__CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L
ENDASM"

I changed to the old config directives and 1: it compiled correctly and 2: it works! For the record PBP 2.60A is the version I am using.