I am trying to use an 18F25K20 to send I2C to a Si570 digitally controlled oscillator. It doesn't work. The clock and data lines reside low and flicker high. I know that is backwards for I2C. Can one of you gentlemen tell me what I am doing wrong?
I didn't post a schematic because it is so simple. The data line on the PIC goes to the data line on the oscillator. The clock line on the PIC goes to the clock line on the oscillator. Each of these is pulled up to 3.3 volts with a 5100 ohm resistor.
Looking with a scope, the pulses are nice and square, but apparently upside down. One expects an I2C line to stay high and then flicker downward when data is sent. These seem to be doing the opposite.
Chip
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you gentlemen. I am using version 0.9 dated 11/5/2014.
The IRCF bits are set as the regular way to set the internal oscillator on a 18F25K20.
ANSEL & ANSELH are cleared because I'm not using any analog inputs.
PortC is set as output because if I set it to input I get no result at all.
Tomorrow when I get to work I'll try not declaring it either way.
SENDI2C is supposed to be a subroutine. It's written funny because I fouled up.
I will correct it immediately, that could be the problem.
The pull up resistors certainly go to +3.3 VDC.
Thank you again.
Chip
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Okay, I updated to version 0.94. That immediately fixed the problem with the "upside down" lines. So we are making progress. I also connected a Bus Pirate to it and used its native I2C mode as well as its logic analyzer mode. The problems now seem limited to the stop character. When the data line rises to form the stop pulse, it puts a glitch in the timing pulse and splits the timing pulse in two. I tried a power filter capacitor right at the chip, but it didn't help.
Chip V.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
My latest effort is below. As you can clearly see in the subroutine, it is supposed to send groups of three bytes out the I2C port. Problem is, it randomly drops one of the three bytes. Can anybody see what is wrong?
'Set chip model:
#chip 18F25k20, 16 'at 16 MHz
'Switch Low-Volt-Programming:
#config LVP = Off
#config MCLR = Off
'Set internal clock speed to 16 MHz:
Set IRCF0 = 1
Set IRCF1 = 1
Set IRCF2 = 1
Dim REGISTER as Byte
Dim DATUM as Byte
Dim ADDRESS as Byte
Let ADDRESS = 0b10101010 'address 85 decimal, sending.
#define I2C_MODE Master
#define I2C_DATA PORTC.4 'this pin has 5k1 resistor to +3.3 volts.
#define I2C_CLOCK PORTC.3 'this pin has 5k1 resistor to +3.3 volts.
#define I2C_BIT_DELAY 4 uS
#define I2C_CLOCK_DELAY 2 uS
#define I2C_END_DELAY 2 uS
wait 5 mS 'time to do the defines?
'Main routine
Start:
Let REGISTER = 137 'freezing the output
Let DATUM = 0b00010000 'the freezing bit
SENDI2C
Let REGISTER = 7
Let DATUM = 0b00100010 ' HS_DIV and part of N1
SENDI2C
Let REGISTER = 8
Let DATUM = 0b01000010 ' end of N1 and beginning RFREQ
SENDI2C
Let REGISTER = 9 'more RFREQ
Let DATUM = 0xBC
SENDI2C
Let REGISTER = 10 'more RFREQ
Let DATUM = 0x01
SENDI2C
Let REGISTER = 11 'more RFREQ
Let DATUM = 0x1E
SENDI2C
Let REGISTER = 12 'the last of RFREQ
Let DATUM = 0xB8
SENDI2C
Let REGISTER = 137 'thawing output
LET DATUM = 0b00000000
SENDI2C
Let REGISTER = 135 'asserting new frequency
Let DATUM = 0b01000000
SENDI2C
Wait 1000 ms 'repeat once a second for scope test.
Goto Start 'jump back to the start of the program
'main line ends here
sub SENDI2C ' label to start i2c sending subroutine
I2CStart
I2CSend ADDRESS 'writing to slave at 85 decimal.
I2CSend REGISTER 'sending register addy within Si570
I2CSend DATUM
I2CStop
wait 5 mS ' this delay vital for Si570 to digest info.
end sub
end
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I just found out that the Si570, when oscillating, interferes with its own I2C communications. I'm working on a setup to shut off the output while I set a new frequency. That will do fine for my application.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you Evan and William. Together we prevailed. Working code below:
' Program sets Si570 to 100 MHz for calibration.
'Set chip model:
#chip 18F25k20,16 'at 16 MHz
'Switch Low-Volt-Programming:
#config LVP = Off
#config MCLR = Off
'Set internal clock speed to 16 MHz:
Set IRCF0 = 1
Set IRCF1 = 1
Set IRCF2 = 1
Dim REGISTER as Byte
Dim DATUM as Byte
Dim ADDRESS as Byte
Let ADDRESS = 0b10101010 'address 85 decimal, sending.
#define I2C_MODE Master
#define I2C_DATA PORTC.4 'this pin has 5k1 resistor to +3.3 volts.
#define I2C_CLOCK PORTC.3 'this pin has 5k1 resistor to +3.3 volts.
#define I2C_BIT_DELAY 5 uS
#define I2C_CLOCK_DELAY 3 uS
#define I2C_END_DELAY 3 uS
wait 5 mS 'time to do the defines?
'Main routine
do
portc.2 = 0 'Shut off output. Connect to Si570 OE
wait 1 mS 'waiting for quiet
Let REGISTER = 137 'freezing the output
Let DATUM = 0b00010000 'the freezing bit
SENDI2C
Let REGISTER = 7
Let DATUM = 0b00100010 ' HS_DIV and part of N1
SENDI2C
Let REGISTER = 8
Let DATUM = 0b01000010 ' end of N1 and beginning RFREQ
SENDI2C
Let REGISTER = 9 'more RFREQ
Let DATUM = 0xBC
SENDI2C
Let REGISTER = 10 'more RFREQ
Let DATUM = 0x01
SENDI2C
Let REGISTER = 11 'more RFREQ
Let DATUM = 0x1E
SENDI2C
Let REGISTER = 12 'the last of RFREQ
Let DATUM = 0xB8
SENDI2C
Let REGISTER = 137 'thawing output
LET DATUM = 0b00000000
SENDI2C
Let REGISTER = 135 'asserting new frequency
Let DATUM = 0b01000000
SENDI2C
portc.2 = 1 'starting the oscillator
Wait 1000 ms 'repeat once a second for scope test.
loop 'jump back to the start of the program
'main line ends here
sub SENDI2C ' label to start i2c sending subroutine
I2CStart
I2CSend ADDRESS 'writing to slave at 85 decimal.wait 20 uS
I2CSend REGISTER 'sending register addy within Si570wait 20 uS
I2CSend DATUM
I2CStop
wait 4 mS ' this delay vital for Si570 to digest info.
end sub
end
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It seems that the key factors in the solution were 1. Compile with version 0.94 2. Slow down the I2C pulses as shown 3. Shut off the Si570 while sending I2C so it doesn't interfere with itself.
Chip
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am trying to use an 18F25K20 to send I2C to a Si570 digitally controlled oscillator. It doesn't work. The clock and data lines reside low and flicker high. I know that is backwards for I2C. Can one of you gentlemen tell me what I am doing wrong?
'Set chip model:
#chip 18F25k20, 16 'at 16 MHz
'Switch Low-Volt-Programming:
#config LVP = Off
'Set internal clock speed to 16 MHz:
Set IRCF0 = 1
Set IRCF1 = 1
Set IRCF2 = 1
Dim REGISTER as Byte
Dim DATUM as Byte
Dim ADDRESS as Byte
Let ADDRESS = 0b10101010 'address 85 decimal, sending.
'Set the pin direction to output:
' (PORTC.4 = Pin 15 on PIC18F25k20 portc.3 = pin 14.)
Dir PORTC Out
#define I2C_MODE Master
#define I2C_DATA PORTC.4 'this pin has 5k1 resistor to +3.3 volts.
#define I2C_CLOCK PORTC.3 'this pin has 5k1 resistor to +3.3 volts.
ANSEL = 0
ANSELH = 0
SSPEN = 0
'Main routine
Start:
Let REGISTER = 137 'freezing the output
Let DATUM = 0b00010000 'the freezing bit
Gosub SendI2C
Let REGISTER = 7
Let DATUM = 0b001000001 ' HS_DIV and part of N1
Gosub SendI2C
Let REGISTER = 8
Let DATUM = 0b0100010 ' end of N1 and beginning RFREQ
Gosub SendI2C
Let REGISTER = 9 'more RFREQ
Let DATUM = 0xBC
Gosub SendI2C
Let REGISTER = 10 'more RFREQ
Let DATUM = 0x01
Gosub SendI2C
Let REGISTER = 11 'more RFREQ
Let DATUM = 0x1E
Gosub SENDI2C
Let REGISTER = 12 'the last of RFREQ
Let DATUM = 0xB8
Gosub SENDI2C
Let REGISTER = 137 'thawing output
LET DATUM = 0b00000000
Gosub SENDI2C
Let REGISTER = 135 'asserting new frequency
Let DATUM = 0b01000000
Gosub SENDI2C
Wait 1000 ms 'repeat once a second for scope test.
Goto Start 'jump back to the start of the program
'main line ends here
SendI2C: ' label to start i2c sending subroutine
I2CStart
I2CSend ADDRESS,FALSE 'writing to slave at 85 decimal.
I2CSend REGISTER,FALSE 'sending register addy within Si570
I2CSend DATUM,FALSE
I2CStop
wait 5 mS ' this delay vital for Si570 to digest info.
RETURN
Thanks in advance,
Chip
Last edit: Charles R. Veres 2015-05-22
Mr. Anobium:
I didn't post a schematic because it is so simple. The data line on the PIC goes to the data line on the oscillator. The clock line on the PIC goes to the clock line on the oscillator. Each of these is pulled up to 3.3 volts with a 5100 ohm resistor.
Looking with a scope, the pulses are nice and square, but apparently upside down. One expects an I2C line to stay high and then flicker downward when data is sent. These seem to be doing the opposite.
Chip
Can post a circuit diagram?
Do you have any pull ups? See http://www.robot-electronics.co.uk/acatalog/I2C_Tutorial.html
Most odd. I do not know. Pulled low? But, the resistors should pull high.
Can I ask? What version of GCB and the Release of your GCB code? Is this the latest build? I am wondering if you have old version of i2c.h.
@Anyone .. help us get to bottom of this one. :-)
Hi,
Here are some observations and some questions.
Last edit: William Roth 2015-05-25
Thank you gentlemen. I am using version 0.9 dated 11/5/2014.
The IRCF bits are set as the regular way to set the internal oscillator on a 18F25K20.
ANSEL & ANSELH are cleared because I'm not using any analog inputs.
PortC is set as output because if I set it to input I get no result at all.
Tomorrow when I get to work I'll try not declaring it either way.
SENDI2C is supposed to be a subroutine. It's written funny because I fouled up.
I will correct it immediately, that could be the problem.
The pull up resistors certainly go to +3.3 VDC.
Thank you again.
Chip
Please ugrade your GCB. This is really critical so we can help you.
See here, https://sourceforge.net/projects/gcbasic/ and select Download
Okay, I updated to version 0.94. That immediately fixed the problem with the "upside down" lines. So we are making progress. I also connected a Bus Pirate to it and used its native I2C mode as well as its logic analyzer mode. The problems now seem limited to the stop character. When the data line rises to form the stop pulse, it puts a glitch in the timing pulse and splits the timing pulse in two. I tried a power filter capacitor right at the chip, but it didn't help.
Chip V.
ummm. Does it work?
I have not seen any glitches.
Try increasing the I2C timings by changing from the defaults (defaults are shown below).
~~~~
define I2C_BIT_DELAY 2 us 'width of data bit on SDA
define I2C_CLOCK_DELAY 1 us 'width of clock pulse on SCL
define I2C_END_DELAY 1 us 'interval between clock pulses
Last edit: Anobium 2015-05-26
A logic trace is not showing a glitch.
Scope is not showing a glitch.
A better trace.
Slowing down helps. Just caught another error in my program. More tomorrow.
Chip V.
Gentlemen:
My latest effort is below. As you can clearly see in the subroutine, it is supposed to send groups of three bytes out the I2C port. Problem is, it randomly drops one of the three bytes. Can anybody see what is wrong?
'Set chip model:
#chip 18F25k20, 16 'at 16 MHz
'Switch Low-Volt-Programming:
#config LVP = Off
#config MCLR = Off
'Set internal clock speed to 16 MHz:
Set IRCF0 = 1
Set IRCF1 = 1
Set IRCF2 = 1
Dim REGISTER as Byte
Dim DATUM as Byte
Dim ADDRESS as Byte
Let ADDRESS = 0b10101010 'address 85 decimal, sending.
#define I2C_MODE Master
#define I2C_DATA PORTC.4 'this pin has 5k1 resistor to +3.3 volts.
#define I2C_CLOCK PORTC.3 'this pin has 5k1 resistor to +3.3 volts.
#define I2C_BIT_DELAY 4 uS
#define I2C_CLOCK_DELAY 2 uS
#define I2C_END_DELAY 2 uS
wait 5 mS 'time to do the defines?
'Main routine
Start:
Let REGISTER = 137 'freezing the output
Let DATUM = 0b00010000 'the freezing bit
SENDI2C
Let REGISTER = 7
Let DATUM = 0b00100010 ' HS_DIV and part of N1
SENDI2C
Let REGISTER = 8
Let DATUM = 0b01000010 ' end of N1 and beginning RFREQ
SENDI2C
Let REGISTER = 9 'more RFREQ
Let DATUM = 0xBC
SENDI2C
Let REGISTER = 10 'more RFREQ
Let DATUM = 0x01
SENDI2C
Let REGISTER = 11 'more RFREQ
Let DATUM = 0x1E
SENDI2C
Let REGISTER = 12 'the last of RFREQ
Let DATUM = 0xB8
SENDI2C
Let REGISTER = 137 'thawing output
LET DATUM = 0b00000000
SENDI2C
Let REGISTER = 135 'asserting new frequency
Let DATUM = 0b01000000
SENDI2C
Wait 1000 ms 'repeat once a second for scope test.
Goto Start 'jump back to the start of the program
'main line ends here
sub SENDI2C ' label to start i2c sending subroutine
I2CStart
I2CSend ADDRESS 'writing to slave at 85 decimal.
I2CSend REGISTER 'sending register addy within Si570
I2CSend DATUM
I2CStop
wait 5 mS ' this delay vital for Si570 to digest info.
end sub
end
Post the datasheet of the target device - I need to see the protocol.
Just for fun test the attachment please. you may need to edit but I quickly created. It is you code! I called it the wrong name.
https://www.silabs.com/.../si570.pdf
Is the data sheet for the Si570.
ok. I review it.
try the code I posted - ensure you check every parameter passed to the sub! :-)
Trying the code you posted - no joy so far. It rapidly sends the address byte over and over again. Trying to debug.
Chip V.
I just spotted I put 139 not 137 as the parameter. Did you change that?
I changed that, but still no help. Don't let the 570 datasheet make you too crazy. It is a true model of unclarity.
Chip
😃
Can you post any traces? Do you have any analysis tools?
I just found out that the Si570, when oscillating, interferes with its own I2C communications. I'm working on a setup to shut off the output while I set a new frequency. That will do fine for my application.
Thank you Evan and William. Together we prevailed. Working code below:
' Program sets Si570 to 100 MHz for calibration.
'Set chip model:
#chip 18F25k20,16 'at 16 MHz
'Switch Low-Volt-Programming:
#config LVP = Off
#config MCLR = Off
'Set internal clock speed to 16 MHz:
Set IRCF0 = 1
Set IRCF1 = 1
Set IRCF2 = 1
Dim REGISTER as Byte
Dim DATUM as Byte
Dim ADDRESS as Byte
Let ADDRESS = 0b10101010 'address 85 decimal, sending.
#define I2C_MODE Master
#define I2C_DATA PORTC.4 'this pin has 5k1 resistor to +3.3 volts.
#define I2C_CLOCK PORTC.3 'this pin has 5k1 resistor to +3.3 volts.
#define I2C_BIT_DELAY 5 uS
#define I2C_CLOCK_DELAY 3 uS
#define I2C_END_DELAY 3 uS
wait 5 mS 'time to do the defines?
'Main routine
do
portc.2 = 0 'Shut off output. Connect to Si570 OE
wait 1 mS 'waiting for quiet
Let REGISTER = 137 'freezing the output
Let DATUM = 0b00010000 'the freezing bit
SENDI2C
Let REGISTER = 7
Let DATUM = 0b00100010 ' HS_DIV and part of N1
SENDI2C
Let REGISTER = 8
Let DATUM = 0b01000010 ' end of N1 and beginning RFREQ
SENDI2C
Let REGISTER = 9 'more RFREQ
Let DATUM = 0xBC
SENDI2C
Let REGISTER = 10 'more RFREQ
Let DATUM = 0x01
SENDI2C
Let REGISTER = 11 'more RFREQ
Let DATUM = 0x1E
SENDI2C
Let REGISTER = 12 'the last of RFREQ
Let DATUM = 0xB8
SENDI2C
Let REGISTER = 137 'thawing output
LET DATUM = 0b00000000
SENDI2C
Let REGISTER = 135 'asserting new frequency
Let DATUM = 0b01000000
SENDI2C
portc.2 = 1 'starting the oscillator
Wait 1000 ms 'repeat once a second for scope test.
loop 'jump back to the start of the program
'main line ends here
sub SENDI2C ' label to start i2c sending subroutine
I2CStart
I2CSend ADDRESS 'writing to slave at 85 decimal.wait 20 uS
I2CSend REGISTER 'sending register addy within Si570wait 20 uS
I2CSend DATUM
I2CStop
wait 4 mS ' this delay vital for Si570 to digest info.
end sub
end
Well done - the delay fixed it?
It seems that the key factors in the solution were 1. Compile with version 0.94 2. Slow down the I2C pulses as shown 3. Shut off the Si570 while sending I2C so it doesn't interfere with itself.
Chip