i2c PBP questions


Closed Thread
Results 1 to 15 of 15
  1. #1
    Join Date
    Jan 2007
    Location
    Toronto
    Posts
    11

    Default i2c PBP questions

    Hi:

    I have read through several posts on the forum regarding i2c, and I have read the information in the PBP manual.

    I have used the following code:
    ADDR var byte
    ADDR = $07
    GOSUB TIME_125
    I2CWRITE PORTC.4,PORTC.3,$A0,ADDR,[7]
    GOSUB TIME_125

    I2CREAD PORTC.4,PORTC.3,$A0,ADDR,[i2c_Data],Fail
    GOSUB TIME_125

    TIME_125:
    FOR Counter = 1 TO 125
    Counter = Counter + 1
    NEXT Counter
    RETURN
    ;

    to try to talk to a 24AA512 EEPROM.

    I have an ICD connected and single stepped my way through the code and followed the assembler code as it runs.

    I have confirmed with my meter on the chip pins (and leds on SDA SCL) that I am getting the signals to the EEPROM.

    I do not appear to be writing and i2c_Data in the read statement returns 0.

    I am clearly missing something, but I am not sure what it is.

    For this project which is a proto-typer based on a 16F877A, I will also be using i2c to talk to a DS1631 temperature sensor and a DS1307 RTC.

    I have a working LCD and 4 7 segment displays working through a MAX7219. My next phase was to get the i2c going before moving on to the One_Wire and iButton devices.

    Any suggestions on how to set up the i2c properly would be greatly appreciated.

    Thanks

    Tim

  2. #2
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    ADDR MUST be a WORD sized variable.

    Make sure you're using < 4.7K pull-up resistor
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  3. #3
    Join Date
    Jan 2007
    Location
    Toronto
    Posts
    11


    Did you find this post helpful? Yes | No

    Default i2C and EEPROM

    Thanks Steve:

    I will change ADDR to be "Word". Is it acceptable to just say $07 as the address I want to write to?

    The data sheet for the EEPROM states that it is expecting the Address High after it acknowledges the Start condition.

    It is written as "high-order byte of the word address and will be written into the Address Pointer" Is the address pointer the location that I intend to write to? It then says that the next byte (2nd half of address word) is the least significant address byte. It does not say what this represents.

    The EEPROM has memory addressing from $0000 - $FFFF. Should my $07 as a target address go in as $0700 and then 0000 as the second half of the word?

    Confused,

    Tim

  4. #4
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    When you write ADDR=$07 or ADDR=$7, it store $0007 to the word variable in one shot...If you prefer in the MSB and LSB. have Look to your EEPROM datasheet...
    http://ww1.microchip.com/downloads/e...doc/21754E.pdf

    Look Figure 6-1. What happen if your address variable is a byte? Yes it miss the LowByte of the address. Using a word sized variable, nothing is missing.

    Nothing else to worry about, I2CREAD/WRITE will do the job for you.

    P.S. : Welcome on the forum Yet another Canadian Woohoo !!!
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  5. #5
    Join Date
    Jan 2007
    Location
    Toronto
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Hi Steve:

    Thanks for the response. Happy to strengthen the Canadian contingent

    I am sitting here watching the program run on the ICD. I wish they went faster.

    I will confirm that the address stuff is exactly as you said. I watched 8 0s get fed before it put in my address and I am now watching shift my address across.

    From what I can see, everything is working properly.

    When I let it run, I am expecting to see the number contained in the [] brackets on the write statement returned in my byte i2c_Data which is in the [] brackets in my read statement.

    If this correct?

    The read statement does not hit the "Fail" after the [] so that would imply that the program is "running".

    Tim

  6. #6
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Running or at least it says that there's something on the I2C lines.

    If you really want to know if it's working, you could still write to the EEPROM, then read back the data, if both are the same... it confirm it's working.. just fine.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  7. #7
    Join Date
    Jan 2007
    Location
    Toronto
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Hi Steve:

    Well that is my big question in my previous response. If this was doing what it is supposed to be doing, would I not see the result in my i2c_Data variable?

    ADDR var word
    ADDR = $07
    PAUSE 10
    I2CWRITE PORTC.4,PORTC.3,$A0,ADDR,[1]
    PAUSE 10

    I2CREAD PORTC.4,PORTC.3,$A0,ADDR,[i2c_Data],Fail
    PAUSE 10

    GOTO MAIN

    Fail:
    PORTC.5 = 1
    GOTO MAIN

    I would expect i2c_Data to contain "1"

    It does not.

    Am I giving everything enough time?

    Thanks

    Tim

  8. #8
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Try this one, it's working here
    Code:
    define LOADER_USED 1
    disable debug
    Data_READ   var byte
    Data_Write  var byte
    Bad         var bit
    ADDR        var word
    SDA         var PORTC.4
    SCL         var PORTC.3
    Control     con $A0
    
    Bad = 0
    
    Start:
        For addr=0 to $FFFF
            
            data_write=addr.lowbyte
            bad = 0
            I2CWRITE sda,scl,control,ADDR,[data_write]
            PAUSE 10 
    
            I2CREAD sda,scl,control,ADDR,[Data_read]
            enable debug
                data_read=data_read ' refresh ICD display
            disable debug
            if data_read != data_write then bad=bad +1
    
            next
        GOTO Start
    Last edited by mister_e; - 2nd February 2007 at 04:09.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  9. #9
    Join Date
    Jan 2007
    Location
    Toronto
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Hi Steve:

    Thanks for posting the code. How long should this take to complete? I can see that it is cycling through addresses 0 to $FFFF. I put in a line between the next and GOTO Start to light up one of the status LEDs I have on the board.

    It is not lighting up. In the watch window, Data_READ is blank. When I pause the program, I am in the library PBPPIC14.LIB stuck in the PAUSE routine waiting for the carry bit to be cleared. This bit does not get cleared.

    I just thought of something. I have no includes in my program as I normally did with assembler. I am just starting out with PBP.

    Am I perhaps not adding some includes that I need?

    I didn't see a list in the manual anywhere of any special requirements that have to be in the code. I don't have a device include either.

    Please advise


    Thanks

    Tim

  10. #10
    Join Date
    Jan 2007
    Location
    Toronto
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Hi:

    Some further information for clarity. I am working from MPLAB and the debugger is the ICD 2.

    Tim

  11. #11
    Join Date
    Jan 2007
    Location
    Toronto
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Hi:

    An update on the current state of affairs.

    I have an LCD hooked up and sitting idle. Perhaps I can just write out different values during the program execution to see what is going on.

    Later

    Tim

  12. #12
    Join Date
    Jan 2007
    Location
    Toronto
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Ok, Here's the bad news.

    By writing "data_write" to the LCD, I can see the data is being sent.

    By writing "bad" to the 2nd line, I can see that it is returning a 1 for each of the 64 loops.

    I am certain that I have not write protected the 24AA512. I think it's time to pull the EEPROM and see if I can talk to the DS1307.

    If I can, it would seem the EEPROM is not happy. If I can't talk to the DS1307, I have a bigger problem.

    Do I have to set i2c_slow? anywhere, or is that the default.

    Later

    Tim

  13. #13
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    This device support high speed I2C clock... no need too add I2C_SLOW define.

    Double check that you didn't revert SDA & SCL and that you have place 1 pull-up (4.7k or lower) on SDA and SCL lines.

    Forget the ICD stuff and try this one
    Code:
            '
            '       Device configuration fuses
            '       ==========================
            '       4MHz Clock     ---------> XT
            '       WatchDog Timer ---------> ON
            '       PowerUp Timer  ---------> ON
            '       BrowOut Detect ---------> ON      
            '       LowVoltage programming -> OFF
            '
            @   __CONFIG _XT_OSC & _WDT_ON & _PWRTE_ON & _BODEN_ON & _LVP_OFF 
            '
            '       ---------------------------------------------------------------
            '       If you're using PM assembler, you must change the above line 
            '       for the following
            '
            '       @   DEVICE PIC16F877A, XT_OSC, WDT_ON, PWRT_ON, BOD_ON, LVP_OFF
            '       ---------------------------------------------------------------        
    
            '       
            '       Hardware configuration
            '       ======================
                    '
                    '   I/O PORT
                    '   --------
            TRISC = %10000000
            TRISD = 0
            TRISE = 0
                    '
                    '   USART
                    '   ----- 
                    '   Baudrate = 19200                  
                    '
            DEFINE HSER_RCSTA 90h               ' Enable serial port & continuous receive
            DEFINE HSER_TXSTA 24h               ' Enable transmit, BRGH = 1
            DEFINE HSER_SPBRG 12                ' 19200 Baud @ 4MHz, 0.16%
                    '
                    '   ADC
                    '   ---
            ADCON1 = 7                          ' set all related i/o to digital
            
            '
            '       Hardware assignments
            '       ====================
                    '
                    '   I2C BUS
                    '   -------
                    '   4.7K (or less) pull-up resistor on SDA & SCL line
                    '   
                    '   24LC512 
                    '   -------
                    '   A0 - A2 pin -> GND 
                    '   WP pin ------> GND  
                    '
            SDA var PORTC.4                     ' I2C bus SDA line 
            SCL var PORTC.3                     ' I2C bus SCL line
                    '   
                    '   LCD
                    '   ---
                    '   4 bits mode
                    '   Data DB<7:4> -> PORTD<7:4>
                    '   RS -----------> PORTE.0
                    '   E ------------> PORTE.1
                    '   R/W ----------> GND
                    '   Vo -----------> 10-20K Trim pot wiper
                    '
            DEFINE LCD_DREG PORTD               ' LCD data port
            DEFINE LCD_DBIT 4                   ' LCD data starting bit
            DEFINE LCD_RSREG PORTE              ' LCD register select port
            DEFINE LCD_RSBIT 0                  ' LCD register select bit
            DEFINE LCD_EREG PORTE               ' LCD enable port
            DEFINE LCD_EBIT 1                   ' LCD enable bit
            DEFINE LCD_BITS 4                   ' LCD data bus size
            DEFINE LCD_LINES 2                  ' Number lines on LCD
            DEFINE LCD_COMMANDUS 2000           ' Command delay time in us
            DEFINE LCD_DATAUS 50                ' Data delay time in us
    
            '
            '       Internal EEPROM assignement
            '       ===========================
            data @0, "Good",13,10
            data     "Bad ",13,10   
                
            '
            '       Variable definition
            '       ===================
            ADDR            var word               
            Data_READ       var byte               
            Data_Write      var byte               
            IsBad           var bit
            TotalBad        var word
            PicEepromAddr   var byte
            Char            var byte
                        
            '
            '       Software constants
            '       ==================                
            Control         con $A0             ' 24LC512 control byte 
                        
            '
            '       Program start
            '       =============
                    '
                    '   Hardware and software initialisation
                    '   ------------------------------------
            PORTC = 0 
            PORTD = 0
            PORTE = 0 
            clear                               ' clear all variable
            pause 500                           ' LCD start-up delay
            lcdout $FE,1                        ' clear LCD
                        '       
                        '       Send repport header via serial communication
                        '       --------------------------------------------
            hserout ["    ADDR    Data_Write    Data_READ    Good/Bad",13,10,_
                     "    ----    ----------    ---------    --------",13,10]    
    
                    '
                    '       EEPROM write, read & test loop           
                    '       ------------------------------
                    '       1) write to EEPROM the LowByte value of current
                    '          address (ADDR) value.
                    '
                    '       2) read it back and compare results
                    '               case it's different: 
                    '                   set 'IsBad' flag bit
                    '                   increment 'TotalBad' variable value
                    '
                    '       3) Show results on LCD
                    '
                    '       4) Send results via serial communication @ 19200 bauds 
                    '   
            For addr=0 to $FFFF
                IsBad=0                         ' set as good results
                                                
                data_write=addr.lowbyte         ' get the LowByte of current EEPROM
                                                ' address
                                                
                I2CWRITE sda,scl,control,ADDR,[data_write] : PAUSE 5 
                                                ' send it to the EEPROM and
                                                ' wait max Twc delay
                                                
                I2CREAD  sda,scl,control,ADDR,[Data_read]
                                                ' read the current data 
                                                ' at the current address
                                                
                if data_read != data_write then ' data stored is different?
                                                '    YES!
                    IsBad  = 1                  '    set bad result flag
                    totalbad = totalbad + 1     '    increment total of bad result
                    endif                       
                        '
                        '       Show data on LCD
                        '       ----------------
                lcdout $FE,2,"W:",hex4 data_write,"   R:",hex4 data_read,_    
                       $FE,$C0,"TotalBad=", dec totalbad                        
                        '
                        '       Send data via serial communication
                        '       ----------------------------------
                                '
                                '   Show : Current address
                                '          Data_Write 
                                '          Data_read
                                '
                hserout [rep " "\4,hex4 addr, rep " "\7, hex4 data_write ,_
                         rep " "\10,hex4 Data_read,rep " "\8]
                                '
                                '   Show if the actual reading is "Good"
                                '   or "Bad"
                                '
                for piceepromaddr=(IsBad*6) to ((IsBad*6)+5)
                    read piceepromaddr, char    ' read character from PIC EEPROM
                    hserout [char]              ' send it
                    next
                                                  
                next        
                    '
                    '       *******************************
                    '       *    the whole job is done    *
                    '       *******************************
                    '
                    '       Show the amount of bad results
                    '       ------------------------------
            hserout [rep " "\4,rep "="\43,13,10,_
                     rep " "\4,"TotalBad = ",dec totalbad,13,10]
                     
            lcdout $FE,1,"TotalBad=",dec totalbad
    
    SpinHere:
            goto spinhere                       ' spin in round forever
    Last edited by mister_e; - 3rd February 2007 at 15:09.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  14. #14
    Join Date
    Jan 2007
    Location
    Toronto
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Hi Steve:

    Thanks for the suggestions and the code. I am just building my proto type board, and so far, I have the LCD working and 2 dual segment 7 segment displays running off a MAX7219. That is all that is working at this time. I am trying to get the i2c working next.

    I do not have the rs232 link working yet, so I can't implement your suggestion below.

    I have confirmed the SDA and SCL connections at the IC with a meter on the pin while single stepping the code. I am getting 2.03 volts at both SDA and SCL and I do have a 4k7 resistor on each line.

    The ICD 2 is both my debugger and my programmer and it is my only interface to the 16F877a at the moment.

    I will check all the wiring as I have prewired the DS1307 and DS1631 sockets. They checked out with a meter when I tested SDA and SCL, but I will have a close look again.

    thanks

    tim

  15. #15
    Join Date
    Jan 2007
    Location
    Toronto
    Posts
    11


    Did you find this post helpful? Yes | No

    Default

    Hi:

    I did some rewiring as I have found in the past that a particular type of 8 pin socket that seems to be the only kind I can get has caused me problems. I wired an 18Pin socket of the type I like for the 24AA512 and the DS1307.

    As embarrassing as it is, since this is a forum and a post that someone else might read and benefit from, here is some information that should be checked. (And more than once it seems)

    Pin 7 on the EEPROM is WP (Write Protect). If it is high, you cannot write to the EEPROM. I had missed the mark by one tiny little hole on my proto board and wired WP high.

    I discovered this after rewiring to the new socket and having the same problem writing to the EEPROM. This time, I had forgotten to add the wire for WP at all. I measured with the meter and found that if left floating, WP will be high.

    I destroyed the EEPROM by accidently by taking too long to clear a solder bridge with the iron when trying to wire WP low.

    So, I have moved on the the DS1307 RTC. I have yet to read back the config properly (I get "16") when I send the value LCDOUT, $FE, $80, #CONFIG where "CONFIG" is the value sent after Year to address $07. I think that is telling me that I am reading "FF" from the config register which I know from previous experience is telling me that I am not talking to the DS1307.

    It was getting late, and I packed it in. I will have another look at it tonight.

    Sorry to have missed the WP on the EEPROM. Too bad I burned it out. I was hoping for the best.

    If I can't get the DS1307 to run properly, I will move on to the One-Wire phase of bringing the board on line. Hopefully that will not be a difficult as the i2c has been

    thanks for the help

    Tim

Similar Threads

  1. explanation on I2C command (PBP)
    By F1CHF in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 12th May 2014, 06:30
  2. I2C Master/Slave 16F88/16F767 working code
    By DanPBP in forum Code Examples
    Replies: 2
    Last Post: - 23rd October 2012, 23:31
  3. HARDWARE I2C SAMPLE CODE question
    By Michael Wakileh in forum Code Examples
    Replies: 2
    Last Post: - 16th June 2009, 22:07
  4. I2C Master Slave issues.
    By cpayne in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 29th March 2008, 20:33
  5. Still new to PicBasic - i2c questions
    By cometboy in forum mel PIC BASIC
    Replies: 4
    Last Post: - 13th November 2006, 19:27

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

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