Menu

I2C - PICAXE20X2 (Master), 16F628A (Slave)

Help
Morty
2020-05-01
2020-05-02
<< < 1 2 (Page 2 of 2)
  • Morty

    Morty - 2020-05-01

    Sorry, I meant same as the 20X2.

    Funnily enough I also have a AXE091 dev board, but I practically never use it as I just completely create what I need with breadboards.

    Regards,
    Morty.

     
  • Anobium

    Anobium - 2020-05-01

    This code generates NO I2C bus communications.

    test:
    HI2cSetup I2CMASTER, $60, I2C, I2CBYTE 'I2C comms to PIC16F628A
    let b20=10
    hi2cout 0,(b20)
    hi2cin (b21)
    sertxd(cr,cr,"Returned from 16F628A: ",#b21,cr,cr,lf)
    goto test
    

    I have scope on Pin 7 and 10 give no signals.
    I have analyser on the bus nothing.

     
  • Morty

    Morty - 2020-05-01

    Part of your CODE is incorrect. Try Copy/Paste this:

    test:
    HI2cSetup I2CMASTER, $60, I2CFAST, I2CBYTE  'I2C comms to PIC16F628A
    let b20=10
    hi2cout(b20)
    hi2cin (b21)
    sertxd(cr,cr,"Returned from 16F628A: ",#b21,cr,cr,lf)
    goto test
    

    Regards,
    Morty.

     

    Last edit: Morty 2020-05-01
  • Anobium

    Anobium - 2020-05-01

    Nothing on the I2C bus - and, therefore I get 255 on the PICAXE terminal

     
  • Morty

    Morty - 2020-05-01

    Here is some CODE with the PIC16F628 & LTC2485 on the same bus.

    HI2cSetup I2CMASTER, $60, I2CFAST, I2CBYTE  'I2C comms to PIC16F628A
    let b20=10
    hi2cout(b20)
    hi2cin (b21)
    sertxd(cr,cr,"Returned from 16F628A: ",#b21,cr,cr,lf)
    
    
    HI2cSetup I2CMASTER, $48, I2CFAST, I2CBYTE  'I2C Setup for LTC2485 - 24-bit external ADC
    hi2cin (b14,b15,b16,b17)
    sertxd("LTC2485: ",#b14," ",#b15," ",#b16," ",#b17,cr,lf)
    

    Attached is what is returned.

    Regards,
    Morty.

     
  • Anobium

    Anobium - 2020-05-01

    OK. This should work. This is HIGHLY sensitive to the amount of time between the OUT and IN in the PICAXE. I would add a delay to allow the SLAVE to do the work.

    Please send beer.

    ;----- Program
    do
    
      if I2CStartOccurred then                ;wait for Start signal
          I2CReceive( addr   )             ;then wait for an address
          if I2CMatch  = true then           ;if it matches, proceed
            I2CReceive( value )
            'do stuff here....  at the MASTER end... put a delay to enable processing
            value=value*5
    
            wait while I2C_CLOCK =0           ;wait for transition
            I2CReceive( addr  )               ;and the read address
            I2CSend value, NAK                ;and send the value
            I2CStop
    
          end if
       end if
    
    loop
    

    PICAXE

    pullup %0001111100111110
    setfreq m32
    HI2cSetup I2CMASTER, $60, i2cslow_32, I2CBYTE 'I2C comms to PIC16F628A
    let b20=1
    test:
    hi2cout (b20)
    'add a delay... would really help
    hi2cin (b21)
    sertxd(cr,cr,"Returned from 16F628A: ",#b21,cr,cr,lf)
    b20=b20+1
    if b20 > 25 then
        b20 = 1 
    end if
    goto test
    

    Gives this...

    Returned from 16F628A: 105
    Returned from 16F628A: 110
    Returned from 16F628A: 115
    Returned from 16F628A: 120
    Returned from 16F628A: 125
    Returned from 16F628A: 5
    Returned from 16F628A: 10
    Returned from 16F628A: 15
    Returned from 16F628A: 20
    
     

    Last edit: Anobium 2020-05-01
  • Anobium

    Anobium - 2020-05-01

    Morty the root cause from my examination is the PICAXE is following Clock stretching. The Slave should be able to hold the Clock line low to prevent the Master transmitting but this does not happen with the PICAXE.

    And, I like this code better... Whilst the Slave is waiting for the Slave Read Address the clock is monitored wait while I2C_CLOCK =0 then this version checks the Slave Read Address has been received. Should work a tad better.

    Evan

    ;----- Variables
    dim addr, reg, value as byte

    ;----- Program
    do
    
      if I2CStartOccurred then                ;wait for Start signal
          I2CReceive( addr   )             ;then wait for an address
          if I2CMatch  = true then           ;if it matches, proceed
            I2CReceive( value )
    
            'do stuff here....
            value=value+1
    
            wait while I2C_CLOCK =0           ;wait for transition
            I2CReceive( addr  )               ;and its address
            if ( addr OR 1 ) = ( I2C_ADDRESS OR 1 ) then
              I2CSend value, NAK
            end if
            I2CStop
    
          end if
       end if
    
    loop
    
     
  • Morty

    Morty - 2020-05-01

    Whoa! Thanks for the effort Evan, very much appreciated. Where do I send the beer mate?

    Copy/Paste both sets of code however I still constantly return 255.

    Did I have the correct ADDRESS in both sets of CODE?

    The two complete sets of CODE:
    PICAXE 20X2:

    'pullup %0001111100111110 <<<COMMENTED OUT, PRESUMED PULLUPS FOR I2C
    setfreq m32
    HI2cSetup I2CMASTER, $60, i2cslow_32, I2CBYTE 'I2C comms to PIC16F628A
    let b20=1
    test:
    hi2cout (b20)
    'add a delay... would really help
     pause 100  ' <<<DELAY ADDED HERE
    hi2cin (b21)
    sertxd(cr,cr,"Returned from 16F628A: ",#b21,cr,cr,lf)
    b20=b20+1
    if b20 > 25 then
        b20 = 1 
    end if
    goto test
    

    16F628A:

    ;----- Configuration
    
        #chip 16F628A
    
        #define I2C_MODE    Slave     ;this is a slave device now
        #define I2C_CLOCK   portb.2   ;SCL on pin 8
        #define I2C_DATA    portb.1   ;SDA on pin 7
        #define I2C_ADDRESS 0x60      ;address of the slave device
    
        ;----- Variables
        dim addr, value as byte
    
    ;----- Program
    do
    
      if I2CStartOccurred then                ;wait for Start signal
          I2CReceive( addr   )             ;then wait for an address
          if I2CMatch  = true then           ;if it matches, proceed
            I2CReceive( value )
            'do stuff here....  at the MASTER end... put a delay to enable processing
            value=value*5
    
            wait while I2C_CLOCK =0           ;wait for transition
            I2CReceive( addr  )               ;and the read address
            I2CSend value, NAK                ;and send the value
            I2CStop
    
          end if
       end if
    
    loop
    
     
  • Anobium

    Anobium - 2020-05-01

    You will need to run the 16F628a at 16mhz with an external clock to make this work.

    So, #chip 16f628a, 16 (with external OSC) and you will have to drop the PICAXE to m4 and i2cslow_4. Something is totally ignoring clock stretching........

    I was testing here at 32 mhz on the my 16f slave, if I drop to 4mhz or 8mhz [these are internal clocks)... I get 255. Set to 16mhz.... all ok.

     
    • Anobium

      Anobium - 2020-05-01

      Just tried to get 4mhz/8mhz working... nope.

       
  • Anobium

    Anobium - 2020-05-01

    You can make the 16F628a at internal 4mhz with setfreq m1 with i2cslow_4 will force the I2C clock to 25khz which works!!

     
  • Anobium

    Anobium - 2020-05-01

    PICAXE connected via I2C bus with suitable pullup resistors. The I2C Slave address is 0x60. The frequency of the PICAXE is critical. .

    The PICAXE Master sends a value to the Slave and the Slave returns the value with 1 added to it.

    Enjoy

    Final code:

    PICAXE CODE

    'i2C Master with external PIC Slave
    'Frequency of PIXACE is CRITICAL
    'This is has been tested to interoperate with a PIC at 4mHz
    '
    setfreq m1
    let b20=1
    test:
        HI2cSetup I2CMASTER, $60, i2cslow_4, I2CBYTE 'I2C comms to PIC16F628A
        hi2cout (b20)
        pause 10  'This delay is required, it gives time for the Slave to process stuff.
        hi2cin (b21)
        sertxd(cr,cr,"Returned from PIC: ",#b21,cr,cr,lf)
        b20=b20+1
        if b20 = 25 then
            b20 = 0 
        end if
        pause 500
    goto test
    

    Great Cow BASIC PIC CODE

    'change the chip...
    #chip 16F15376, 4
    
    
      #define I2C_MODE    Slave     ;this is a slave device now
      #define I2C_CLOCK   portd.1
      #define I2C_DATA    portd.0
      #define I2C_ADDRESS 0x60      ;address of the slave device
    
      ;----- Variables
      dim addr, reg, value as byte
    
    
      wait 1 s  
      ;----- Program
      do
    
        if I2CStartOccurred then                ;wait for Start signal
            I2CReceive( addr   )                ;then wait for an address
            if I2CMatch  = true then            ;if it matches, proceed
              I2CReceive( value )
    
              'do stuff here.... whlist the PICAXE is waiting....
              value=value+1
    
              'end of do stuff.....
              wait while I2C_CLOCK =0           ;wait for transition
              I2CReceive( addr  )               ;and its address
              if ( addr OR 1 ) = ( I2C_ADDRESS OR 1 ) then    ;check it is the read address
                I2CSend value, NAK                            ;send the data
              end if
              I2CStop
    
            end if
         end if
    
      loop
    
     

    Last edit: Anobium 2020-05-01
  • Morty

    Morty - 2020-05-02

    This has now been resolved.

    Thanks again.

    Regards,
    Morty.

     
<< < 1 2 (Page 2 of 2)

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.