J_norrie
- 1st November 2010, 15:06
Hi there, I am trying to get my existing program that outputs 2-3 readings per second of serial data at 19200 at an internal clock frequency of 8Mhz. If I increase the clock frequency to 25Mhz by fitting an external HS crystal, I dont seem to get many more readings per second. PS I changed the Oscillator to HS in the INC file
Here is my code can anyone advise on what is wrong.
thanks again in advance John
' file : RS232CW.bas
' author : John Norrie
' date : 26/10/10
' purpose : Seariak output of load and battery condition
' includes : none
' notes : 10.00 te weight Read 16 bit ADC, convert to actual load value,
' :
' inverted 19200 baud value is 16416 used direct wire no 232 driver chip
' at pic end. AD7705 gain set to 4,unipolar 20hz cal test 178k//702R = 1mV/V or kg
' pic pin 18 RX to 9 way 'D' pin 2 crossed at rx end
' pic pin 17 TX to 9 way 'D' pin 3 crossed at rx end
' AD627 gain resistor 909R 0.1 % = gain of approx 200
' Bridge output mV/V for 10.00 te Cal = 0.681mV/V = te
' Bridge supply 2.5VDC REF03
' battery low set at 4.0vdc for 6.0v (4xC type bats) in via 2 x 5M5 resistor potential divider
' compiler : PICBasic Pro Compiler Ver 2.50A
PAUSE 1000 ' Allow power to stabilize on power-up
' Variable definition
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::
DEFINE OSC 25
OSCTUNE = %11111100 ' external primary osc block
'DEFINE LOADER_USED 1 ' Comment out if not using boot-loader
INCLUDE "modedefs.bas"
INTCON2.7 = 0 'enable weak pull-ups on PORTB
output portc.4 ' set pin to output operates cal relay
'AIN Channel setup
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 5 ' Set clock source (rc = 3)
DEFINE ADC_SAMPLEUS 5000
ADCON1 = %00001101 ' Set PORTA analog and select chs
ADCON2 = %10111110 ' Set PORTA analog and right justify res
ADCON0 = %00000001 ' Set enable analog
'AD7705 setup
output portb.7 'adc Clock pin
output portA.5 'AD7705 Data in pin
input portA.4 ' AD7705 Data out pin
input portA.3 'AD7705 Ready pin
input portA.0 ' Battery voltage input
input portA.1 ' Overload setting voltage input
symbol SCK=PORTB.7 'Clock pin
Symbol SI=PORTA.5 ' AD7705 Data in pin
Symbol SO=PORTA.4' AD7705 Data out pin
Symbol ADCready = PortA.3 'AD7705 Ready pin
'Symbol CS = PORTA.2'AD7705 Chip Select pin
symbol CalOut=PORTc.4
'AD7705 variables
adcSend var Byte 'byte sent to communication register of AD7705
adcrec var Byte 'byte received from AD7705:only for communication register, set-up register and clock register (8 bit registers)
ad1 var Word 'ad converter value read from AD7705
'ad2 var Word 'ad converter value read from AD7705
' ADC variables
Volt1 var word
VoltsA var word
Voltx var word
Total1 var word
i var byte
pass var byte
MaxVal var byte
MinVal var byte
Load var word
ADCvalue var word
gtare var byte
counts var byte
ScaleBits con 4096 '12 bit
z VAR Byte
c VAR Byte
B0 var byte
B1 VAR BYTE
B2 VAR word
d0 VAR BYTE
d1 VAR BYTE
d2 VAR BYTE
d3 VAR BYTE
p0 VAR BYTE
p1 VAR BYTE
p2 VAR BYTE
p3 VAR BYTE
t0 VAR BYTE
t1 VAR BYTE
t2 VAR BYTE
t3 VAR BYTE
x VAR Byte
p VAR Byte
a VAR Byte
b VAR Byte
v VAR Byte
tm var word
' Define keypad program variables
col var byte ' Keypad column
row var byte ' Keypad row
key var byte ' Key value
press var byte
db var byte
Total VAR WORD
totaly var word
Value VAR WORD
Value1 VAR WORD
Tare VAR WORD
TXBat var word
TXBat1 var word
RXBat var byte
Loadx var word
Loady var word
Range var word
NewVal var word
Calval var word
Cal1 var byte
peak var Word
peak1 var byte
peak2 var byte
load1 var byte
load2 var byte
CX var byte
DAout var word
cal1 = 100
B0 = 0
B2 = 0
tare = 0
Range = 2000
Calval = 850
volt1 = 0
peak = 0
CX = 1
calout = 0
key = 20
counts = 0
'EEPROMDATA:
'write 1,Cal1
'write 4,Calval.byte0 :write 5,Calval.byte1
'write 6,Range.byte0 :write 7,Range.byte1
Read 1,Cal1
Read 6,Range.byte0 :Read 7,Range.byte1
'Read 2,Tare.byte0 :read 3,Tare.byte1
if range < 1000 then range = 2000
if range > 2500 then range = 2000
if Cal1 < 1 then Cal1 = 100
if Cal1 > 255 then Cal1 = 100
Calval = Cal1 + 600
Tare = 0
' Main software
Start:
gosub MAX7705
gosub calibrate
gOTO Main
Main:
gosub ADCloop
gosub GetBatValue
volt1 = Newval
gosub AutoZero
gosub GetDigits
SEROUT2 PortC.6,16416,["L",#d3,#d2,".",#d1,#d0,"B",#t2,#t1,#t0] '19200 baud
goto Main
GetDigits:
d3 = Volt1 Dig 3
d2 = Volt1 Dig 2
d1 = Volt1 Dig 1
d0 = Volt1 Dig 0
t3 = txbat Dig 3
t2 = txbat Dig 2
t1 = txbat Dig 1
t0 = txbat Dig 0
return
MAX7705:
tare = 0
gosub MX7705Ini
pause 50
gosub mxch1
gosub mxcal1
return
ADCloop:
gosub getad1
return
getad1: 'for counterA = 0 to 15
Total1 = 0
For x = 1 to 8
adcsend=$38 ' Read the 16 bit DATA Register, channel 0.
shiftout SI, SCK, 5, [adcsend\8] ' adcsend read command and data register address
shiftin SO, SCK, 6, [ad1\16] ' Read 16 bit data
While ADCready = 1 'wait for valid data to be received
Wend 'wait for valid data to be received
value1 = abs (ad1/8)
Total1 = Total1 + value1
next x
value1 = abs (Total1/16) '65535/8 = 8192
if value1 < 1 then value1 = 0
if value1 > 4096 then value1 = 4096
value = value1 * Range
NewVal = div32 ScaleBits ' scalebits = 4096 (12 active bits)
return
GetAdValue:
Total1 = 0
For x = 1 to 8
adcsend=$38 ' Read the 16 bit DATA Register, channel 0.
shiftout SI, SCK, 5, [adcsend\8] ' adcsend read command and data register address
shiftin SO, SCK, 6, [ad1\16] ' Read 16 bit data
While ADCready = 1 'wait for valid data to be received
Wend 'wait for valid data to be received
ADCvalue = abs (ad1/8)
Total1 = Total1 + ADCvalue
next x
ADCvalue = abs (Total1/16) ' 4096 bits
return
AutoZero:
If volt1 < 3 then
counts = counts + 1
goto AutoZ
else
counts = 0
endif
return
AutoZ:
if counts = 5 then
volt1 = 0
counts = 0
endif
return
MX7705Ini:
'Reset MX7705
adcsend=$ff
adcrec=$ff
shiftout SI, SCK, 5, [adcsend\8] ' adcsend command to communication register
shiftout SI, SCK, 5, [adcrec\8] ' adcsend value to the selecte register
shiftout SI, SCK, 5, [adcsend\8] ' adcsend command to communication register
shiftout SI, SCK, 5, [adcrec\8] ' adcsend value to the selecte register
return
'SetADGAIN:
' if gainval = 1 then ADGAIN = $44 'decimal 68 gain = 1
' if gainval = 2 then ADGAIN = $4c 'decimal 76 gain = 2
' if gainval = 3 then ADGAIN = $54 'decimal 84 gain = 4
' if gainval = 4 then ADGAIN = $5c 'decimal 92 gain = 8
' if gainval = 5 then ADGAIN = $64 'decimal 100 gain = 16
' if gainval = 6 then ADGAIN = $6c 'decimal 108 gain = 32
' if gainval = 7 then ADGAIN = $74 'decimal 116 gain = 64
' if gainval = 8 then ADGAIN = $7c 'decimal 124 gain = 128
' return
mxch1:'CH1 AD7705 set-up Start. SEE AD7705.XLS FOR TABLE OF SETTINGS
adcsend=$20 ' WRITE TO THE COMMUNICATIONS REGISTER. SELECT CHANNEL 0 AND SET NEXT OPERATION AS A WRITE TO THE CLOCK REG
' CLOCK REGISTER.(0x20)
adcrec=$00 ' write on clock register: clock division=1, clock bit=1, master clock enabled (bit set to 0),
' bit output rate set to 20hz
gosub mxsend
'adcsend=$28
'GOSUB adread
return
mxcal1: 'CH1 Calib 'self-calibration
adcsend=$10 ' WRITE TO THE COMMUNICATIONS REGISTER. SELECT CHANNEL 0 AND SET NEXT OPERATION AS A WRITE TO THE SETUP REGISTER.(0x10).
adcrec=$54 ' WRITE TO THE SETUP REGISTER. SET SELF-CALIBRATION MODE, GAIN TO 4, UNIPOLAR MODE, BUFFERED MODE.
' BEGIN SELF-CALIBRATION/CONVERSION BY CLEARING FSYNC.(0x44)
gosub mxsend
gosub adcrdy
'adcsend=$8
'GOSUB adread
return
mxsend:
shiftout SI, SCK, 5, [adcsend\8] ' adcsend command to communication register
shiftout SI, SCK, 5, [adcrec\8] ' adcsend value to the selecte register
return
adcrdy:
While ADCready = 1:Wend 'wait for valid data to be adceived. Er angivet under self calibration mode.
' Note that after the self calibration, AD7705 start free conversion cycle.
Return
' ----------------------------------------------------------------------------
' Get Battery level Value A to D routine
' ----------------------------------------------------------------------------
' usable battery 2.7-5.4vdc (4xAAbats)
GetBatValue: 'potential divider of 2x 5m6 res accross bat
Total = 0 ' 0-1024 bits for 0-10.00 vin (o/p max650)
For z = 1 to 64 'Average of 64 readings to reduce noise
ADCIN 0, value1
Total = Total + value1
next
TXbat = Total >> 6 ' Same as divide by 64
TXbat = TXbat-722 'usable range 300 bits
TXbat = TXbat/3
if Txbat < 1 then Txbat = 0
if Txbat > 100 then Txbat = 100
if TXbat < 20 then
freqout portc.2, 500,5 'gosub Battlow '10.0 volt level '1024 bits for 12.9vdc usable range
else
freqout portc.2,10,10
endif
return
GetRange:
REAd 6,Range.byte0 :read 7,Range.byte1
if range < 1000 then range = 2000
if range > 4096 then range = 2000
goto Main
' ----------------------------------------------------------------------------
' Auto calibrate
' ----------------------------------------------------------------------------
calibrate:
portc.4 = 0
PAUSE 5000
gosub getadvalue
if ADCvalue > 800 then
goto GetRange
else
gosub GetAdValue
Loadx = ADCvalue
portc.4 = 1: pause 5000 ' Apply calibration signal & wait 5 sec's
gosub GetAdValue
Loady = ADCvalue
portc.4 = 0 ' Switch off calibration signal
Loady = abs (Loady - Loadx)
gosub calspan
Return
endif
' ----------------------------------------------------------------------------
' Calspan
' ----------------------------------------------------------------------------
calspan:
if (calval < 650 ) or ( calval > 999) then calval = 750
x = Calval * ScaleBits
Range = div32 Loady
peak = 0
write 6,Range.byte0 :write 7,Range.byte1
return
Here is my code can anyone advise on what is wrong.
thanks again in advance John
' file : RS232CW.bas
' author : John Norrie
' date : 26/10/10
' purpose : Seariak output of load and battery condition
' includes : none
' notes : 10.00 te weight Read 16 bit ADC, convert to actual load value,
' :
' inverted 19200 baud value is 16416 used direct wire no 232 driver chip
' at pic end. AD7705 gain set to 4,unipolar 20hz cal test 178k//702R = 1mV/V or kg
' pic pin 18 RX to 9 way 'D' pin 2 crossed at rx end
' pic pin 17 TX to 9 way 'D' pin 3 crossed at rx end
' AD627 gain resistor 909R 0.1 % = gain of approx 200
' Bridge output mV/V for 10.00 te Cal = 0.681mV/V = te
' Bridge supply 2.5VDC REF03
' battery low set at 4.0vdc for 6.0v (4xC type bats) in via 2 x 5M5 resistor potential divider
' compiler : PICBasic Pro Compiler Ver 2.50A
PAUSE 1000 ' Allow power to stabilize on power-up
' Variable definition
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::
DEFINE OSC 25
OSCTUNE = %11111100 ' external primary osc block
'DEFINE LOADER_USED 1 ' Comment out if not using boot-loader
INCLUDE "modedefs.bas"
INTCON2.7 = 0 'enable weak pull-ups on PORTB
output portc.4 ' set pin to output operates cal relay
'AIN Channel setup
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 5 ' Set clock source (rc = 3)
DEFINE ADC_SAMPLEUS 5000
ADCON1 = %00001101 ' Set PORTA analog and select chs
ADCON2 = %10111110 ' Set PORTA analog and right justify res
ADCON0 = %00000001 ' Set enable analog
'AD7705 setup
output portb.7 'adc Clock pin
output portA.5 'AD7705 Data in pin
input portA.4 ' AD7705 Data out pin
input portA.3 'AD7705 Ready pin
input portA.0 ' Battery voltage input
input portA.1 ' Overload setting voltage input
symbol SCK=PORTB.7 'Clock pin
Symbol SI=PORTA.5 ' AD7705 Data in pin
Symbol SO=PORTA.4' AD7705 Data out pin
Symbol ADCready = PortA.3 'AD7705 Ready pin
'Symbol CS = PORTA.2'AD7705 Chip Select pin
symbol CalOut=PORTc.4
'AD7705 variables
adcSend var Byte 'byte sent to communication register of AD7705
adcrec var Byte 'byte received from AD7705:only for communication register, set-up register and clock register (8 bit registers)
ad1 var Word 'ad converter value read from AD7705
'ad2 var Word 'ad converter value read from AD7705
' ADC variables
Volt1 var word
VoltsA var word
Voltx var word
Total1 var word
i var byte
pass var byte
MaxVal var byte
MinVal var byte
Load var word
ADCvalue var word
gtare var byte
counts var byte
ScaleBits con 4096 '12 bit
z VAR Byte
c VAR Byte
B0 var byte
B1 VAR BYTE
B2 VAR word
d0 VAR BYTE
d1 VAR BYTE
d2 VAR BYTE
d3 VAR BYTE
p0 VAR BYTE
p1 VAR BYTE
p2 VAR BYTE
p3 VAR BYTE
t0 VAR BYTE
t1 VAR BYTE
t2 VAR BYTE
t3 VAR BYTE
x VAR Byte
p VAR Byte
a VAR Byte
b VAR Byte
v VAR Byte
tm var word
' Define keypad program variables
col var byte ' Keypad column
row var byte ' Keypad row
key var byte ' Key value
press var byte
db var byte
Total VAR WORD
totaly var word
Value VAR WORD
Value1 VAR WORD
Tare VAR WORD
TXBat var word
TXBat1 var word
RXBat var byte
Loadx var word
Loady var word
Range var word
NewVal var word
Calval var word
Cal1 var byte
peak var Word
peak1 var byte
peak2 var byte
load1 var byte
load2 var byte
CX var byte
DAout var word
cal1 = 100
B0 = 0
B2 = 0
tare = 0
Range = 2000
Calval = 850
volt1 = 0
peak = 0
CX = 1
calout = 0
key = 20
counts = 0
'EEPROMDATA:
'write 1,Cal1
'write 4,Calval.byte0 :write 5,Calval.byte1
'write 6,Range.byte0 :write 7,Range.byte1
Read 1,Cal1
Read 6,Range.byte0 :Read 7,Range.byte1
'Read 2,Tare.byte0 :read 3,Tare.byte1
if range < 1000 then range = 2000
if range > 2500 then range = 2000
if Cal1 < 1 then Cal1 = 100
if Cal1 > 255 then Cal1 = 100
Calval = Cal1 + 600
Tare = 0
' Main software
Start:
gosub MAX7705
gosub calibrate
gOTO Main
Main:
gosub ADCloop
gosub GetBatValue
volt1 = Newval
gosub AutoZero
gosub GetDigits
SEROUT2 PortC.6,16416,["L",#d3,#d2,".",#d1,#d0,"B",#t2,#t1,#t0] '19200 baud
goto Main
GetDigits:
d3 = Volt1 Dig 3
d2 = Volt1 Dig 2
d1 = Volt1 Dig 1
d0 = Volt1 Dig 0
t3 = txbat Dig 3
t2 = txbat Dig 2
t1 = txbat Dig 1
t0 = txbat Dig 0
return
MAX7705:
tare = 0
gosub MX7705Ini
pause 50
gosub mxch1
gosub mxcal1
return
ADCloop:
gosub getad1
return
getad1: 'for counterA = 0 to 15
Total1 = 0
For x = 1 to 8
adcsend=$38 ' Read the 16 bit DATA Register, channel 0.
shiftout SI, SCK, 5, [adcsend\8] ' adcsend read command and data register address
shiftin SO, SCK, 6, [ad1\16] ' Read 16 bit data
While ADCready = 1 'wait for valid data to be received
Wend 'wait for valid data to be received
value1 = abs (ad1/8)
Total1 = Total1 + value1
next x
value1 = abs (Total1/16) '65535/8 = 8192
if value1 < 1 then value1 = 0
if value1 > 4096 then value1 = 4096
value = value1 * Range
NewVal = div32 ScaleBits ' scalebits = 4096 (12 active bits)
return
GetAdValue:
Total1 = 0
For x = 1 to 8
adcsend=$38 ' Read the 16 bit DATA Register, channel 0.
shiftout SI, SCK, 5, [adcsend\8] ' adcsend read command and data register address
shiftin SO, SCK, 6, [ad1\16] ' Read 16 bit data
While ADCready = 1 'wait for valid data to be received
Wend 'wait for valid data to be received
ADCvalue = abs (ad1/8)
Total1 = Total1 + ADCvalue
next x
ADCvalue = abs (Total1/16) ' 4096 bits
return
AutoZero:
If volt1 < 3 then
counts = counts + 1
goto AutoZ
else
counts = 0
endif
return
AutoZ:
if counts = 5 then
volt1 = 0
counts = 0
endif
return
MX7705Ini:
'Reset MX7705
adcsend=$ff
adcrec=$ff
shiftout SI, SCK, 5, [adcsend\8] ' adcsend command to communication register
shiftout SI, SCK, 5, [adcrec\8] ' adcsend value to the selecte register
shiftout SI, SCK, 5, [adcsend\8] ' adcsend command to communication register
shiftout SI, SCK, 5, [adcrec\8] ' adcsend value to the selecte register
return
'SetADGAIN:
' if gainval = 1 then ADGAIN = $44 'decimal 68 gain = 1
' if gainval = 2 then ADGAIN = $4c 'decimal 76 gain = 2
' if gainval = 3 then ADGAIN = $54 'decimal 84 gain = 4
' if gainval = 4 then ADGAIN = $5c 'decimal 92 gain = 8
' if gainval = 5 then ADGAIN = $64 'decimal 100 gain = 16
' if gainval = 6 then ADGAIN = $6c 'decimal 108 gain = 32
' if gainval = 7 then ADGAIN = $74 'decimal 116 gain = 64
' if gainval = 8 then ADGAIN = $7c 'decimal 124 gain = 128
' return
mxch1:'CH1 AD7705 set-up Start. SEE AD7705.XLS FOR TABLE OF SETTINGS
adcsend=$20 ' WRITE TO THE COMMUNICATIONS REGISTER. SELECT CHANNEL 0 AND SET NEXT OPERATION AS A WRITE TO THE CLOCK REG
' CLOCK REGISTER.(0x20)
adcrec=$00 ' write on clock register: clock division=1, clock bit=1, master clock enabled (bit set to 0),
' bit output rate set to 20hz
gosub mxsend
'adcsend=$28
'GOSUB adread
return
mxcal1: 'CH1 Calib 'self-calibration
adcsend=$10 ' WRITE TO THE COMMUNICATIONS REGISTER. SELECT CHANNEL 0 AND SET NEXT OPERATION AS A WRITE TO THE SETUP REGISTER.(0x10).
adcrec=$54 ' WRITE TO THE SETUP REGISTER. SET SELF-CALIBRATION MODE, GAIN TO 4, UNIPOLAR MODE, BUFFERED MODE.
' BEGIN SELF-CALIBRATION/CONVERSION BY CLEARING FSYNC.(0x44)
gosub mxsend
gosub adcrdy
'adcsend=$8
'GOSUB adread
return
mxsend:
shiftout SI, SCK, 5, [adcsend\8] ' adcsend command to communication register
shiftout SI, SCK, 5, [adcrec\8] ' adcsend value to the selecte register
return
adcrdy:
While ADCready = 1:Wend 'wait for valid data to be adceived. Er angivet under self calibration mode.
' Note that after the self calibration, AD7705 start free conversion cycle.
Return
' ----------------------------------------------------------------------------
' Get Battery level Value A to D routine
' ----------------------------------------------------------------------------
' usable battery 2.7-5.4vdc (4xAAbats)
GetBatValue: 'potential divider of 2x 5m6 res accross bat
Total = 0 ' 0-1024 bits for 0-10.00 vin (o/p max650)
For z = 1 to 64 'Average of 64 readings to reduce noise
ADCIN 0, value1
Total = Total + value1
next
TXbat = Total >> 6 ' Same as divide by 64
TXbat = TXbat-722 'usable range 300 bits
TXbat = TXbat/3
if Txbat < 1 then Txbat = 0
if Txbat > 100 then Txbat = 100
if TXbat < 20 then
freqout portc.2, 500,5 'gosub Battlow '10.0 volt level '1024 bits for 12.9vdc usable range
else
freqout portc.2,10,10
endif
return
GetRange:
REAd 6,Range.byte0 :read 7,Range.byte1
if range < 1000 then range = 2000
if range > 4096 then range = 2000
goto Main
' ----------------------------------------------------------------------------
' Auto calibrate
' ----------------------------------------------------------------------------
calibrate:
portc.4 = 0
PAUSE 5000
gosub getadvalue
if ADCvalue > 800 then
goto GetRange
else
gosub GetAdValue
Loadx = ADCvalue
portc.4 = 1: pause 5000 ' Apply calibration signal & wait 5 sec's
gosub GetAdValue
Loady = ADCvalue
portc.4 = 0 ' Switch off calibration signal
Loady = abs (Loady - Loadx)
gosub calspan
Return
endif
' ----------------------------------------------------------------------------
' Calspan
' ----------------------------------------------------------------------------
calspan:
if (calval < 650 ) or ( calval > 999) then calval = 750
x = Calval * ScaleBits
Range = div32 Loady
peak = 0
write 6,Range.byte0 :write 7,Range.byte1
return