I2C clock code with tiny problem


Closed Thread
Results 1 to 8 of 8
  1. #1
    Join Date
    Apr 2011
    Location
    Welches, Oregon
    Posts
    198

    Default I2C clock code with tiny problem

    I hope this day finds you well.

    Armed with the information I gained in my last post (thank you again), I set about putting it to use in the following code. I think that it is a good beginner project - a clock that uses the popular DS series I2C chip and is very simple in hardware by displaying to the debug window rather than some complicated interface. Unlike many I have seen posted, the complete code for buttons is included and to the best of my ability it is commented and tested to function in every regard - except one: It doesn't work.

    Enjoy your laugh at my chagrin, as I have! Then, wipe the tear from your eye and consider my problem, if you please.

    The clock starts by displaying the special and status registers, writes to them and reads back the values without flaw.
    It then initialized each day and date register with it's hex value ($00 is written to seconds, $01 to minutes, $02 to hours...). This also works well and displays as expected.

    Clock display outputs as it should.

    Each of the three buttons work as I intended: Press "1" to enter the adjustment routines, "2" to advance though the registers, and "3" to advance through valid values. "1" again writes the new register value to the clock chip and, in a few seconds without input, at any point, the routines abort appropriately.

    Almost perfect, except the clock value never advances - stubbornly remaining precisely as set. I believe that in my fumbling attempts to "pull up" the heartbeat signal I may have damaged the clock chip. I haven't another and so expose my ineptitude in hopes of avoiding the delay of ordering another (or at least verifying such a delay is unavoidable) by asking for help - either by hardware test or simulation to determine I have not a code error. Is that possible? If so, thank you.

    Code:
    '****************************************************************
    '*  Name    : 3 BTN CLOCK.BAS                                   *
    '*  Author  : [AMOQUE]                                          *
    '*  Notice  : Copyright (c) 2013 [PBP 2.6]                      *
    '*          : All Rights Reserved                               *
    '*  Date    : 10/21/2013                                        *
    '*  Version : 1.0                                               *
    '*  Notes   : 16F88, DS1337 or equivalent,                      *
    '*          : 3 BUTTONS - ACTIVE HIGH                           *
    '****************************************************************
    
    #CONFIG
       __config _CONFIG1, _INTRC_IO & _WDT_OFF & _PWRTE_OFF & _MCLR_ON & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _WRT_PROTECT_OFF & _DEBUG_OFF 
       __config _CONFIG2, _FCMEN_OFF & _IESO_OFF  
    #ENDCONFIG
    DEFINE OSC 8
    
    '-----DEBUG (SERIAL) SETUP----------------------------------------
    DEFINE DEBUG_REG PORTB
    DEFINE DEBUG_BIT 5
    DEFINE DEBUG_BAUD 2400
    DEFINE DEBUG_MODE 0
    
    '-----CHIP REGISTER SET-UP----------------------------------------
    TRISA = %00000000      ' Set PORTA output
    TRISB = %00001101                                                      
    OSCCON = %01110000
    CCP1CON = %00001100
    T2CON = %00000101
    'ADCON0 = %11000000      ' Configure and turn on A/D Module
    'ADCON1 = %10000000      ' Set PORTA analog and LEFT justify result
    'ANSEL = %00000011
    
    '-----PORT SET-UP-------------------------------------------------   
    SDA  VAR PORTB.1
    SCL  VAR PORTB.4
    BTN1 VAR PORTB.0
    BTN2 VAR PORTB.2
    BTN3 VAR PORTB.3
    
    '-----CLOCK SET-UP------------------------------------------------
    RTC_ADD CON %11010000
    REG_TIM CON $00
    REG_AL1 CON $07		' Not implemented 
    REG_AL2 CON $0B		' Not implemented
    REG_SPC con $0E
    REG_STS CON $0F
    
    '-----TIME/ CLOCK VARIABLES----------------------------------------
    REG_MIN VAR BYTE[7]     ' Minimum register values
    REG_VAL VAR Byte[7]	    ' Seconds, minutes, hours, day of week, date, month, year
    REG_MAX VAR BYTE[7]     ' Maximum register values
    ACT_REG VAR BYTE        ' Active register (setting)
    
    '-----GENERAL USE VARIABLES---------------------------------------
    LP VAR BYTE             ' For/ Next value
    D0 VAR BYTE
    D1 VAR BYTE
    D2 VAR BYTE
    
    '-----INITIALIZE CLOCK--------------------------------------------
    'CHECK STATUS
    debug "---STABALIZE---", 10
    pause 250
    D0 = $00 : D1 = $00
    gosub SPCL_READ
    D0 = $00 : D1 = $00    ' Assign 'special' registers
    gosub SPCL_WRITE       ' Write 'special' registers
    gosub SPCL_READ        ' Verify
    
    'SET INITIAL TIME
    FOR lp = 0 TO 6        ' For each register
      REG_VAL[LP] = LP     ' Set value to address
    NEXT LP                ' Loop
    '----------------------' Alarm set-up
    GOSUB CLK_WRITE        ' Write initial values and start clock
    
    'LOAD REGISTER MIN/ MAX VALUES
    REG_MIN[0] = 00: REG_MIN[1] = 00: REG_MIN[2] = 00: REG_MIN[3] = 1: REG_MIN[4] = 01: REG_MIN[5] = 01: REG_MIN[6] = 00
    REG_MAX[0] = 59: REG_MAX[1] = 59: REG_MAX[2] = 23: REG_MAX[3] = 6: REG_MAX[4] = 31: REG_MAX[5] = 12: REG_MAX[6] = 99
    
    
    '+++++MAIN LOOP+++++++++++++++++++++++++++++++++++++++++++++++++++
    MAIN:
      if BTN1 then goto CLK_SET          ' Button 1 = Enter set mode  
      GOSUB CLK_READ:                    ' Read clock
      PAUSE 500                          ' Pause 
    GOTO MAIN                            ' Loop til the end of time (lol)
    
    
    
    '-----SUB-ROUTINES------------------------------------------------
    'READ TIME, CONVERT TO DECIMAL VALUES, DISPLAY
    CLK_READ:
      I2CRead SDA, SCL, RTC_ADD, REG_TIM, [REG_VAL[0], REG_VAL[1], REG_VAL[2], REG_VAL[3], REG_VAL[4], REG_VAL[5], REG_VAL[6]]
      FOR LP = 0 TO 6			' For each register
        D0 = (REG_VAL[LP] >> 4) * 10	' Decode 10's digit
        D1 = REG_VAL[LP] & %0001111		' Blank 10's, get 1's
        REG_VAL[LP] = D0 + D1 		    ' Write Decimal value to register
        NEXT LP				            ' Next register
      DEBUG "TIME:[", dec1 REG_VAL[3], "]  ", dec2 REG_VAL[5], "/", dec2 REG_VAL[4], "/", dec2 REG_VAL[6], "  ", dec2 REG_VAL[2], ":", dec2 REG_VAL[1], ":", 
    
    dec2 REG_VAL[0], 10
    Return
    
    'CONVERT TO BCD VALUES, WRITE TO CLOCK REGISTERS
    CLK_WRITE:
      FOR LP = 0 TO 6			        ' For each register
        D0 = REG_VAL[LP] / 10		    ' Get decimal 10's digit
        D1 = REG_VAL[LP] // 10 		    ' Get decimal 1's
        REG_VAL[LP] = (D0 << 4) + d1	' Shift BCD 10's in, add 1's
      NEXT LP				' Next register
      I2CWrite SDA, SCL, RTC_ADD, REG_TIM, [REG_VAL[0], REG_VAL[1], REG_VAL[2], REG_VAL[3], REG_VAL[4], REG_VAL[5], REG_VAL[6]]
      GOSUB CLK_READ			        ' Update display
    Return
    
    'SPECIAL REGISTERS--------------------------------------------------------------
    SPCL_WRITE:
      I2CWrite SDA, SCL, RTC_ADD, REG_SPC, [D0, D1]   
    Return
    
    SPCL_READ:
      I2CRead SDA, SCL, RTC_ADD, REG_SPC, [D0, D1]
      debug "SPCL: [", bin8 D0, "] STATUS: [", BIN8 D1, "]", 10, 10
      pause 1000   
    Return
    
    'BEGIN SET ROUTINE--------------------------------------------------------------
    CLK_SET:
      debug "SET TIME", 10              ' Announce in debug window
      For LP = 0 to 100                 ' Start timer loop
        IF BTN2 Then Goto SELECT_REG    ' Button 2 = select register
        Pause 100                       ' Advance time
      NEXT LP                           ' Loop
      GOTO MAIN                         ' Time expired, drop out
       
    'SELECT REGISTER
    SELECT_REG:
       debug "SELECT REGISTER" , 10
       ACT_REG = 0 : D2 = 0                         ' Reset active register
       For LP = 0 to 100                            ' Start timer loop
         IF BTN2 Then                               ' Button 2 press
           ACT_REG = ACT_REG + 1                    ' Advance active register
           LP = 0                                   ' Restart time loop
           IF ACT_REG > 6 THEN ACT_REG = 0          ' Keep register number in bounds
           DEBUG "EDIT=", DEC1 ACT_REG, "   MAX="   ' Announce register and max value to debug
           debug DEC2 REG_MAX[ACT_REG], 10      
         Endif
         If BTN3 Then                               ' Button 3 press
           debug "SET REGISTER VALUE" , 10          ' Announce to debug
           LP = 0                                   ' Restart time loop
           Goto ADV_VALUE                           ' Goto advance register value routine
         Endif                                      ' End button 3 loop
         Pause 100                                  ' Advance time
       NEXT LP                                      ' Loop
       GOTO MAIN                                    ' Time expired, drop out
       
    'ADVANCE REGISTER VALUE
    ADV_VALUE:
      debug "ADVANCE REGISTER VALUE" , 10
      for LP = 0 to 100                                                    ' Announce to debug
        IF Btn3 Then                                                       ' Button 3 press
          LP = 0                                                           ' Restart time loop
          D2 = D2 + 1                                                      ' Advance register value
          IF D2 > REG_MAX[ACT_REG] THEN D2 = REG_MIN[ACT_REG]              ' Keep register value in bounds
          debug "REG=", DEC2 ACT_REG, "   NEW VALUE=", DEC2 D2 , 10        ' Announce to debug
        ENDIF                                                              ' End button 3 press
        IF BTN1 Then                                                       ' Button 1 press
          debug "WRITE VALUE TO CLOCK" , 10                                ' Announce to debug
          LP = 0                                                           ' Restart timer
          GOSUB CLK_READ                                                   ' Read fresh clock values 
          REG_VAL[ACT_REG] = D2                                            ' Insert new value
          GOSUB CLK_WRITE                                                  ' Write to chip
          GOTO SELECT_REG                                                  ' Goto 'select register'
        EndIF                                                              ' End button 1 press
        Pause 100                                                          ' Advance timer
      Next LP                                                              ' Loop
      GOTO MAIN                                                            ' Time expired, drop out
    
    END

  2. #2
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default Re: I2C clock code with tiny problem

    You have pullup resistors on I2C lines?
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  3. #3
    Join Date
    Apr 2011
    Location
    Welches, Oregon
    Posts
    198


    Did you find this post helpful? Yes | No

    Default Re: I2C clock code with tiny problem

    Yes, I have verified the hardware again and again. In fact, early iterations worked quite well - the clock advancing for long periods as I worked through writing code, loading new many times. Then, as if choosing death over submission, it simply died.

  4. #4
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,614


    Did you find this post helpful? Yes | No

    Default Re: I2C clock code with tiny problem

    just if ... by greatest hazards ...

    DS1337C ONLY
    The DS1337C integrates a standard 32,768Hz crystal in the package. Typical accuracy at nominal VCC and +25°C is approximately +10ppm. Refer to Application Note 58 for information about crystal accuracy vs. temperature.
    that checked ...


    Bit 7: Enable Oscillator (EOSC). This active-low bit when set to logic 0 starts the oscillator. When this bit is set to logic 1, the oscillator is stopped. This bit is enabled (logic 0) when power is first applied
    that states the device should run by itself @ power up ...

    IF it's not accidentally overwritten ...

    now ... did you notice the very low Xtal charge capacitance value ???

    Alain
    Last edited by Acetronics2; - 25th October 2013 at 17:30.
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  5. #5
    Join Date
    Apr 2011
    Location
    Welches, Oregon
    Posts
    198


    Did you find this post helpful? Yes | No

    Default Re: I2C clock code with tiny problem

    With each post I, again, verify without prejudice. Chip is DS1337, "Special" registers report valid (functioning) values before being written, and verify valid values after first write (as described in RTFM). I did not notice low capacitor values, rather stuck a crystal in the appropriate holes without consideration for any value but frequency, yet it has worked without glitch for several days until after I thought I loaded "perfect" version of code.

    I will see what I can do with that... though ordering crystals is as time consuming as ordering chips and, I still don't know if/ why it worked so well and stopped so suddenly.

  6. #6
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,614


    Did you find this post helpful? Yes | No

    Default Re: I2C clock code with tiny problem

    after years ( or not ! ) Xtals die without any announcements ...

    I already experienced that ... ( with R/C Models : Ayayayay ... )

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  7. #7
    Join Date
    Apr 2011
    Location
    Welches, Oregon
    Posts
    198


    Did you find this post helpful? Yes | No

    Default Re: I2C clock code with tiny problem

    I double checked both RTFM and crystal specs; they match, but as a precaution, I replaced it... and perfect! Time advances normally. Perhaps static? One again, I am stymied by the smallest thing, but different eyes (or minds) offer resolution. Thank you again, good to know my coding is correct.

    All the best--

    Amoque

  8. #8
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default Re: I2C clock code with tiny problem

    Quote Originally Posted by Acetronics2 View Post
    after years ( or not ! ) Xtals die without any announcements ...

    I already experienced that ... ( with R/C Models : Ayayayay ... )

    Alain
    Good information to know, thanks Alain.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

Similar Threads

  1. i2c clock speed on 16F887
    By robertpoll in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 29th April 2010, 09:52
  2. Tiny Bootloader 18F2420
    By ultiblade in forum mel PIC BASIC Pro
    Replies: 11
    Last Post: - 31st March 2010, 17:32
  3. I2C function... clock pin?
    By Qacer in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 2nd February 2006, 22:09
  4. I2C clock frequency?
    By Qacer in forum Serial
    Replies: 8
    Last Post: - 27th January 2006, 14:40
  5. Tiny bootloader and 18F4525
    By Najim in forum Off Topic
    Replies: 1
    Last Post: - 11th January 2006, 11:43

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