I2C with 16F628A mystery


Closed Thread
Results 1 to 18 of 18
  1. #1
    Join Date
    May 2009
    Location
    Montreal, QC, Canada
    Posts
    118

    Default I2C with 16F628A mystery

    I am having some difficulty understanding the results I am getting, maybe it is due to something simple but I've been trying to figure it out for the past few hours.

    I am using 16F628A reading and writing to 24LC16 and displaying results on LCD.
    I am also using another application called PonyProg to read/write to my same EEPROM.

    So here is the story;
    I write to the 2416 these values:
    Code:
    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 back the values and display on the LCD in this way:
    Code:
    i2caddr = 0
    i2cread d1,d2,i2cdevice,i2caddr,[dat[0],dat[1],dat[2],dat[3],dat[4],dat[5],dat[6],dat[7],dat[8],dat[9],dat[10],dat[11],dat[12],dat[13],dat[14],dat[15]]
    pause 10
    errchk = 0
    for i = 0 to 15
        errchk = errchk + dat[i]
    next
        LCDOUT $FE,1
        lcdout $FE,$80,dec errchk: pause 3000
    Now I am expecting to get errchk = 741 but I get 716.
    I cycled through each value after the addition within the loop and the last number to add up is 230 although the value I wrote was $FF = 255

    Furthermore if I display on the LCD all values I see this:
    1113c3c3c3c3c
    3c888212121cc

    but $cc = 204

    Reading the content of 2416 with PonyProg shows properly:
    01 01 01 3c 3c 3c 3c 3c 3c 08 08 08 21 21 21 ff


    My code is not cleaned up because I was trying different ways but I always get to the same results I tried changing dat[] to word instead of byte but all the data gets messed up on the 2416.

    Code:
    @ __config _INTOSC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _LVP_OFF & _CP_OFF
    clear
    DEFINE OSC 4
    TRISB = 0                   ' Make PORTB all outputs
    CMCON = 7                   ' Disable comparator
    
    
    Dat         VAR byte[15]
    I           var byte
    D1          var PORTA.2
    D2          VAR PORTA.3
    I2CAddr     Var byte
    I2CDevice   var byte
    ERRchk      var word
    OK          VAR PORTA.4
    ;NOTOK       var PORTA.5
    ERRStatus   var bit
    
    LCD_DB4     VAR PORTB.7       ' Set port for 4 bits bus
    LCD_DB5     VAR PORTB.6
    LCD_DB6     VAR PORTB.5
    LCD_DB7     VAR PORTB.4
    LCD_RS      VAR PORTB.0       ' Set RS bit port
    LCD_E       VAR PORTB.1       ' Set Enable bit port
    LCD_Lines     CON 2         ' # of Lines on LCD,  1 or 2 (Note: use 2 for 4 lines)
    LCD_DATAUS    CON 50        ' Data delay time in us 
    LCD_COMMANDUS CON 2000      ' Command delay time in us 
    INCLUDE "LCD_AnyPin.pbp"    ' Must go after LCD initialization 
    Pause 500: LCDOUT $FE,1: pause 250   ' clear screen and relax
    
    Start:
    
    i2cdevice =160
    
    LCDOUT $FE,$80,"Start" 
    pause 500 
    
    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
    
    i2caddr = 0
    i2cread d1,d2,i2cdevice,i2caddr,[dat[0],dat[1],dat[2],dat[3],dat[4],dat[5],dat[6],dat[7],dat[8],dat[9],dat[10],dat[11],dat[12],dat[13],dat[14],dat[15]]
    pause 10
    errchk = 0
    for i = 0 to 15
        errchk = errchk + dat[i]
    next
        LCDOUT $FE,1
        lcdout $FE,$80,dec errchk: pause 3000
    
    
    if errchk = 741 then ERRStatus = 0
    i2caddr = 2032
    i2cread d1,d2,i2cdevice,i2caddr,[dat[0],dat[1],dat[2],dat[3],dat[4],dat[5],dat[6],dat[7],dat[8],dat[9],dat[10],dat[11],dat[12],dat[13],dat[14],dat[15]]
    pause 10
    Errchk = 0
    for i = 0 to 15
        errchk = errchk + dat[i]
       ; LCDOUT $FE,1
       ; lcdout $FE,$80,dec ERRCHK: pause 2000
    
    next
    if errchk = 741 and errstatus = 0 then 
        high ok
        pause 10000
        low ok
    else
    lcdout $FE,$C0,dec ERRCHK
    LCDOUT $FE,$80,hex dat[0],hex dat[1],hex dat[2],hex dat[3],hex dat[4],hex dat[5],hex dat[6],hex dat[7]    
    LCDOUT $FE,$C0,hex dat[8],hex dat[9],hex dat[10],hex dat[11],hex dat[12],hex dat[13],hex dat[14],hex dat[15]
    endif
    
    END
    Thanks for any help.

    Mike

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


    Did you find this post helpful? Yes | No

    Default

    Dat VAR byte[15]

    must be 16
    </pre>
    Steve

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

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


    Did you find this post helpful? Yes | No

    Default

    Hi Steve,

    Thank you...!

    I tried changing it to 16 and my total is now as expected = 741
    and also showing as FF on LCD.

    But why should it be 16?
    if Dat[0] is working then 0 to 15 = 16 addresses isn't it?


    Mike

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


    Did you find this post helpful? Yes | No

    Default

    an array that range from 0 to 15 is an array of 16 elements... hence the 16. Facile hein?
    Steve

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

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


    Did you find this post helpful? Yes | No

    Default

    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

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

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

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

  9. #9
    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: 1201
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: 1098
Size:  35.2 KB

    The more I test the more I get confused!

    Mike

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

  11. #11
    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: 1197
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: 1136
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

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

  13. #13
    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: 1524
Size:  19.5 KB

    Thanks for your time,

    Mike

  14. #14
    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: 1213
Size:  27.6 KB

    Mike

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

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

  17. #17
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Dave
    Always wear safety glasses while programming.

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


    Did you find this post helpful? Yes | No

    Default

    Hi Dave,

    I went a little too fast in my project, when I thought my circuit was good I built the PCB and dismantled my breadboard and its only after I saw this.

    But thanks for the info

    Mike

Members who have read this thread : 1

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