Menu

help with I2C

Help
2017-12-05
2021-11-30
  • Bill Kelsey

    Bill Kelsey - 2017-12-05

    I have been having trouble getting I2C to work. I have tried an endless loop with an I2C start, send, and stop so I could look at the signal with a Scope with a couple of LEDs blinking so I would know the program was running, and the program won't go. If I comment out the I2C commands, the LEDs blink. What am I missing??

    The program follows :

    `

     ;Chip Settings
    #chip 16F18325,4
    #config FEXTOSC=OFF, RSTOSC=HFINT1, MCLRE=ON
    
    ;Defines (Constants)
    #define I2C_MODE Master
    #define I2C_DATA PORTC.5
    #define I2C_CLOCK PORTC.4
    
    Do Forever
        PulseOut PORTC.2, 100 ms
        I2CStart
        I2CSend 96
        I2CStop
        Wait 100 ms
        PulseOut PORTC.1, 500 ms
    Loop
    `
    
     

    Last edit: Anobium 2017-12-06
  • Peter

    Peter - 2017-12-05

    This sounds similar to a problem that I had but using hardware i2c. Updating my version of Great Cow Basic fixed it
    https://sourceforge.net/p/gcbasic/discussion/579126/thread/747d3f6e/?limit=25#cfcc

    Do you need to set the data and clock pins to be inputs? (You do for HI2C)

     
  • Anobium

    Anobium - 2017-12-06

    @Bill. What are you trying to achieve? We need to know this as the code is not complete.

    My analysis.
    We do not know what version of Great Cow BASIC compiler you are using
    You are using software I2C not hardware I2C
    * You are not completing an I2C transaction. You start, send an address then stop. Very odd.

    Why not start with the i2C demos in your installation? the 16f18855 is a similar architecture chip and you can easily adapt. Remember if you use harware I2C (with this chip) you must use PPS.

    Start with the demos please. Adapt from a known baseline

    :-)

     
    • Bill Kelsey

      Bill Kelsey - 2017-12-06

      Anobium -
      Assuming I get the two lines to show me volage change, what do I do next? I have about 30 data points to send via I2C to my device. Do I send the I2C address once and the send all 30 pieces of data, or do I send the I2C address every time I send data to the device?

       
      • Anobium

        Anobium - 2017-12-06

        It depends.   What is the target device ? We need to know this. Each device may handle dataexchange differenlty but knowing the device will really help.

         
        • Bill Kelsey

          Bill Kelsey - 2017-12-06

          I'm trying to talk to an Si5351.. It has a default address of dec 96, and will be the only device on the line.

           
          • Anobium

            Anobium - 2017-12-06

            Nice device.

            You have chosen a device for which we need a library or are you up to writing the functions to drive the device?   I ask because if you are wanting a clock there are alternatives that a more commonly supported.

            If you are up to writing the functions based on the datasheet then we can help.

            If you want someone to write a library then that will take time until someone is willing to help.

            But, essentially,   a library is a set of functions that write data to setup the device and functions to read data.

            What are your thoughts?

            Edited: https://www.silabs.com/documents/public/application-notes/AN619.pdf Wow what a device. You will have fun.

             

            Last edit: Anobium 2017-12-06
            • Bill Kelsey

              Bill Kelsey - 2017-12-06

              As I understand it, all I have to do is write some hex data to some registers, and the Si5351 will generate the desired signal. Silabs provides software that does all the calculations to come up with the appropriate registers and values, so I have the data to go into the chip via I2C. I'll take the data Silabs comes up with, put it in a table in GC Basic, read the table, and send the values to the Si5351 vie I2C. Sounds simple enough....

               
              • Anobium

                Anobium - 2017-12-06

                To be honest that is it.

                As with all things.. things are tougher first time.

                We a lot of libraries that can show you the way to communicate. I think if you review the EEPROM libary this will show you the way to send and read data. One of the I2C GLCD libraries will show methods to use constants and pass lots of parameters.

                You will enjoy it.

                 
  • William Roth

    William Roth - 2017-12-06

    @Bill

    The code you posted [should] show clock and data signals on PORTC.4 and C.5. If it does not, then my guess is that there are no Pullup Resistors on the I2C Pins. I2C only sinks current, Therfore in order for the clock and data signals to go "high" these pullup resistors must be in place. A value of 4K7 should be adequate. So make sure you have pullups on PortC.4 and PortC.5.

    You have the ChipMhz set at 4. Since you are using bit-banged software IC2, this means that the IC2 Clock will only be about 40KHz. If you want ~100Khz then increase the ChipMhz to 16.

    While GCB tries to set the pin direction automatically it is generally a good practice to set this in your source code. I am referring to PortC.2 that you are using for an LED. So add

    DIR PORTC.2 Out
    

    Sometimes folks do not set their programmer to "release from reset" after programming. This makes it seem as though notihng is happening. Check the voltage on MCLR Pin . If it remains low after programming then the chip is in reset and will not run. After programming, either disconnect the programmer or configure the programmer application to "release from reset".

    As Evan suggested, it it a good idea to use the demos as a baseline instead of trying to wing it, or trying to reinvent the wheel.

     
  • Bill Kelsey

    Bill Kelsey - 2017-12-06

    First - it has been 50 years since I did any programming.. Everything in those 50 years has been hardware. Thats why I want to see those lines move on my scope! The START, SEND(anything), and STOP cmds looped forever should wiggle those lines.....I think!

    I couldn't find the version of GC Basic , but the date of compile of GC Basic is 0.98.01 2017-10-27 .
    I did start with the examples in the help file. Nothing seemed to happen, so I am trying to get the two I2C lines to go between plus and zero so I know I am at least talking to the chip. (I know it won't talk to my Si5351 with the I2C) I can't even get that to happen.
    I do have a 1.5k resistor to +3.3v from each of the I2Clines.
    The LED's blink when I have the START, SEND, and STOP lines commented out. They do not blink at all when those three lines are included in the code.
    I will try hardware I2C - now I have to figure out what PPS is!

    Thanks for your help!  I'll get it eventually
    
     
    • bed

      bed - 2017-12-06

      One old Guy to an other: I would consider 1.5k as very low, may be to low. For I2C @5V I use 10K, that is enough for more than 30cm.
      Your Version is 0.98.01
      Anyway great to have you on Board :-)

       

      Last edit: bed 2017-12-06
    • Peter

      Peter - 2017-12-06

      I will try hardware I2C - now I have to figure out what PPS is!

      PPS simply lets you rearrange what pin does what.
      On older PICs SDA1 and SCL1 from the hardware I2C module were hard wired to specific pins, on chips with PPS the you can connect SDA1 and SCL1 to any pin you like via your code at runtime.

      https://www.youtube.com/watch?v=tf2SfSm6fQg

      There is a configuration tool included with Great Cow Basic that helps generate the code.

          'Generated by PIC PPS Tool for Great Cow Basic
          'PPS Tool version: 0.0.5.11
          'PinManager data: v1.55
          '
          'Template comment at the start of the config file
          '
          #startup InitPPS, 85
      
          Sub InitPPS
      
                  'Module: MSSP1
                  RC5PPS = 0x0019    'SDA1 > RC5
                  SSP1DATPPS = 0x0015    'RC5 > SDA1 (bi-directional)
                  RC4PPS = 0x0018    'SCK1 > RC4
                  SSP1CLKPPS = 0x0014    'RC4 > SCK1 (bi-directional)
      
          End Sub
          'Template comment at the end of the config file
      
       

      Last edit: Peter 2017-12-06
  • William Roth

    William Roth - 2017-12-06

    @Bill

    The code you posted does exacrly what is expected on a 16F18346 chip here. This chip is the same as yours except for pin count and memory. I can see the clock and data signals on the scope. There is nothing connected to the PIC except the Programmer. the LED.and related current limit resistor on C.1 and the and pullup resistors on C.4 and C.5. You should get the same results as I do given the same seup.

    If you are getting no signals on the I2C lines then replicate my setpup and try again. If you get no ouput with bit-banged I2C, then my guess is that you will likely get none with Hardware I2C until you find the root cause of the problem.

    William

     

    Last edit: William Roth 2017-12-06
  • sfyris

    sfyris - 2021-11-25

    Yesterday tried this with a 12f675. It works! no need for pullups, just turn off the chip's option_reg.7 !

    ;Chip Settings
    #chip 12F675,4
    #option explicit
    
    dim p_w as byte
    
    ' Define I2C settings
    #define I2C_MODE master
    #define I2C_DATA GPIO.4
    #define I2C_CLOCK GPIO.5
    #define I2C_DISABLE_INTERRUPTS ON
    #define I2C_BIT_DELAY 20 us
    #define I2C_CLOCK_DELAY 30 us
    
    **OPTIONREG.7 = 0**
    
    Do Forever
     for p_w = 0 to 255
      repeat 100
        I2CStart
        I2CSend p_w
        i2cstop
        wait 10 ms
       end repeat
    next
    Loop
    
     
  • William Roth

    William Roth - 2021-11-30

    Hi,

    It may seem to work, however quite likely to fail under normal operating conditions.

    Per the 16F1875 Datasheet (p93) the Weak Pullup current is a nominal 250ua. Assuming a 5V power source that correlates to about 20K Ohms. In practice it is closer to 30K= 40K ohms.

    IC2 requires a minimum current to drive the IC2 lines to a high state. This is done via the specified pullup resistor. 20K-40K ohms is simply too much resistance to allow adequate current.

    While a scope may show decent signals with no load, the signals will degrade as devices are added and the distance between the master and slave device(s) increases.

    For reliable operation I would use at most 10K for short distances and less (4K7 or possibly less) for something like an I2C display with 6" leads.

     
  • David Stephenson

    I've never had any problems using the internal weak pull-ups (I may have even put up - on this forum- an oscilloscope trace showing that the pulses are quite acceptable).
    That said I usually only have a run of <10 cm, for longer runs I would definitely use proper pull-ups - though you can sometimes get away with much longer runs by lowering the baud rate (much of the data I send is from a sensor or to a display so the data speed reduction is not discernable).

     

Log in to post a comment.