Menu

16f1829 vs i2c Help need simple code does not work, I had this working but broke something.

Help
ofuzzy1
2013-09-28
2013-09-28
  • ofuzzy1

    ofuzzy1 - 2013-09-28

    It will flash the 2 LEDs @ c.5 & c.4
    THEN HALTS without ANY i2c activity.

    But will not do any i2c work, originally had the LED @ c.5 & c.4 where the LEDs DID flash so we know the pins do work.

    I know that the fix is something really simple but it alludes me.

    The MCP23017 is at 0x26 +R/W so that's 0x4c

    ' 2 Leds @ c.5 & c.4
    ' i2c bus @
    '         I2C_CLOCK PORTc.6
    '         I2C_DATA  PORTc.7
    
    'Chip Settings
    #chip 16F1829, 4
    
    'Defines (Constants)
    
    'I2C settings
    #define I2C_MODE Master
    
    #define I2C_DATA  PORTc.7
    #define I2C_CLOCK PORTc.6
    
    #define BlinkA    portC.5
    #define BlinkB    portC.4
    
    '  original i2c bus connector
    '#define I2C_DATA  PORTb.5
    '#define I2C_CLOCK PORTb.7
    
    #define I2C_Read_BIT  = 1
    #define I2C_Write_BIT = 0
    
    Dir i2c_data Out
    Dir i2c_clock Out
    
    'Variables
    Dim xB            As byte
    
    ADCON0 = 0
    ADCON1 = 0
    
    clrf ANSELa
    clrf ANSELb
    clrf ANSELc
    
    clrf LATa
    clrf LATb
    clrf LATc
    
    'Turn off Comparators
    CM1CON0 = 0
    CM1CON1 = 0
    CM2CON0 = 0
    CM2CON1 = 0
    
    trisC = 0
    
    Start:
    do
    
     'Blink some lights
      for xb = 1 to 30
        BlinkA = 1
        BlinkB = 0
        wait 100 ms
        BlinkA  = 0
        BlinkB  = 1
        wait 100 ms
      next xb
      BlinkA  = 0
      BlinkB  = 0
     ' wait 500 ms
     ' loop
    
     I2CStart
      I2CSend 0x4c   'i2cDevice + I2C_Write_BIT  ' Who + how
      I2CSend 0x00   'dira 'i2cAddress             ' Where to put it
      I2CSend 0x00   'all out 'i2cData                ' What to put there
      I2CStop
     wait 100 ms
    
     I2CStart
      I2CSend 0x4c   'i2cDevice + I2C_Write_BIT  ' Who + how
      I2CSend 0x12   'dira 'i2cAddress             ' Where to put it
      I2CSend 0xFF   'all out 'i2cData                ' What to put there
     I2CStop
    
     wait 250 ms
    
     I2CStart
      I2CSend 0x4c   'i2cDevice + I2C_Write_BIT  ' Who + how
      I2CSend 0x12   'dira 'i2cAddress             ' Where to put it
      I2CSend 0x00   'all out 'i2cData                ' What to put there
     I2CStop
    
     wait 200 ms
    
     Loop
    
     end
    
     
  • kent_twt4

    kent_twt4 - 2013-09-28

    I think the problem with the I2C communication starts with how the MCP23017 is addressed. I have to say the address scheme looks different from what I'm used to. This chip has to write to a config register (IOCON,HAEN) in order to activate the address pins A1-A3, and is reset to zero every POR and RST!

    So the default address is 0x40 plus the R/W bit, just stick with that unless there is a reason. Otherwise, a write to the IOCON,HAEN would be required to initialize the MCP23017 A1-A3 pins prior to main, that's just weird.

    What value of pullup resistors are on the SDA, SCL pins?

    EDIT: Oops, was looking at the SPI (wrong) addressing diagram.

     

    Last edit: kent_twt4 2013-09-28
  • ofuzzy1

    ofuzzy1 - 2013-09-28

    KENT:
    You were correct about the pull ups when I moved the ports away from my original placement of Sck = b.6 & Sda =b.5, the pullups were on the motherboard, not the i2c_IO_board. Need to move them to the last i2c_IO_board in the chain, RTfM, dooh!

    RTfM= read the FINE manual :)

    Issue # 2 is using HSERsend or hserprint causes Sck to be permanently allocated, so that caused some tail chasing, fixed that with:
    saving rcsta
    shutdown the RS232 serial port
    i2C stuff
    then turning it back on.

    I'm sure that will cause havoc when I change the i2c port to somewhere else :).

    Again thanks for the whack upside the head. :)

    This Now Works!

    #define I2C_Read_BIT  = 1
    #define I2C_Write_BIT = 0
    
    ...Main code ...
    
    xb = 0
    i2cWrite (IO_Chip6, IODIRA, xb)  ' make portA outputs
    i2cWrite (IO_Chip6, IODIRB, xb)  ' make portB outputs
    
    xb = 0xFF
    i2cWrite (IO_Chip6, GPIOA, xb)  ' turn all pins on
    i2cWrite (IO_Chip6, GPIOB, xb)  ' turn all pins on
    Wait 250 ms
    
    xb = 0xAA '170
    i2cWrite (IO_Chip6, GPIOA, xb)  ' swap pins on/off
    i2cWrite (IO_Chip6, GPIOB, xb)  '
    zb= i2cread (IO_Chip6, GPIOA)  ' make portA outputs
     HSerPrint " GPIOA= ": HSerprint xB : HSerPrint " " : HSerprint zB  ' make portA outputs
    
    zb= i2cread (IO_Chip6, GPIOB)  ' make portB outputs
     HSerPrint " GPIOB= ": HSerprint xB : HSerPrint " " : HSerprint zB  ' make portA outputs
    Wait 250 ms
    
    xb = 0x55 '85 '
    i2cWrite (IO_Chip6, GPIOA, xb)  ' swap pins on/off
    i2cWrite (IO_Chip6, GPIOB, xb)  '
    zb= i2cread (IO_Chip6, GPIOA)  ' make portA outputs
     HSerPrint " GPIOA= ": HSerprint xB : HSerPrint " " : HSerprint zB  ' make portA outputs
    
    zb= i2cread (IO_Chip6, GPIOB)  ' make portB outputs
     HSerPrint " GPIOB= ": HSerprint xB : HSerPrint " " : HSerprint zB  ' make portA outputs
    Wait 250 ms
    
    xb =  0x00 '0 '
    i2cWrite (IO_Chip6, GPIOA, xb)  ' turn all pins oFF
    i2cWrite (IO_Chip6, GPIOB, xb)  ' turn all pins oFF
    zb= i2cread (IO_Chip6, GPIOA)  ' make portA outputs
     HSerPrint " GPIOA= ": HSerprint xB : HSerPrint " " : HSerprint zB  ' make portA outputs
    
    zb= i2cread (IO_Chip6, GPIOB)  ' make portB outputs
     HSerPrint " GPIOB= ": HSerprint xB : HSerPrint " " : HSerprint zB  ' make portA outputs
    Wait 250 ms
    
    .....
    
    sub i2cWrite (i2cDevice, i2cAddress, i2cData) #NR
     reg_status = RCSTA
     rcsta = 0 ' shutdown the serial port to share with the i2c bus
     Rotate i2cDevice left Simple' *2 = << 1 ' is shifted left 1 because of The RW bit: $26 << 1 = $4C
     i2cstart
      I2CSend i2cDevice + I2C_Write_BIT  ' Who + how
      I2CSend i2cAddress             ' Where to put it
      I2CSend i2cData                ' What to put there
     I2CStop
     RCSTA = reg_status
    end sub
    
    Function i2cRead (i2cDevice, i2cAddress) 'fixed'
    
     Rotate i2cDevice left Simple ' *2 = << 1 ' is shifted left 1 because of The RW bit: $26 << 1 = $4C
     reg_status = RCSTA
     rcsta = 0 ' shutdown the serial port to share with the i2c bus
    I2CStart
      I2CSend     i2cDevice + I2C_Write_BIT  ' Who + how,  Tell it where to read
      I2CSend     i2cAddress             ' Where to GET it,  Give it the location
    I2CStop
    I2CStart
      I2CSend     i2cDevice + I2C_Read_BIT   ' Who + how,  Tell it you want to read
       I2CReceive  i2cData                ' What to GET from there
     I2CStop
    i2cRead  =  i2cData
    RCSTA = reg_status
    end function
    
     

    Last edit: ofuzzy1 2013-09-28
    • ofuzzy1

      ofuzzy1 - 2013-09-28

      The MCP23017 is really easy to use, and has a whole lot of features, unlike the PCF8575.

      Just set up ONE sets of registers just like a PIC.
      1. Direction port IODIR portA=0x00 or portB=0x01
      2. Then move the Data through GPIO portA=0x12 or portB=0x13

       
  • kent_twt4

    kent_twt4 - 2013-09-28

    That MCP23017 is certainly an interesting part.

    My BAD, looking again the ICON,HAEN only applies the the "SPI" addressing scheme, head slap, now that makes more sense.

    You have to use HSER because the free Tiny Bootloader version doesn't support software serial?

     
    • ofuzzy1

      ofuzzy1 - 2013-09-28

      Kent asks: You have to use HSER because the free Tiny Bootloader version doesn't support software serial?

      Ayup.

      And that is fine, I just need to move the i2c away from the HSER port.
      The ALT location c.4=[EN - CS] & c.5=[RS] is being used by the LCD.
      So both locations are important.
      I guess I could use the LCD d4-7 pins c.0-.3 while not trying to do a LCD write :)
      Hold the LCD EN (CS) low and I can torment all the other lines.
      -- This will allow 3 sets of i2c Busses :) c.0=Sck and c.1.2.3 as the Sda for i2c.1 .2 .3 -- that would be a whole lot of IO! 8163 =384
      Oh but wait I could also use the RS line to that make it 512, now that is just plain ridiculous. :0)

      Getting loopy here time for bed.

      Again, thanks for the help.
      G'nite.

       

      Last edit: ofuzzy1 2013-09-28
  • ofuzzy1

    ofuzzy1 - 2013-09-28

    Also, the 23017 comes in DIP28 or soic28 for easy and almost easy prototyping work @$1.20. The 8575 is only soic @$1.50.
    Prices from my order in 2012. 23017 is cheaper and more fun.
    newark.com

     

    Last edit: ofuzzy1 2013-09-28

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.