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

    Quote Originally Posted by lilimike View Post
    Ok that makes sens.

    Actually I am feeling kind of stupid right now!
    After a glass of wine I will be fine.

    Un gros merci!

    Mike
    BTW you defined I2CAddr as a byte, but treat it as a word (2048) - should be a word.
    Peter

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


    Did you find this post helpful? Yes | No

    Default

    This is an interesting observation, Thank you.

    I wonder why it still works though!

    Funny how sometimes a programming error is undetected by the compiler and then the program runs with unpredictable results and other times it just works!

    Mike

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


    Did you find this post helpful? Yes | No

    Default

    Further investigation has revealed why your checksum still worked.... (sorry for the rather brief earlier reply - it was from my mobile phone!). If we use the following code:
    Code:
    I2CAddr     Var byte
    Xray        var byte
    Alpha       var byte
    I2CAddr2    var byte
    I2CDevice   var byte
    
    I2cdevice =160
    I2CAddr2 = 0
    
    for i2caddr = 0 to 2048 step 16
        i2cwrite d1,d2,i2cdevice,i2caddr,[$55]
        hserout [hex I2CAddr, " "]
        pause 10
    next
    This reveals that with i2caddr as a byte, the for/next loop assigns the following values to I2CAddr:
    0 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0
    then stops (whereas as a word continues up to 800 as expected).
    So you are actually only writing to a memory address up to F0, but then reading back gives you the correct checksum. However where are you actually writing to memory? - Well the memory assignment by PBP is sequential in alphabetic order, words first then bytes, and the next byte after I2CAddr is in fact I2CDevice in your code, or in my modification, I2CAddr2, as is seen here:
    Code:
    _Alpha           		EQU	RAM_START + 018h
    _I2CAddr         		EQU	RAM_START + 019h
    _I2CAddr2        		EQU	RAM_START + 01Ah
    _I2CDevice       		EQU	RAM_START + 01Bh
    _Xray            		EQU	RAM_START + 01Ch
    Now the PBP manual states "The Address size sent (byte or word) is determined by the size of the variable that is used. If a byte-sized variable is used for the Address, an 8-bit address is sent. If a word-sized variable is used, a 16-bit address is sent. Be sure to use the proper sized variable for the device you wish to communicate with."

    I suspect this is in fact not correct and looking at the assembler code that PBP generates, in fact I2CWRITE seems to send a word, using I2CAddr, I2CAddr2 as the (word) address in my example, or the case of your code, actually I2CAddr, I2CDevice (=$A0) which is I suspect somewhere other than you intended in memory!
    Peter

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


    Did you find this post helpful? Yes | No

    Default

    Thank you Peter,

    I understand the first part of your response but not sure about the second part:
    Now the PBP manual states "The Address size sent (byte or word) is determined by the size of the variable that is used. If a byte-sized variable is used for the Address, an 8-bit address is sent. If a word-sized variable is used, a 16-bit address is sent. Be sure to use the proper sized variable for the device you wish to communicate with."

    I suspect this is in fact not correct and looking at the assembler code that PBP generates, in fact I2CWRITE seems to send a word, using I2CAddr, I2CAddr2 as the (word) address in my example, or the case of your code, actually I2CAddr, I2CDevice (=$A0) which is I suspect somewhere other than you intended in memory!
    I will continue to read it over and over, some times it takes me a few times to understand.

    Now again I am running into some mystery and I wish I could understand better...

    If I run this code:
    Code:
    i2cdevice =$A0
    for i2caddr = 0 to 2048 step 16
        i2cwrite d1,d2,i2cdevice,i2caddr,[$01]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$01]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$01]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$3c]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$3c]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$3c]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$3c]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$3c]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$3c]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$08]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$08]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$08]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$21]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$21]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$21]:i2caddr = i2caddr + 1:pause 10
        i2cwrite d1,d2,i2cdevice,i2caddr,[$ff]:pause 10
    next
    Then I read the EPROM with Ponyprog and observed everything as expected.
    Name:  pony1.png
Views: 1336
Size:  35.7 KB

    Then I rewrote my code by changing:
    Code:
    for i2caddr = 0 to 2048 step 16
    to
    Code:
    for i2caddr = 0 to 1024 step 16
    and the 3 first line I replaced $01 by $ff.

    I was expecting to see half of the memory filled with my changes but it got filled all the way to address $7FF:
    Name:  pony2.png
Views: 1233
Size:  35.2 KB

    The more I test the more I get confused!

    Mike

  5. #5
    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

  6. #6
    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: 1329
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: 1278
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

  7. #7
    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

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