I2C with 16F628A mystery


Closed Thread
Results 1 to 18 of 18

Hybrid View

  1. #1
    Join Date
    Jun 2005
    Location
    Surrey, England
    Posts
    35


    Did you find this post helpful? Yes | No

    Default

    Actually I was wrong about the Addressing - I hadn't noticed you were using a 24C16 - I normally use larger chips - in fact the 24C16 needs a byte for the address. Unfortunately the addressing you require is a little more complex - the 2K memory is organised in 8 x 256 byte blocks and the A10, A9, A8 are conveyed as the lower 3,2,1 bits of the Control byte, and A7-0 in the Address byte - a rewrite of your addressing is needed!
    Control Byte: 1010XXX0 where XXX are the high order 3 bits of the address
    Address Byte: XXXXXXXX = A7-0
    You will need to create the Control byte for each successive write. Get back to me if you need any more help.
    Peter

  2. #2
    Join Date
    May 2009
    Location
    Montreal, QC, Canada
    Posts
    118


    Did you find this post helpful? Yes | No

    Default

    Ok so maybe I need more help.
    There is obviously something I don't understand.

    Looking at the 24CL16 datasheet:
    Name:  24cl16.png
Views: 1453
Size:  23.1 KB

    Based on this I changed the address to word and my understanding is:
    Control byte = 1010 000 0 = $A0
    I want to write $aa at address $400 so I wrote this code:

    Code:
    i2cdevice =$A0
    i2caddr = $400
    
        i2cwrite d1,d2,i2cdevice,i2caddr,[$aa]:pause 10
    I was expecting to see only address $400 showing value $aa but this is the result:
    Name:  pony3.png
Views: 1428
Size:  38.4 KB

    the value $aa is now showing at address $004 and at every next 16 locations all the way to 2048.

    ???

    Mike

  3. #3
    Join Date
    Jun 2005
    Location
    Surrey, England
    Posts
    35


    Did you find this post helpful? Yes | No

    Default

    I suggest you use a data array to send your bytes, and then you need to construct the ControlByte and address as in this example:
    Code:
    Dat         VAR byte[16]
    i           var word
    j           var Byte
    SDA         var PORTA.2
    SCL         VAR PORTA.3
    CntrB       var Byte
    Addr        var byte
        for i = 0 to 15
            lookup i, [$01,$01,$01,$3c,$3c,$3c,$3c,$3c,$3c,$08,$08,$08,$21,$21,$21,$FF], j
            Dat[i] = j
        next
        for i = 0 to $7F0 step 16  'End at 2048-16 = $7F0
            CntrB = %10100000
            CntrB.3 = i.10
            CntrB.2 = i.9
            CntrB.1 = i.8
            Addr = i.lowbyte
            i2cwrite SDA,SCL,CntrB,Addr,[str Dat\16]
            pause 10
        next
    Peter

  4. #4
    Join Date
    May 2009
    Location
    Montreal, QC, Canada
    Posts
    118


    Did you find this post helpful? Yes | No

    Default

    ok I have created a new file and inserted your code with some of my code required for access to the EEPROM but when I run this code nothing gets written to the chip.

    This is the complete code:
    Code:
    @ __config _INTOSC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _LVP_OFF & _CP_OFF
    clear
    DEFINE OSC 4
    TRISB = %00001000           
    CMCON = 7                   ; Disable comparator
    OPTION_REG = 0
    
    Activate    var PORTB.2     ; 1 = access eeprom / 0 = normal operation
    GO          VAR PORTB.3     ; Start switch
    OK          VAR PORTB.4     ; Green LED
    NOTOK       var PORTB.5     ; Red LED
    
    Dat         VAR byte[16]
    i           var word
    j           var Byte
    SDA         var PORTA.2
    SCL         VAR PORTA.3
    CntrB       var Byte
    Addr        var byte
    
    activate = 1
    
    
    
        for i = 0 to 15
            lookup i, [$01,$01,$01,$3c,$3c,$3c,$3c,$3c,$3c,$08,$08,$08,$21,$21,$21,$FF], j
            Dat[i] = j
        next
        for i = 0 to $7F0 step 16  'End at 2048-16 = $7F0
            CntrB = %10100000
            CntrB.3 = i.10
            CntrB.2 = i.9
            CntrB.1 = i.8
            Addr = i.lowbyte
            i2cwrite SDA,SCL,CntrB,Addr,[str Dat\16]
            pause 10
        next
    activate = 0   
    end
    I've been struggling with this almost nonstop for a couple of days and I believe that either I think I am working with a 24LC16 chip and it is not or I have a hardware issue. The EEPROM chip is not visually accessible but my PonyProg application is detecting it as"2416" - Device type "2402-16"
    This is my hardware and I ruled out any discrepancies between my drawing and actual PCB:
    Name:  hw.png
Views: 1773
Size:  19.5 KB

    Thanks for your time,

    Mike

  5. #5
    Join Date
    May 2009
    Location
    Montreal, QC, Canada
    Posts
    118


    Did you find this post helpful? Yes | No

    Default

    sorry, Your code did write to the chip, what I did was to zero out the complete memory using this code:
    Code:
    I2CAddr = $0
    I2CDevice = $A0
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[0]:i2caddr = i2caddr + 1:pause 10
    Then I ran your code (as previous post) and I see that it wrote value FF on every 16th location from memory 0 to 2032 as such:
    Name:  pony4.png
Views: 1476
Size:  27.6 KB

    Mike

  6. #6
    Join Date
    Jun 2005
    Location
    Surrey, England
    Posts
    35


    Did you find this post helpful? Yes | No

    Default

    I am not familiar with PonyProg, are you using the SI-Prog baseboard hardware and the I²CBus eeprom adapter - I note that the adaptor does not have any pullup resistors on SDA and SCL and the baseboard does not provide these either - You have implemented the R2/R3 4K7 pullups shown on your schematic, havent you?? I have had many frustrating experiences with I2C Memory chips instantly solved by a pair of pull up resistors.

    Failing this, I dont understand why the memory chip is visually inaccessible, but these results suggest you may not be dealing with a 24C16 chip - other chips may need different addressing.

  7. #7
    Join Date
    May 2009
    Location
    Montreal, QC, Canada
    Posts
    118


    Did you find this post helpful? Yes | No

    Default

    The chip is enclosed into a sealed device and the only thing exposed are the 4 pads for power and I2C. With trial and error... and trial and error over trial and error I managed to get what I need working. I know my program doesn't have much style but for now it does what it is supposed to do.

    The process of my program is as follow:
    When I press the switch I need to read address $04 and if it is > 5 it will flash the OK LED the number of the value found and then quit. If it is not greater than 5 then I want to set values $01,$01,$01,$3c,$3c,$3c,$3c,$3c,$3c,$08,$08,$08,$2 1,$21,$21,$FF all over.
    I don't understand why I just write once and the chip gets updated all over but it works.

    This device is hooked up to another device that will update the chip daily by setting address $04, $05, $06 to -1 each day.

    I am definitely going to order some chips and test on breadboard until I get a good understanding of this.
    In the mean time this is my working code:
    Code:
    @ __config _INTOSC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _LVP_OFF & _CP_OFF
    clear
    DEFINE OSC 4
    TRISB = %00001000           
    CMCON = 7                   ; Disable comparator
    OPTION_REG = 0
    
    
    SWSTAT      var byte
    Dat         VAR byte
    I           var byte
    I2CAddr     Var word
    I2CDevice   var byte
    D1          var PORTA.2     ; Cartrige white wire
    D2          VAR PORTA.3     ; Cartrage blue wire
    Activate    var PORTB.2     ; select between reset=1 normal=0
    GO          VAR PORTB.3     ; Start switch
    OK          VAR PORTB.4     ; Green LED
    NOTOK       var PORTB.5     ; Red LED
    
    activate = 0                ; Normal operation
    ok = 0                      ; Green LED off
    notok = 0                   ; Red LED off
    
    goto swstatus
    
    Start:
    
    ;--------make sure reset is needed-----------
    activate = 1                ; get ready to reset
    swstat = 0                  ; reset switch debounce
    pause 50                    ; give time or relay contact
    
    i2cdevice = $A1
    i2caddr = 3
    i2cread d1,d2,i2cdevice,i2caddr.lowbyte,[dat]
    pause 10
    
    if dat > 5 then
        for I = 1 to dat
            ok=1: pause 500:ok = 0:pause 500
        next
        activate = 0                    ;------Resume normal operation
        goto SwStatus
    else
    
        ok = 1: pause 3000: ok = 0  ; Green LED on for 3 seconds
        pause 5000
        I2CAddr = $0
        I2CDevice = $A0
    
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$01]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$01]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$01]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$3c]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$3c]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$3c]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$3c]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$3c]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$3c]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$08]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$08]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$08]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$21]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$21]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$21]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr.lowbyte,[$ff]:pause 10
    
    ;---------------------make sure data was written-------------------------
        i2cdevice = $A1
        i2caddr = 4
        i2cread d1,d2,i2cdevice,i2caddr.lowbyte,[dat]
        pause 10
        activate = 0                ;------Resume normal operation
        if dat = $3c then           ;------all is good, flash green LED
            for I = 1 to 10
                toggle ok
            pause 500
            next
            ok = 0
        else                        ;------Something wrong, flash red LED
            for I = 1 to 10
                toggle notok
                pause 500   
            next
            notok = 0
        endif
    endif
    
    SwStatus:
    if go = 0 then debounce
    swstat = 0
    goto SWstatus
    
    debounce:
    swstat = swstat + 1
    pause 10
    if swstat = 150 then start
    goto swstatus
    
    END
    Thank you for your help.

    Mike

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