i2c non-eeprom examples?


+ Reply to Thread
Results 1 to 15 of 15
  1. #1
    justDIY's Avatar
    justDIY Guest

    Default i2c non-eeprom examples?

    Hi All

    just found this forum with google - deffinately will be having a good time 'catching up' on all the old posts.

    Has anyone worked with Maxim MAX6650 (or 6651) fan speed regulator?

    I think I understand using i2c read and write with a serial eeprom, and it looks very straight forward.

    however, I'm wondering about interfacing with more 'complex' i2c devices.

    Even if you haven't worked with the 6650 or 6651, can anyone share example or rough starting points on how to control a similar device?

    thanks a lot!

    Gordon

    datasheet for 6650/1

    http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf

  2. #2
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Here's an example snippet... reads the time from a DS1307...

    I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl]

    Melanie

    oops... it's all supposed to be on one line... but won't edit as such!

  3. #3
    justDIY's Avatar
    justDIY Guest


    Did you find this post helpful? Yes | No

    Default

    Originally posted by Melanie
    I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl]
    ok, so this is basicly just a multibyte read... all the named variables were declared as bytes ?

    $d0 is the device's address, with the read / write bit set to read 1101000 + 0 ?

    $00 is the location (register?) the read starts at?

    I assume then that a write to that device would be similar, but the address would be $D1 (1101000 + 1) and the variables would be loaded with bytes properly formatted as per the datasheet?

    sorry to ask such a novice question, but, how do I take apart a byte and figure out what the individual bits are, like reading the RTCCtrl byte?

  4. #4
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    OK, you've posed a whole heap of questions... so let's take this apart...

    1. Yes, all the variables were prevoiuly decalred as bytes. You can send words, they are sent highbyte first which can conflict with the usual default memory storage arrangements. If in doubt use the highbyte or lowbyte modifier and send bytes to ensure your target device gets data in the arrangement it expects.

    2. $D0 (always do Hex in capitals as some assemblers will turn around and bite you if you use lower-case). Yes, it's the device address. I didn't do it in this example, but ideally you will have previously defined this as either an 8-bit or 16-bit variable (to suit your device) and preloaded ($D0 in my case) into it. No, don't worry about changing bit 0 of the address to a '1' or a '0' (depending on Read or Write) as the I2C commands will automatically handle that bit for you. I usually always leave it as '0'.

    3. $00. Yes this is the Register address. My example showed me reading eight bytes starting with address $00. If I only wanted to read the Hours Register, I could have executed...

    I2CRead SDApin,SCLpin,$D0,$02,[RTCHour]

    4. Writing would be the opposite of reading (including my new example above). The Data bytes would have been preloaded with the information targeting the registers I wanted loaded with that data. As I said before, don't worry about bit 0 of the Address, it's handled for you. If you do include it, no harm done as the I2C commands will ignore it and do their own thing anyway.

    5. Strip a byte apart using the bit manipulation facilities of PICBasic.

    Example 1. Let me use the Seconds Byte RTCSec in my example. When you first power-up a DS1307 (you just got it fresh from Dallas), and you apply power to it (either by slotting-in a Battery or from it's main +5v Supply, or both, or if it's been powered off without Battery Backup), then the chip basically is brainless. It has no Date, no Time, and everything (including it's NVRam which is only NV if there's a battery connected - kinda like my Laptop!) is in an unpredicatable state. Worse, the chip isn't even ticking. The only thing that you DO know is that bit 7 of the Seconds Register is set to '1'. So, you read the Seconds Register and do this...

    If RTCSec.7=1 goto SetDateandTime

    Example 2. You want the DS1307 to output a 1 second tick on it's SQW/OUT pin. This is done by setting bit 4 to 1, and bits 1 and 0 of the Control Register to zero. Two ways to do this... either...

    (a) Read the Control Register Byte first, then do this...

    RTCCtrl.4=1
    RTCCtrl.1=0
    RTCCtrl.0=0

    and then write the Byte back out again into the Control Register (which will not affect the setting of the other five bits), or,

    (b) Preset the entire Control Register BYTE (all eight bits of it)...

    RTCCtrl=%00010011

    and again write the whole byte out...

    You will notice we can only do BYTE I2CREAD/WRITE operations, and cannot manipulate a single individual bit. The method you chose is up to you. This chip requires method (b) to initialise because you can't rely on Dallas's engineers to have built it properly to initialise itself into any predetermined state - therefore you have to do it. The Datasheet of your chosen I2C device should tell you the state of all it's internals at Power-Up.

    The I2C bit is really easy - but study the Datasheet of your chosen device. See what state it's in and what it needs to initialise it from Power Up. Once you've done that, everything is as sweet as Mom's Apple Pie...

    Melanie

  5. #5
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    I'm just going to add to my previous posting to give you a nudge in the right direction... looking at the datasheet for your fan controller, it looks like you cannot address all the Registers sequentially in one hit (like I do with the DS1307 example). For a start, they're not sequential - it looks like Maxim designed this on a Friday afternoon and they went home early... so each Register will have to be addressed on an individual basis with it's own I2CRead/Write instruction.... example...

    FanAddress var Byte
    FanControl var Byte
    FanData var Byte

    FanControl=$02:FanData=%00001010:Gosub SetFanA
    FanControl=$04:FanData=%11110101:Gosub SetFanA

    .. ..

    SetFanA:
    FanAddress=$90
    I2CWrite SDApin,SCLpin,FanAddress,FanControl,[FanData]
    Return

    I'll let you figure what I've set, and how I connected the chip to give it a $90 address...

    Melanie

  6. #6
    justDIY's Avatar
    justDIY Guest


    Did you find this post helpful? Yes | No

    Talking

    Originally posted by Melanie
    I'm just going to add to my previous posting to give you a nudge in the right direction... looking at the datasheet for your fan controller, it looks like you cannot address all the Registers sequentially in one hit (like I do with the DS1307 example). For a start, they're not sequential - it looks like Maxim designed this on a Friday afternoon and they went home early... so each Register will have to be addressed on an individual basis with it's own I2CRead/Write instruction.... example...

    FanAddress var Byte
    FanControl var Byte
    FanData var Byte

    FanControl=$02:FanData=%00001010:Gosub SetFanA
    FanControl=$04:FanData=%11110101:Gosub SetFanA

    .. ..

    SetFanA:
    FanAddress=$90
    I2CWrite SDApin,SCLpin,FanAddress,FanControl,[FanData]
    Return

    I'll let you figure what I've set, and how I connected the chip to give it a $90 address...

    Melanie
    wow - great replies Melanie - thanks a ton!

    always type hex values in caps - noted!

    no need to specify read or write bit in the address - noted!

    about the ds1307:

    from reading the datasheet, I see what you mean about $00 bit 7 ... assuming a fresh (or disconnected) clock chip, that bit will be high, so I can tell whether I need to initialize the chip or not.

    bit manipulation:

    well I'm real sorry I had to ask that! I've spent all this time reading datasheets but haven't given the pbp manual any attention.

    about the max6650:

    $90 - ok I'll answer the easy one first, wiring for the address!

    Address $90 hex = 1001000 ... tie ADD pin 5 to ground

    now, for my 100th time reading the 6650 datasheet, all the talk of register this ... bit that... is starting to make sense!

    FanControl=$02=%00000010 ... select the CONFIG register

    byte fandata=%00001010

    bits 7 to 6 always 00 according to data sheet
    bits 5 to 4 set to 00 = software full-on
    bit 3 set to 1 = 12 volt fan
    bits 2 to set to 010 = Prescaler divide by 4

    next, FanControl=$04=%00000100 ... select GPIO configuration

    byte fandata=%11110101

    bit 7 set to 1 = gpio 4 high/input
    bit 6 set to 1 = gpio 3 high/input
    bits 5,4 set to 11 = gpio 2 high/input
    bits 3,2 set to 01 = gpio 1 set to FULL ON input
    bits 1,0 set to 01 = gpio 0 set to ALERT output


    thanks A LOT for your help!

    i'm in an optimistic mood already, as I tested my pair of max6650s that I had hand soldered to DIP 10 to µSOP adapters (max6650 is about the size of two grains of white rice!) ... both passed with flying colors connected directly to my PC's smbus

    your responses to my questions makes me even more optimistic that I'll be able to complete my project easily! pbp is powerfull stuff, and so is the microchip pic!

    my serial programmer just arrived saturday, cant wait to try some code against the real pic now!

    have a good week,

    Gordon

  7. #7
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Spot On. See - that was easy... the forum has just got a new fan expert!

  8. #8
    Join Date
    Mar 2005
    Posts
    15


    Did you find this post helpful? Yes | No

    Default

    I've read and followed the example/explanation above and it looked great to me. I've got a problem wich looks like this. I'm trying to control the MAX6953. (Datasheet: MAX6953 http://pdfserv.maxim-ic.com/en/ds/MAX6953.pdf )

    The MAX6953 is an I2C-controlled LED-matrix driver for 4 segments of 5*7 LED's.
    I'm using a PIC16f870 to control one MAX6953. I thought it would be simple to try to use the display test mode first. In this test-mode, all LED's will light up.

    This is the code I'm using:

    Include "modedefs.bas"
    DEFINE OSC 20

    SCL VAR PORTB.0
    SDA VAR PORTB.1

    CommandByte VAR BYTE
    SlaveAddress VAR BYTE
    DataByte VAR BYTE

    Main:
    'Set the device address at the I2C-bus (datasheet page 10)
    SlaveAddress = $50

    'Set the Command Byte ($07 = displaytestmode. Datasheet page 11)
    CommandByte = $07

    'Set the Data Byte
    DataByte = $01

    'Write the data to the I2C-device
    I2CWRITE SDA, SCL, SlaveAddress, CommandByte, [DataByte]

    end


    The problem is that there is nothing happening. Does anybody know what I'm doing wrong?

  9. #9
    justDIY's Avatar
    justDIY Guest


    Did you find this post helpful? Yes | No

    Default

    first let me blow the dust off this thread... *sneeze*

    It might have been a better idea to start a new thread than dig up one thats 9 months old

    Quote Originally Posted by RubenR
    I thought it would be simple to try to use the display test mode first. In this test-mode, all LED's will light up.

    Main:
    'Set the device address at the I2C-bus (datasheet page 10)
    SlaveAddress = $50

    The problem is that there is nothing happening. Does anybody know what I'm doing wrong?
    Looks like you wanted slave address = $A0 not $50 ... i2c address uses the 7 most significant bits of a byte, leaving the LSB for the read/write indicator ... see page 7 on the datasheet under slave address for the nitty gritty details

    so $50 = 0101000x , but you need $A0 = 1010000x

    the command and command data look a-ok

    looks like a really feature packed chip - hope to hear more about it!

  10. #10
    Join Date
    Mar 2005
    Posts
    15


    Did you find this post helpful? Yes | No

    Default

    Thanks! The address looks better now, but it still doesn't work yet.

    I'll keep trying and will let you know when it works. If someone else got a good idea, I would like to here it too!

  11. #11
    justDIY's Avatar
    justDIY Guest


    Did you find this post helpful? Yes | No

    Default

    hmm all i can think of is make sure the various decalres and registers are setup properly for i2c writes

    if your pic has an MSSP module, you could try HBUSOUT and HBUSIN

    also, make sure your i2c bus is wired properly, sda and scl need to be pulled high.

    you can try breaking your commands down to their basics, write the address byte and wait for an ack, write the command byte, wait for an ack, data byte, ack .... etc ... just to troubleshoot your communications.

  12. #12
    Join Date
    Mar 2005
    Posts
    15


    Did you find this post helpful? Yes | No

    Default

    Thanks for the reply. I've pulled up the ports and it look like it works now! It is possible to put the LED-driver into the test-mode and to set it back to normal operation.

    The only problem is that I can't get a character on the display. To find te problem I've attached a serial cable to the PIC and added some debug commands.

    The code I've used:


    Include "modedefs.bas"
    DEFINE OSC 20
    'DEFINE I2C_HOLD 1

    SCL VAR PORTB.4
    SDA VAR PORTB.5

    CommandByte VAR BYTE
    SlaveAddress var BYTE
    DataByte VAR BYTE
    ReadData VAR BYTE
    Character VAR BYTE

    'Set Debug pin port
    DEFINE DEBUG_REG PORTC
    'Set Debug pin bit
    DEFINE DEBUG_BIT 5
    'Set Debug baud rate
    DEFINE DEBUG_BAUD 2400
    'Set Debug mode: 0 = true, 1 = inverted
    DEFINE DEBUG_MODE 1


    Init:

    Debug "-->> Start <<--", 10 ,13

    Debug "Test mode", 10 ,13
    SlaveAddress = $A0 'Set the device address at the I2C-bus (datash. p. 10)
    CommandByte = $07 'Set the Command Byte ($07 = displaytestmode. Datasheet page 11)
    DataByte = $01 'Set the Data Byte
    I2CWRITE SDA, SCL, SlaveAddress, CommandByte, [DataByte] 'Write the data to the I2C-device
    I2CREAD SDA, SCL, SlaveAddress, [ReadData]
    Debug "ReadData = ", dec ReadData ,10 ,13 ,10 ,13

    pause 500

    Debug "Normal mode", 10 ,13
    SlaveAddress = $A0 'Set the device address at the I2C-bus (datash. p. 10)
    CommandByte = $07 'Set the Command Byte ($07 = Normal mode. Datasheet page 11)
    DataByte = $00 'Set the Data Byte
    I2CWRITE SDA, SCL, SlaveAddress, CommandByte, [DataByte] 'Write the data to the I2C-device
    I2CREAD SDA, SCL, SlaveAddress, [ReadData]
    Debug "ReadData = ", dec ReadData ,10 ,13 ,10 ,13

    pause 500

    Debug "Set LED intensity 1", 10 ,13
    SlaveAddress = $A0 'Set the device address at the I2C-bus (datash. p. 10)
    CommandByte = $01 'Set the Command Byte ($01 = Intensity10. Datasheet page 11)
    DataByte = $FF 'Intensity of all segments set to maximum (Page 20)
    I2CWRITE SDA, SCL, SlaveAddress, CommandByte, [DataByte] 'Write the data to the I2C-device
    I2CREAD SDA, SCL, SlaveAddress, [ReadData]
    Debug "ReadData = ", dec ReadData ,10 ,13 ,10 ,13

    pause 500

    Debug "Set LED intensity 2", 10 ,13
    SlaveAddress = $A0 'Set the device address at the I2C-bus (datash. p. 10)
    CommandByte = $02 'Set the Command Byte ($02 = Intensity32. Datasheet page 11)
    DataByte = $FF 'Intensity of all segments set to maximum (Page 20)
    I2CWRITE SDA, SCL, SlaveAddress, CommandByte, [DataByte] 'Write the data to the I2C-device
    I2CREAD SDA, SCL, SlaveAddress, [ReadData]
    Debug "ReadData = ", dec ReadData ,10 ,13 ,10 ,13

    pause 500

    Debug "Set Scan-Limit", 10 ,13
    SlaveAddress = $A0 'Set the device address at the I2C-bus (datash. p. 10)
    CommandByte = $03 'Set the Command Byte ($01 = Intensity10. Datasheet page 11)
    DataByte = $01 'Intensity of all segments set to maximum (Page 20)
    I2CWRITE SDA, SCL, SlaveAddress, CommandByte, [DataByte] 'Write the data to the I2C-device
    I2CREAD SDA, SCL, SlaveAddress, [ReadData]
    Debug "ReadData = ", dec ReadData ,10 ,13 ,10 ,13

    pause 500

    Debug "Character 'I'D0,P0&P1", 10 ,13
    SlaveAddress = $A0 'Set the device address at the I2C-bus (datash. p. 10)
    CommandByte = $60 'Set the Command Byte ($60 = Digit 0 Plane P0 & P1. Datasheet page 11)
    DataByte = $49 'Display Character 'I'
    I2CWRITE SDA, SCL, SlaveAddress, CommandByte, [DataByte] 'Write the data to the I2C-device
    I2CREAD SDA, SCL, SlaveAddress, [ReadData]
    Debug "ReadData = ", dec ReadData ,10 ,13 ,10 ,13

    Debug "-->> End <<--", 10 ,13 ,10 ,13 ,10 ,13

    end


    And this is the result at my serial port:


    -->> Start <<--
    Test mode
    ReadData = 0

    Normal mode
    ReadData = 0

    Set LED intensity 1
    ReadData = 0

    Set LED intensity 2
    ReadData = 1

    Set Scan-Limit
    ReadData = 0

    Character 'I'D0,P0&P1
    ReadData = 0

    -->> End <<--

    While the chip is in test-mode, the LED's are all burning. After the testmode, no LED is burning.

  13. #13
    justDIY's Avatar
    justDIY Guest


    Did you find this post helpful? Yes | No

    Default

    well, i had my basics confused ... hbusin/out is a proton command, not an melabs command - appologies


    anyway the data sheet talks about "read-after-write verification" (pgs 7-9):

    When performing read-after-write verification, reset the command byte's address because the stored byte address generally is autoincremented after the write (Table 4).
    so I would try:

    I2CWRITE SDA, SCL, SlaveAddress, CommandByte, [DataByte] ' write data to register
    I2CREAD SDA, SCL, SlaveAddress, CommandByte, [ReadData] ' reset pointer and read register

    depending how your program will end up, you can also use the auto-increment feature to write all the configuration with a single I2CWRITE command, just add more byte variables, after your DataByte

    as far as no character showing up, not sure what to say there... from a cursory glance, I find no errors in what youve written compared to the datasheet. double, triple, quadruple check your wiring to the datahseet ... I experimented with maxim's 6956, a little simpler beast than what you have there, but it still took a lot of fiddling to make it work!

  14. #14
    Join Date
    Mar 2005
    Posts
    15


    Did you find this post helpful? Yes | No

    Default MAX6953 <-> pic16f870: working!

    Yes, it's working.
    What I was doing wrong was not setting the intensity registers, so the LED's won't light up. Here's the configuration code I'm using now:


    SetConfig:
    SlaveAddressWrite = $A0
    CommandByte = $04 'Set the Command Byte ($04 = Configuration Datasheet page 11)
    DataByte = $81 '10000001 Tabel 7 page 12
    FOR i = 0 to nAddress
    I2CWRITE SDA, SCL, SlaveAddressWrite, CommandByte, [DataByte] 'Write the data to the I2C-device
    I2CREAD SDA, SCL, SlaveAddressWrite, CommandByte, [RcvDataByte]
    SlaveAddressWrite = SlaveAddressWrite + $02
    NEXT i
    return


    LEDintensity: 'Set intensity of all LEDs
    SlaveAddressWrite = $A0
    CommandByte = $01 'Set the Command Byte ($01 = Intensity10. Datasheet page 11)
    DataByte = Intensity '$FF 'Intensity of all segments set to maximum (Page 20)
    I2CWRITE SDA, SCL, SlaveAddressWrite, CommandByte, [DataByte] 'Write the data to the I2C-device
    I2CREAD SDA, SCL, SlaveAddressWrite, CommandByte, [RcvDataByte]
    for i = 0 to nAddress
    I2CWRITE SDA, SCL, SlaveAddressWrite, CommandByte, [DataByte] 'Write the data to the I2C-device
    I2CREAD SDA, SCL, SlaveAddressWrite, CommandByte, [RcvDataByte]
    SlaveAddressWrite = SlaveAddressWrite + $02
    NEXT i

    SlaveAddressWrite = $A0
    CommandByte = $02 'Set the Command Byte ($01 = Intensity10. Datasheet page 11)
    DataByte = Intensity '$FF 'Intensity of all segments set to maximum (Page 20)
    I2CWRITE SDA, SCL, SlaveAddressWrite, CommandByte, [DataByte] 'Write the data to the I2C-device
    I2CREAD SDA, SCL, SlaveAddressWrite, CommandByte, [RcvDataByte]
    for i = 0 to nAddress
    I2CWRITE SDA, SCL, SlaveAddressWrite, CommandByte, [DataByte] 'Write the data to the I2C-device
    I2CREAD SDA, SCL, SlaveAddressWrite, CommandByte, [RcvDataByte]
    SlaveAddressWrite = SlaveAddressWrite + $02
    NEXT i
    return

  15. #15
    Join Date
    Jan 2010
    Posts
    37


    Did you find this post helpful? Yes | No

    Default

    Hi RubenR!

    Can you post entire code you used to control MAX6953 driver?
    I try to use what is posted here but I have many error.
    Thank you very much

Similar Threads

  1. I2C Master/Slave 16F88/16F767 working code
    By DanPBP in forum Code Examples
    Replies: 2
    Last Post: - 23rd October 2012, 22:31
  2. Can't read sequential addresses in external EEPROM
    By tjkelly in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 18th February 2010, 14:46
  3. Problem with I2C EEPROM addressing
    By Atom058 in forum General
    Replies: 14
    Last Post: - 3rd November 2009, 03:17
  4. HARDWARE I2C SAMPLE CODE question
    By Michael Wakileh in forum Code Examples
    Replies: 2
    Last Post: - 16th June 2009, 21:07
  5. Pic16F628A and 24LC256 EEPROM I2C
    By Mike96 in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 1st January 2006, 03:13

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts