Data from DS1307 (BCD) saved to ext memory and read back to display


Closed Thread
Results 1 to 11 of 11
  1. #1
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891

    Default Data from DS1307 (BCD) saved to ext memory and read back to display

    Hi there,

    I have setup a 16F690 reading a DS1307's time and date (I use RA2/INT interrupt to trigger the process every second), save this data to an external 24LC64 memory, read back what has just been written from the memory and display it.

    If I bypass the I2CWRITE/I2CREAD commands, the DS1307 displays time correctly.

    But, like in the code here under, after saving RTC's time to the memory, this is what I get after reading back the data from the external memory:
    Name:  2016-07-18 23_56_00-LCD Module.jpg
Views: 505
Size:  10.5 KB

    Data from DT1307 is in BCD format and data conversion, that's where I think I'm wrong, is not my cup of tea

    What am I missing?


    Code:
    '-------------------------------------------------------------------------------
    ' PIC 16F690 Fuses (MPASM)
    @ __Config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_HS_OSC &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF 
    
    '-------------------------------------------------------------------------------
    ' Registers   76543210
    OPTION_REG = %10000000 'PORT A&B Pull-Ups disabled (look WPUA & WPUB) INTEDG rising edge on A2
    ANSEL      = %00000000 'Analog inputs Channels 0 to 7
    ANSELH     = %00000000 'Analog inputs Channels 8 to 11
    ADCON0     = %00000000 'A/D Module is OFF
    CM1CON0    = %00000000 'Comparator1 Module is OFF
    CM2CON0    = %00000000 'Comparator2 Module is OFF
    INTCON     = %00010000 'INTerrupts CONtrol
    TRISA      = %00000100 'Set Input/Output (0 to 5)
    PORTA      = %00000000 'Ports High/Low (0 to 5)
    TRISB      = %00010000 'Set Input/Output (4 to 7)
    PORTB      = %00000000 'Ports High/Low (4 to 7)
    TRISC      = %00000000 'Set Input/Output (0 to 7)
    PORTC      = %00000000 'Ports High/Low (0 to 7)
    
    '-------------------------------------------------------------------------------
    ' Defines
    DEFINE OSC 4
    
    '-------------------------------------------------------------------------------
    ' Variables
    SQW         VAR PORTA.2     'DS1307's 1Hz output
    D_Out       VAR PORTB.7     'serial data out for display
    SCL         VAR PORTC.0     'DS1307 clock line
    SDA         VAR PORTC.1     'DS1307 data line
    
    DB0         VAR BYTE(8)
    DB0(0)      = 0 ' Seconds (00-59)
    DB0(1)      = 0 ' Minutes (00-59)
    DB0(2)      = 0 ' Hours (00-23)
    DB0(3)      = 0 ' Day (01-07; 1=Sunday, 2=Monday, ...)
    DB0(4)      = 0 ' Date (01-31)
    DB0(5)      = 0 ' Month (01-12)
    DB0(6)      = 0 ' Year (00-99)
    DB0(7)      = 0 ' Control (see datasheet)
    
    D_Bps       CON 16468   ' 9600 Driven Inverted None
    
    '-------------------------------------------------------------------------------
    ' Initialize
    
    '-------------------------------------------------------------------------------
    ' Program
    ON INTERRUPT GOTO Read_DS1307
    
    MAIN:
        GOTO MAIN:
    END    
    
    '-------------------------------------------------------------------------------
    ' Interrutp Service Routine
    DISABLE
    Read_DS1307:      ' Read time Secs,Mins,Hours,Day,Date,Month,Year,Control
        I2CREAD SDA,SCL,$D0,$00,[STR DB0\8] ' Read 8 bytes from DS1307
    
        ' Write to external memory
        I2CWRITE SDA,SCL,$A0,$00,[DB0(2),DB0(1),DB0(0)]
        PAUSE 10
        
        'Read from external memory
        I2CREAD SDA,SCL,$A0,$00,[DB0(2),DB0(1),DB0(0)]
    
        SEROUT2 D_Out,D_Bps,[HEX2 DB0(2),":",HEX2 DB0(1),":",HEX2 DB0(0),13,10]
    
        INTCON.1 = 0  'clear INTF interrupt flag
        RESUME 
    ENABLE
    Roger

  2. #2
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: Data from DS1307 (BCD) saved to ext memory and read back to display

    Hi Roger, I'm no expert, but maybe this can be of some use.

    I have these variables to display the time on an LCD

    Code:
    TimeH           var byte                 'variable to store Hours
    TimeM           var byte                 'variable to store Minutes
    SS              VAR Byte                 'variable to store Seconds
    
    RTCsec          var byte                'RTC Seconds
    RTCMin          var byte		        'RTC Minutes
    RTCHour         var byte	            'RTC Hours
    I then read the DS1307 and convert the BDC value into time as follows

    Code:
    I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour]   ' read the RTC
    	
    timeH=(RTCHour>>4)                        'convert the BCD format of the hours register and store in variable timeH
    timeH=(timeH &$03)*10
    timeH=timeH+(RTCHour&$0F)
    
    timeM=(RTCMin>>4)                         'convert the BCD format of the mins register and store in variable timeM
    timeM=(timeM &$07)*10
    timeM=timeM+(RTCMin&$0F)    
    
    ss=(RTCSec>>4)                            'convert the BCD format of the sec register and store in variable ss
    ss=(ss &$07)*10
    ss=ss+(RTCSec&$0F)   
    
    LCDOut $FE,$C0+11,#TimeH DIG 1,#TimeH DIG 0,":",#TimeM DIG 1,#TimeM DIG 0          'display the current time on the LCD
    Now maybe (I don't know as I've never written to an external e-prom) you can save the byte variables for TimeH, TimeM and SS with something like
    Code:
    I2Cwrite SDApin,SCLpin,$insert address of eeprom,[TimeH,TimeM,SS]
    Like I said, I'm no expert, and may be sending you off on a tangent !!

    Forgot to add, this is the routine to convert to BDC if required

    Code:
    CounterA=SetMN
    Gosub ConvertBCD
    RTCMin=CounterB
    
    CounterA=SetHR
    Gosub ConvertBCD
    RTCHour=CounterB
    I2Cwrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour]
    
    
    ConvertBCD:
    	CounterB=CounterA DIG 1                        ' CounterA is the entry variable
    	CounterB=CounterB<<4                           ' CounterB holds the converted BCD result on exit
    	CounterB=CounterB+CounterA DIG 0
    Return
    CounterA and CounterB are byte variables, as are setHR and setMN. I used these as the initial time to display on the LCD. For example I want to set the initial time to 12:00 I use 12 for setHR and 0 for setMN. If you need to convert from decimal to BDC before sending to the eepprom, then maybe this bit of code can help ??
    Last edited by Scampy; - 19th July 2016 at 18:19. Reason: added more examples

  3. #3
    Join Date
    May 2013
    Location
    australia
    Posts
    2,389


    Did you find this post helpful? Yes | No

    Default Re: Data from DS1307 (BCD) saved to ext memory and read back to display

    Malcom is nearly correct


    I2Cwrite SDApin,SCLpin,$insert address of eeprom,[TimeH,TimeM,SS]
    should be
    I2Cwrite SDApin,SCLpin,$a0,eprom_location,[TimeH,TimeM,SS]
    where :- for a 24lc64 8k bytes and 32 byte page size
    1. eprom_location must be a word var
    2. eprom_location must be < 8192
    3. ( eprom_location//page_size ) < (32 -number_of_bytes to write ) ie don't try to write past a page boundary

    ps can't see the need for bcd - bin - bcd conversions though
    Warning I'm not a teacher

  4. #4
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: Data from DS1307 (BCD) saved to ext memory and read back to display

    Quote Originally Posted by richard View Post
    Malcom is nearly correct
    Hi Richard, nice to know I was almost there

    Quote Originally Posted by richard View Post
    ps can't see the need for bcd - bin - bcd conversions though
    Roger stated that the RTC uses BDC format, which needs converting

    Quote Originally Posted by flotulopex View Post

    Data from DT1307 is in BCD format and data conversion, that's where I think I'm wrong, is not my cup of tea
    I presume that once you've converted the BDC format and stored them into variables as decimal values for hours and minutes you would then simply write those to the external memory, although they would need to be word variables, so would this be correct ?

    Code:
    I2Cwrite SDApin,SCLpin,$a0,eprom_location,[TimeH.lowbyte, TimeH.highbyte,TimeM.lowbyte, TimeM.highbyte,SS.lowbyte, SS.highbyte]
    Assuming TimeH, TimeM and SS are all declared as word variables

  5. #5
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default Data from DS1307 (BCD) saved to ext memory and read back to display

    Quote Originally Posted by Scampy View Post
    ...you would then simply write those to the external memory although they would need to be WORD variables...
    I thought only the address variable must be WORD sized?
    Name:  2016-07-20 20_41_53-Memory-24LC64_serial-I2C-EEPROM.pdf - [24AA64_24LC64 64K I2C Serial EEPROM] .jpg
Views: 423
Size:  23.4 KB
    Roger

  6. #6
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default Re: Data from DS1307 (BCD) saved to ext memory and read back to display

    Well,

    I'm still making some mistake somewhere.

    The display says now "55:55:55".

    If I bypass the I2CWRITE and I2CREAD commands, everything is fine

    Code:
    '-------------------------------------------------------------------------------
    ' PIC 16F690 Fuses (MPASM)
    @ __Config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_HS_OSC &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF 
    
    '-------------------------------------------------------------------------------
    ' Registers   76543210
    OPTION_REG = %10000000 'PORT A&B Pull-Ups disabled (look WPUA & WPUB) INTEDG rising edge on A2
    'OSCCON     = %01100000 'Internal RC set to 4Mhz - not to be used with XTal
    ANSEL      = %00000000 'Analog inputs Channels 0 to 7
    ANSELH     = %00000000 'Analog inputs Channels 8 to 11
    ADCON0     = %00000000 'A/D Module is OFF
    CM1CON0    = %00000000 'Comparator1 Module is OFF
    CM2CON0    = %00000000 'Comparator2 Module is OFF
    INTCON     = %00010000 'INTerrupts CONtrol
    TRISA      = %00000100 'Set Input/Output (0 to 5)
    PORTA      = %00000000 'Ports High/Low (0 to 5)
    TRISB      = %00010000 'Set Input/Output (4 to 7)
    PORTB      = %00000000 'Ports High/Low (4 to 7)
    TRISC      = %00000000 'Set Input/Output (0 to 7)
    PORTC      = %00000000 'Ports High/Low (0 to 7)
    
    '-------------------------------------------------------------------------------
    ' Defines
    DEFINE OSC 4
    
    '-------------------------------------------------------------------------------
    ' Variables
    SQW     VAR PORTA.2 ' RTC 1Hz output
    D_Out   VAR PORTB.7 ' serial data out
    SCL     VAR PORTC.0 ' RTC clock
    SDA     VAR PORTC.1 ' RTC data 
    
    RTC_Sec VAR BYTE    ' Seconds (00-59)
    RTC_Min VAR BYTE    ' Minutes (00-59)
    RTC_Hou VAR BYTE    ' Hours (00-23)
    
    D_Bps   CON 16468   ' 9600 Driven Inverted None
    
    '-------------------------------------------------------------------------------
    ' Initialize
    PAUSE 1000                      ' power-up serial-LCD
    SEROUT2 D_Out,D_Bps,[27,"C",0]  ' set serial-LCD cursor OFF
    SEROUT2 D_Out,D_Bps,[27,"L",0]  ' set serial-LCD backlight OFF
    
    '-------------------------------------------------------------------------------
    ' Program
    ON INTERRUPT GOTO Read_DS1307
    
    MAIN:
        GOTO MAIN:
    END    
    
    '-------------------------------------------------------------------------------
    ' Interrutp Service Routine
    DISABLE
    Read_DS1307:
        I2CREAD SDA,SCL,$D1,$00,[RTC_Sec,RTC_Min,RTC_Hou]
    
        ' Convert Hex coded to decimal
        RTC_Sec = (RTC_Sec & $F)+((RTC_Sec >> 4)*10)
        RTC_Min = (RTC_Min & $F)+((RTC_Min >> 4)*10)
        RTC_Hou = (RTC_Hou & $F)+((RTC_Hou >> 4)*10)
    
        ' Write to external memory
        I2CWRITE SDA,SCL,$A0,$00,[RTC_Sec,RTC_Min,RTC_Hou]
        PAUSE 10
        
        'Read from external memory
        I2CREAD SDA,SCL,$A0,$00,[RTC_Sec,RTC_Min,RTC_Hou]
    
        SEROUT2 D_Out,D_Bps,["Time: ",DEC2 RTC_Hou,":",DEC2 RTC_Min,":",DEC2 RTC_Sec,13,10]
    
        INTCON.1 = 0
        RESUME 
    ENABLE
    Roger

  7. #7
    Join Date
    Sep 2009
    Posts
    737


    Did you find this post helpful? Yes | No

    Default Re: Data from DS1307 (BCD) saved to ext memory and read back to display

    Address should be word or byte variable, not constant.
    Code:
         MemAdr var word
        MemAdr =0
        ' Write to external memory
        I2CWRITE SDA,SCL,$A0,MemAdr ,[RTC_Sec,RTC_Min,RTC_Hou]
        PAUSE 10
        
        'Read from external memory
        I2CREAD SDA,SCL,$A0,MemAdr ,[RTC_Sec,RTC_Min,RTC_Hou]
    EDIT:
    Constant works for clock, as PBP send minimum 8 bits, but it wont work for EEPROM as it expecting 16bits.
    I mention that in another topic.
    Last edited by pedja089; - 20th July 2016 at 22:29.

  8. #8
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: Data from DS1307 (BCD) saved to ext memory and read back to display

    I have a project that sends values from 0 to 4096 to an 16 channel PWM led driver chip, and this is a sample line of code
    Code:
      I2CWRITE SDApin,SCLpin,i2cWriteAddress,i2cControl,[0,0,CH1_PWM.lowbyte,CH1_PWM.highbyte]
    The reference to word variables I made was because your external eprom is expecting 16 bit values for the data, hence my reference to making your TimeH, TimeM and TimeS word variables, and trying the lowbyte / highbyte approach. - Like I mentioned in my first reply, I'm no expert, and this may be taking you off tangent, but then again, might be worth trying

  9. #9
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default Data from DS1307 (BCD) saved to ext memory and read back to display

    Quote Originally Posted by pedja089 View Post
    Address should be word or byte variable, not constant.
    Okay, I haven't declared the address as a variable at all.

    So I'll give it a try a little later (I'm in the office right now).


    ...your external eeprom is expecting 16 bit values for the data.
    This is confusing me. I think the 24LC64 needs data in BYTE format as where it's addresses are in WORD format.
    Roger

  10. #10
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default Re: Data from DS1307 (BCD) saved to ext memory and read back to display

    That is correct. The 24LC64 data is 8 bits wide per individual location. CH1_PWM.lowbyte,CH1_PWM.highbyte is the correct way to sequentially load data into the eeprom if the variable is a word.
    Dave Purola,
    N8NTA
    EN82fn

  11. #11
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Thumbs up Defining eeprom address made it work

    It works!

    I declared the EEPROM address as WORD, replaced the $00 in the I2CWRITE and I2CREAD commands and now the result is okay.

    Thanks a lot for the help

    Code:
    '-------------------------------------------------------------------------------
    ' PIC 16F690 Fuses (MPASM)
    @ __Config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_HS_OSC &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF 
    
    '-------------------------------------------------------------------------------
    ' Registers   76543210
    OPTION_REG = %10000000 'PORT A&B Pull-Ups disabled (look WPUA & WPUB) INTEDG rising edge on A2
    'OSCCON     = %01100000 'Internal RC set to 4Mhz - not to be used with XTal
    ANSEL      = %00000000 'Analog inputs Channels 0 to 7
    ANSELH     = %00000000 'Analog inputs Channels 8 to 11
    ADCON0     = %00000000 'A/D Module is OFF
    CM1CON0    = %00000000 'Comparator1 Module is OFF
    CM2CON0    = %00000000 'Comparator2 Module is OFF
    INTCON     = %00010000 'INTerrupts CONtrol
    TRISA      = %00000100 'Set Input/Output (0 to 5)
    PORTA      = %00000000 'Ports High/Low (0 to 5)
    TRISB      = %00010000 'Set Input/Output (4 to 7)
    PORTB      = %00000000 'Ports High/Low (4 to 7)
    TRISC      = %00000000 'Set Input/Output (0 to 7)
    PORTC      = %00000000 'Ports High/Low (0 to 7)
    
    '-------------------------------------------------------------------------------
    ' Defines
    DEFINE OSC 4
    
    '-------------------------------------------------------------------------------
    ' Variables
    SQW     VAR PORTA.2 ' RTC 1Hz output
    D_Out   VAR PORTB.7 ' serial data out
    SCL     VAR PORTC.0 ' RTC clock
    SDA     VAR PORTC.1 ' RTC data 
    
    RTC_Sec VAR BYTE    ' Seconds (00-59)
    RTC_Min VAR BYTE    ' Minutes (00-59)
    RTC_Hou VAR BYTE    ' Hours (00-23)
    
    Eep_Adr VAR WORD
    Eep_Adr = $00
    
    D_Bps   CON 16468   ' 9600 Driven Inverted None
    
    '-------------------------------------------------------------------------------
    ' Initialize
    PAUSE 1000                      ' power-up serial-LCD
    SEROUT2 D_Out,D_Bps,[27,"C",0]  ' set serial-LCD cursor OFF
    SEROUT2 D_Out,D_Bps,[27,"L",0]  ' set serial-LCD backlight OFF
    
    '-------------------------------------------------------------------------------
    ' Program
    ON INTERRUPT GOTO Read_DS1307
    
    MAIN:
        GOTO MAIN:
    END    
    
    '-------------------------------------------------------------------------------
    ' Interrutp Service Routine
    DISABLE
    Read_DS1307:
        I2CREAD SDA,SCL,$D1,$00,[RTC_Sec,RTC_Min,RTC_Hou]
    
        SEROUT2 D_Out,D_Bps,["HEX: ",HEX2 RTC_Hou,":",HEX2 RTC_Min,":",HEX2 RTC_Sec,13,10]
    
        ' Convert Hex coded to decimal - can be usefull for external memory data storage (logging)
        RTC_Sec = (RTC_Sec & $F)+((RTC_Sec >> 4)*10)
        RTC_Min = (RTC_Min & $F)+((RTC_Min >> 4)*10)
        RTC_Hou = (RTC_Hou & $F)+((RTC_Hou >> 4)*10)
    
        ' Write to external memory
        I2CWRITE SDA,SCL,$A0,Eep_Adr,[RTC_Sec,RTC_Min,RTC_Hou]
        PAUSE 10
        
        'Read from external memory
        I2CREAD SDA,SCL,$A0,Eep_Adr,[RTC_Sec,RTC_Min,RTC_Hou]
    
        SEROUT2 D_Out,D_Bps,["DEC: ",DEC2 RTC_Hou,":",DEC2 RTC_Min,":",DEC2 RTC_Sec,"   "]
    
        INTCON.1 = 0  'clear INTF interrupt flag
        RESUME 
    ENABLE
    Thank you Dave for explaining the WORD sized eeprom data.

    Before I started this thread, I didn't know about "packed BDC". I think it can be interesting to reduce data size especially when, like in my current project, time data has to be stored in external memory.
    Roger

Similar Threads

  1. Replies: 2
    Last Post: - 3rd January 2013, 16:57
  2. DS1307 - How to store Decimal Value & how to convert back to BCD?
    By financecatalyst in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 2nd January 2011, 23:44
  3. loading data to EXt. eeprom
    By MINHLE in forum General
    Replies: 0
    Last Post: - 28th December 2009, 17:56
  4. Write Onewire data toa I2C memory / read ASCI
    By Eugeniu in forum mel PIC BASIC Pro
    Replies: 67
    Last Post: - 16th November 2008, 19:19
  5. cannot read/write to 16F690 data memory after CPD_ON
    By awdsas in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 22nd November 2006, 11:46

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