DS1337 - 12h to 24h mode


Closed Thread
Results 1 to 31 of 31

Hybrid View

  1. #1
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    Did you find this post helpful? Yes | No

    Default Re: DS1337 - 12h to 24h mode

    I would eliminate the key presses for testing. Setup a pause in your main loop and a just change a new bit variable to mimic the key press action. Just to isolate where the issue may be.

    Something like.
    Keypressbit var bit

    Keypressbit = 0

    Mainloop:
    Pause 1500
    If Keypressbit = 1 then
    ......... Etc

    ' at the end of Mainloop
    Keypressbit = ~ Keypressbit
    Pause 2000 ' 2 second pause
    GOTO Mainloop

    Btw, ! hourmode should have been ~ hourmode (bit wise not)

    Good luck
    Regards,
    TABSoft

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,644


    Did you find this post helpful? Yes | No

    Default Re: DS1337 - 12h to 24h mode

    the code by tabsoft works fine with a ds1307 and the double write is not needed , I have not got a 1337 to test

    Code:
    ' pic16f688
     #CONFIG
           __config _INTRC_OSC_NOCLKOUT & _CP_OFF & _WDT_OFF  &  _PWRTE_ON  &  _MCLRE_ON  & _BOD_ON    &  _BOR_ON
     #ENDCONFIG
      
      
    
            DEFINE OSC 8                 
           DEFINE NO_CLRWDT 1
            CRC VAR BYTE   BANK0 SYSTEM    'CRC
            
                SDApin   var PORTC.0                'SDA
                SCLpin   var PORTC.1               'SCL 
               
                tmp var byte
                pkt var byte[11]
     rtcAMPM   var bit   ' Storage flag to indicate AM or PM ; 0=AM, 1=PM
     hourmode  var bit   ' Storage flag for RTC 12/24 hour mode ; 0=24Hr, 1=12Hr
     BCDResult var byte  ' Storage for temporary result for BCD Conversions
     RTCHour    var byte
              osccon=$70    '8 mhz
              ansel=0       'dig i/o
              CMCON0=7        ' compare off 
                     trisc=%100000
      portc=3
      pause 10
    
    
    i2cwrite  sdapin,sclpin,$D0,0,[$0,$14,$21,3,$14,1,$14]  'SANE TIME AND DATE  
    'i2cwrite  sdapin,sclpin,$D0,0,[0]
     pause 3000  
             serout2 porta.0,84, ["ready",13,10]  
    main:
    
      i2cREAD  sdapin,sclpin,$D0,0,[str pkt \3 ]
          RTCHour = pkt[2]
       if  RTCHour.6 then
       serout2 porta.0,84, [hex2 (pkt[2]&$1f),":",hex2 pkt[1],":",hex2 pkt[0]] 
        if   RTCHour.5 then serout2 porta.0,84, [" pm" ]
         serout2 porta.0,84, [13,10] 
       
       else
       serout2 porta.0,84, [hex2 pkt[2],":",hex2 pkt[1],":",hex2 pkt[0],13,10] 
       endif
        pause 5000
      gosub ampm  
       goto main
       
    ampm:
    
       I2CRead SDApin,SCLpin,$D0,$02,[RTCHour]
       hourmode = RTCHour.6
       if hourmode = 1 then          ' Is the RTC set for 12-hour mode
        rtcAMPM = RTCHour.5          ' Assign AM/PM
        RTCHour = RTCHour & %00011111  ' Bits 4-0 = Hours  0-12
       endif
      BCDResult = RTCHour
      
      gosub Bcd2Dec
      
       
      if hourmode = 1 then  '12Hr Convert to 24Hr
        hourmode = 0    ' change to 24Hr
        if rtcAMPM = 1 then 'PM 
            BCDResult = BCDResult + 12  'PM
        endif
      else  '24Hr Convert to 12Hr
        hourmode = 1
        if BCDResult > 12 then 
            BCDResult = BCDResult - 12
            rtcAMPM = 1
        else
            rtcAMPM = 0
        endif
      endif
      gosub Dec2Bcd
      RTCHour = BCDResult
      RTCHour.6 = hourmode
      RTCHour.5 = rtcAMPM 
      I2cwrite SDApin,SCLpin,$D0,$02,[RTCHour]
      'pause 10
      'I2cwrite SDApin,SCLpin,$D0,$02,[RTCHour]  ' Need to write twice because you changed the mode bit
     
     return 
             
      
     Bcd2Dec:
    ' Subroutine to convert BCD (2 hex digits) to Decimal
    ' Make sure to set BCDResult with parameter value before calling this sub  
    ' Result is stored in BCDResult
    
        BCDResult = (((BCDResult >> 4) * 10) + (BCDResult & $0f))
        
        return
        
    Dec2Bcd:
    ' Subroutine to convert Decimal to BCD (2 hex digits)
    ' Make sure to set BCDResult with parameter value before calling this sub  
    ' Result is stored in BCDResult
         
        BCDResult = (((BCDResult / 10) << 4) | (BCDResult // 10))
        
        return
    Last edited by richard; - 14th January 2015 at 05:51.

  3. #3
    Join Date
    Sep 2006
    Posts
    747


    Did you find this post helpful? Yes | No

    Default Re: DS1337 - 12h to 24h mode

    HI,

    I rework your code so I can read it on my LCD:
    Its works ! dont know what we did wrong in the previous version.
    Also works equally good on DS1337 and DS1307 !
    Thanks a lot to all

  4. #4
    Join Date
    Sep 2006
    Posts
    747


    Did you find this post helpful? Yes | No

    Default Re: DS1337 - 12h to 24h mode

    HI,

    I am adding to the program and came across another difficulty,
    I used one button to increments hours and another to increments minutes. Minutes works fine.
    But hours, when I start with 19H, do a 24h to 12H conversion.. then when I increase the hours, no matter what time I have the output is 20H, with RTChour.6 = 0 and RTCHour.5 = 1.
    I'm stuck in this loop, anybody can see why??
    thanks
    I posted the complete code, the rest is working great.
    INCLUDE "modedefs.bas"
    Define OSC 8
    CM1CON0.7 = 0
    CM2CON0.7 = 0
    DEFINE BUTTON_PAUSE 50

    '////////////////// HPWM /////////////////////////
    DEFINE CCP1_REG PORTC
    DEFINE CCP1_BIT 2
    Pause 20

    '/////////////////////////
    '// LCD configuration //
    '/////////////////////////

    DEFINE LCD_DREG PORTA ' Set LCD Data port
    DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus RB.4, RB.5, RB.6, RB.7
    DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
    DEFINE LCD_RSBIT 7 ' Set LCD Register Select bit
    DEFINE LCD_EREG PORTB ' Set LCD Enable port
    DEFINE LCD_EBIT 6 ' Set LCD Enable bit
    DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits) '4 therefore put wire at 4, 5, 6 and 7 of LCD
    DEFINE LCD_LINES 2 ' Set number of lines on LCD
    DEFINE LCD_COMMANDUS 2500
    DEFINE LCD_DATAUS 250
    DEFINE CHAR_PACING 2000
    pause 1000

    '///////////////////////////////////////////////
    '// Variable Declaration and initialization //
    '///////////////////////////////////////////////

    TrisB= 0
    TrisA= 0
    'TrisC=%00110000
    SDApin var PORTC.4 ' RTC data
    SCLpin var PORTC.3 ' RTC clock

    tmp var byte
    RTCSec var byte
    RTCMin var byte
    temp_hour var byte
    temp_min var byte
    pkt var byte[11]
    rtcAMPM var bit ' Storage flag to indicate AM or PM ; 0=AM, 1=PM
    hourmode var bit ' Storage flag for RTC 12/24 hour mode ; 0=24Hr, 1=12Hr
    BCDResult var byte ' Storage for temporary result for BCD Conversions
    RTCHour var byte
    ' osccon=$70 '8 mhz
    ansel=0 'dig i/o
    ' CMCON0=7 ' compare off
    trisc=%1110000

    pause 10


    i2cwrite sdapin,sclpin,$D0,0,[$0,$14,$13,3,$14,1,$14] 'SANE TIME AND DATE
    'i2cwrite sdapin,sclpin,$D0,0,[0]
    pause 500
    lcdout $fe,$c0," Ready",13,10
    'serout2 porta.0,84, ["ready",13,10]
    main:

    Gosub gethour
    if PortC.6=1 then gosub ADDHour
    if PortC.5=1 then gosub ADDMin


    goto main
    end


    gethour:
    i2cREAD sdapin,sclpin,$D0,0,[str pkt \3 ]
    RTCHour = pkt[2]
    if RTCHour.6 then
    lcdout $fe,1,"Time=", hex2 (pkt[2]&$1f),":",hex2 pkt[1],":",hex2 pkt[0] 'bit 0=sec, bit 1=min, bit 2=hrs
    lcdout $FE,$C0, bin RTCHour.6, " : ", bin RTCHour.5
    if RTCHour.5 then lcdout $fe,$c0, bin RTCHour.6, " pm" 'serout2 porta.0,84, [" pm" ]

    else ' if RTCHour.6 =0
    lcdout $fe,1,"Time=", hex2 pkt[2],":",hex2 pkt[1],":",hex2 pkt[0]
    lcdout $FE,$C0, bin RTCHour.6, " : ", bin RTCHour.5
    endif
    pause 100
    if PortC.5 & PortC.6 then gosub ampm
    return

    ampm:
    Pause 500
    if PortC.5 & PortC.6 then
    I2CRead SDApin,SCLpin,$D0,$02,[RTCHour]
    hourmode = RTCHour.6
    if hourmode = 1 then ' Is the RTC set for 12-hour mode
    rtcAMPM = RTCHour.5 ' Assign AM/PM
    RTCHour = RTCHour & %00011111 ' Bits 4-0 = Hours 0-12
    endif
    BCDResult = RTCHour

    gosub Bcd2Dec
    if hourmode = 1 then '12Hr Convert to 24Hr
    hourmode = 0 ' change to 24Hr
    if rtcAMPM = 1 then 'PM
    BCDResult = BCDResult + 12 'PM
    endif
    else '24Hr Convert to 12Hr
    hourmode = 1
    if BCDResult > 12 then
    BCDResult = BCDResult - 12
    rtcAMPM = 1
    else
    rtcAMPM = 0
    endif
    endif
    gosub Dec2Bcd
    RTCHour = BCDResult
    RTCHour.6 = hourmode
    RTCHour.5 = rtcAMPM
    I2cwrite SDApin,SCLpin,$D0,$02,[RTCHour]
    'pause 10
    endif

    return


    Bcd2Dec:
    ' Subroutine to convert BCD (2 hex digits) to Decimal
    ' Make sure to set BCDResult with parameter value before calling this sub
    ' Result is stored in BCDResult

    BCDResult = (((BCDResult >> 4) * 10) + (BCDResult & $0f))

    return

    Dec2Bcd:
    ' Subroutine to convert Decimal to BCD (2 hex digits)
    ' Make sure to set BCDResult with parameter value before calling this sub
    ' Result is stored in BCDResult

    BCDResult = (((BCDResult / 10) << 4) | (BCDResult // 10))

    return

    ADDHour: 'increment hours
    pause 200
    if PortC.5=1 then return
    if PortC.6=1 then

    I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour]
    hourmode = RTCHour.6
    rtcAMPM = RTCHour.5

    BCDResult = RTCHour
    gosub Bcd2Dec

    if hourmode = 0 then ' this is 24H mode 0H to 23H
    hourmode = 1
    BCDResult = BCDResult + 1
    if BCDResult > 23 then BCDResult = 0
    Pause 2
    gosub Dec2Bcd
    RTCHour = BCDResult
    I2cwrite SDApin,SCLpin,$D0,$02,[RTCHour]

    elseif hourmode = 1 then ' this is 12H mode 0H to 11H
    hourmode = 0
    BCDResult = BCDResult + 1
    if BCDResult > 11 then BCDResult = 0
    Pause 2
    gosub Dec2Bcd
    RTCHour = BCDResult
    RTCHour.5 = rtcAMPM
    ' lcdout $FE,1, "RTCH2: ", bin RTCHour
    ' lcdout $FE,$C0, "BCDR: ", bin BCDResult
    ' pause 5000
    I2cwrite SDApin,SCLpin,$D0,$02,[RTCHour]
    endif
    endif
    return


    ADDMin: ' increment a minutes
    pause 200
    if PortC.6=1 then return
    if PortC.5=1 then

    ' I2CRead SDApin,SCLpin,$D0,$02,[RTCHour]
    I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour]
    BCDResult = RTCMin
    gosub Bcd2Dec
    BCDResult = BCDResult + 1
    if BCDResult > 59 then BCDResult = 0
    Pause 2
    gosub Dec2Bcd
    RTCMin = BCDResult
    I2cwrite SDApin,SCLpin,$D0,$01,[RTCMin]

    endif
    return

  5. #5
    Join Date
    Sep 2006
    Posts
    747


    Did you find this post helpful? Yes | No

    Default Re: DS1337 - 12h to 24h mode

    The bit RTCHour.5 is mixing the time up.. I think..
    Why did they use it at a dual purpose.... !

  6. #6
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    Did you find this post helpful? Yes | No

    Default Re: DS1337 - 12h to 24h mode

    Lerameur,

    So, just some basic high-level things to understand when dealing with these RTC ICs.
    The data in the RTC registers are in BCD format.
    When you make changes to them, say the Hours register you should follow some specific steps.

    Get the BCD Hours from the RTC
    Save the value of 12/24 mode in your code
    Save the value of the am/pm bit value in your code
    Mask out the am/pm and 12/24 bits if required
    Convert the BCD hours to Decimal hours
    Change the Decimal Hours to the value you want
    Convert the Decimal Hours to BCD Hours
    Set the 12/24 Bit correctly in the New BCD Hours value
    Set the am/pm Bit correctly in the New BCD Hours value
    Write the new BCD Hours value to the RTC

    Try not not intermix operations.
    Change the Hour value or change the 12/24 mode, but not both in the same action.

    When in 12hr mode, change the time the way you need to for that mode.
    When in 24hr mode, change the time the way you need to for that mode.

    Another suggestion is create yourself a table for hours in Excel or a text editor.
    List all the hours in 12hr mode and also for 24hr mode.
    Then for each hour record the byte (in binary) value for the RTC Hour register you would need for that time, making sure to set/clear the 12/24 mode and am/pm bits appropriately.
    Looking at that kind of table may help you visualize what you need in your code to change time values to/from different values and when changing 12/24 modes.

    Just some thoughts that I followed quite a while back to get a handle on using RTC ICs.

    Regards,
    TABSoft
    Regards,
    TABSoft

  7. #7
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    Did you find this post helpful? Yes | No

    Default Re: DS1337 - 12h to 24h mode

    Some additional direction.

    12hr Mode

    Display Value to LCD:
    1. Mask off 12/24Hr mode bit
    2. Mask off am/pm bit
    3. Display new masked value with Hex2 modifier

    Change Hour Value in RTC:
    1. Mask off 12/24Hr mode bit
    2. Mask off am/pm bit
    3. Convert new masked value from BCD to Decimal
    4. Change Hour value in Decimal
    5. Convert Decimal Hour back to BCD
    6. Set am/pm bit
    7. Set 12/24Hr mode bit
    8. Write new value to RTC Hour register


    24hr Mode

    Display Value to LCD:
    1. Display value with Hex2 modifier

    Change Hour Value in RTC:
    1. Convert value from BCD to Decimal
    2. Change Hour value in Decimal
    3. Convert Decimal Hour back to BCD
    4. Write new value to RTC Hour register


    Here is a table that shows two hour values in their various permutations.
    SampleTable.txt

    Hope this helps.
    Regards,
    TABSoft

  8. #8
    Join Date
    Sep 2006
    Posts
    747


    Did you find this post helpful? Yes | No

    Default Re: DS1337 - 12h to 24h mode

    I am having difficulty dealing with the bit 5 and 6 of the hours..
    using the subroutine add hours:
    I have 11 with bi6 and bit = 0
    click on addhour, brings me at hour 32 with bit 6 = 0 and bit 5 = 1
    ...
    ADDHour: 'increment hours
    pause 200
    if PortC.5=1 then return
    if PortC.6=1 then

    I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour]
    hourmode = RTCHour.6
    rtcAMPM = RTCHour.5
    ' lcdout $FE,1, "RTCH1: ", bin RTCHour
    ' lcdout $FE,$C0, "BCDR: ", dec BCDResult
    ' pause 2000

    if hourmode = 0 then ' this is 24H mode 0H to 23H
    ' hourmode = 1
    BCDResult = RTCHour
    gosub Bcd2Dec

    BCDResult = BCDResult + 1
    if BCDResult > 23 then BCDResult = 0
    Pause 2
    BCDResult_temp = BCDResult
    gosub Dec2Bcd
    RTCHour = BCDResult
    if BCDResult_temp > 12 then RTCHour.5 = 1
    I2cwrite SDApin,SCLpin,$D0,$02,[RTCHour]

    elseif hourmode = 1 then ' this is 12H mode 0H to 12H
    ' hourmode = 0
    rtcAMPM = RTCHour.5 ' Assign AM/PM
    RTCHour = RTCHour & %00011111 ' Bits 4-0 = Hours 0-12
    BCDResult = RTCHour
    ' lcdout $FE,1, "RTCH1: ", bin RTCHour
    ' lcdout $FE,$C0, "BCDR: ", dec BCDResult
    ' pause 2000
    gosub Bcd2Dec

    BCDResult = BCDResult + 1 ' in decimal
    if BCDResult > 12 then BCDResult = 1
    Pause 2
    gosub Dec2Bcd
    RTCHour = BCDResult
    RTCHour.6 = hourmode
    RTCHour.5 = rtcAMPM
    ' lcdout $FE,1, "RTCH2: ", bin RTCHour
    ' lcdout $FE,$C0, "BCDR: ", bin BCDResult
    ' pause 2000
    I2cwrite SDApin,SCLpin,$D0,$02,[RTCHour]
    endif
    endif
    return

Similar Threads

  1. 12H format setting for DS1307
    By larzazral in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 23rd February 2010, 07:34
  2. example code for DS1337
    By TONIGALEA in forum mel PIC BASIC Pro
    Replies: 25
    Last Post: - 8th December 2009, 21:16
  3. Code for DS1337
    By Fernanda in forum Off Topic
    Replies: 2
    Last Post: - 21st July 2008, 20:18
  4. PBPro for 16-bit PICs (24F/24H/DSPICs)?
    By Sergeant in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 20th April 2007, 20:18
  5. DS1337 Problem
    By snow in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 9th January 2005, 12:17

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