ds1302 elektrik kesilice saat bigisini unutuyor

Başlatan tapir, 26 Ocak 2006, 11:09:23

tapir

Arkadaşlar uzun bir süredir 16f628 ve ds1302  ile proton ide de alarm çıkışlı bir saat yapmak istiyorum (alarm haftada bir kez belirlenen zaman kadar aktif olacak) bunu sonuda yaptım fakaat bacup pilinide (3.6v) rtc nin 8 nolu pinine bağlamama ragmen bir türlü saat bilgisini elektriği kestikten sonra tekrar verdiğimde kaldığı yerden devam ettiremedim
birde merak ettiğim ds1302 elektrik kesildiğinde en son saat kaçta kaldıysa oradan mı deveam ediyor yoksa saat ds1302 de backup pili vasıtasıyla çalışmaya devam edeim tekrar elektrik verildiğinde o an saat kaç ise yani güncel saatten mi devam ediyor bu konuda bilen arkadaşlar yardımcı olursa minnettar kalırım şimdiden teşekkürler

kodlar aşağıda  proteusta çizdiğim simulasyon da var ama buraya nasıl ekliyeceğimi bilmediğimden gönderemiyorum
bu kodlarla hem isis de hemde gerçek devrede çalışıyor tek sorun elektrik kesildiğinde devam etmemesi


Device = 16F628            ' We're compiling for the PIC16F628A
    XTAL = 4                    ' We're using a 4MHz oscillator
    LCD_DTPIN = PORTB.4         ' For Proteus Virtual Hardware Board LCD Data is PORTB.4,5,6,7
    LCD_RSPIN = PORTB.2         ' LCD RS pin
    LCD_ENPIN = PORTB.3         ' LCD EN pin
    LCD_INTERFACE = 4           ' We're using a 4-bit LCD interface
    LCD_LINES = 2               ' We're using a 2-Line LCD
    LCD_TYPE = 0                ' Our LCD is the alphanumeric type

 cmcon=7
 vrcon=0

symbol RST  PORTA.0
symbol IO  PORTA.2
symbol SCLK  PORTA.1
      
   warnings off

   dim bcd_to_bin_byte         'variable used in BCD and Binary conversion routines
   dim low_bits            'low byte for Binary to BCD routine
   dim high_bits            'high byte for Binary to BCD routine
   dim ds1307_address         'DS1307 internal registers address(0=seconds,1=minutes etc.)
   dim second               'seconds variable
   dim minute               'minutes variable
   dim hour               'hours variable
   dim day                  'days variable
   dim date               'dates variable
   dim month               'months variable
   dim year               'years variable
   dim buttonvalue            'variable used for "up" and "down" buttons values
   dim maxvalue            'variable holding highest allowable current value in button routine
   dim minvalue            'variable holding lowest current allowable value in button routine
   dim leap               'variable used to set "maxvalue" in leapyear
   dim monthlength            'variable used to set maximum number of days in the selected month
   dim index               'variable used to select display options in "setup"
   dim character            'variable holding data selected from eeprom or ldata tables to be printed on display
   dim printposition         'start position on the LCD of first "character" in print routine
   dim printend            'last "character" position to be printed on LCD
   dim printaddress         'start position of data in eeprom or ldata table
   dim row                  'the line number you wish to display the info on the LCD
   dim read_data            'tells the print routine,"print_eeprom" to use eeprom(0) or ldata(1) for its data reading
   dim control
   dim sel byte
   dim say byte
   dim secondalr               'seconds variable
   dim minutealr               'minutes variable
   dim houralr               'hours variable
   dim dayalr                  'days variable
   dim datealr               'dates variable
   dim monthalr               'months variable
   dim yearalr                    
     
       Low RST         ' Reset RTC
       Low SCLK
         
   warnings on
   symbol led=portb.1
   symbol up=porta.3         'use porta.2 for the "up" button
   symbol down=porta.4         'use porta.1 for the "down" button
   symbol setup=portb.0      'use portb.3 for the "setup" buton                                                           
 
   trisa=%0011000            
   trisb.0=1               
   trisb.1=0            
    porta=0
    portb=0
   
   'year=06
   'month=01
   'date=31
   'day=03
   'hour=23
   'minute=59
   'second=59
   
 
 
   
start:
     cls
     if setup=0 then goto start         'debounce setup button on return from setting time
      
display_time:
             
           if up=0 then gosub test
           if down=0 then gosub teststop
           if setup=0 then display_time                           
         gosub get_time                     'read time from DS1302         
           gosub print_time                       'print the clock display
           gosub epromoku
           gosub alrmkont
            if setup=0 then gosub sec:'gosub time_set              
       
            if sel=1  then
            sel=0:say=0: CLS:gosub time_set:endif              
         
            if sel=2  then
            sel=0:say=0:CLS:gosub alr_set:endif
                     
           goto display_time
           
         
start_clock:   
   
         
         return
           
    set_time:
        bcd_to_bin_byte=second:gosub convert_to_bcd:second=bcd_to_bin_byte
       bcd_to_bin_byte=minute:gosub convert_to_bcd:minute=bcd_to_bin_byte
       bcd_to_bin_byte=hour:gosub convert_to_bcd:hour=bcd_to_bin_byte
       bcd_to_bin_byte=Day:gosub convert_to_bcd:Day=bcd_to_bin_byte
       bcd_to_bin_byte=Date:gosub convert_to_bcd:Date=bcd_to_bin_byte
       bcd_to_bin_byte=Month:gosub convert_to_bcd:Month=bcd_to_bin_byte
       bcd_to_bin_byte=Year:gosub convert_to_bcd:Year=bcd_to_bin_byte
             
        gosub yaz
        return
       
'*****************************************
get_time:      'print at 1,15,dec2 minute:delayms 500

        gosub oku
         bcd_to_bin_byte=second
         gosub convert_to_bin
         second=bcd_to_bin_byte
         
         bcd_to_bin_byte=minute
         gosub convert_to_bin
         minute=bcd_to_bin_byte
       
         bcd_to_bin_byte=hour
         gosub convert_to_bin
         hour=bcd_to_bin_byte
       
         bcd_to_bin_byte=day
         gosub convert_to_bin
        day=bcd_to_bin_byte
       
         bcd_to_bin_byte=date
         gosub convert_to_bin
        date=bcd_to_bin_byte
       
         bcd_to_bin_byte=month
         gosub convert_to_bin
         month=bcd_to_bin_byte
       
         bcd_to_bin_byte=year
         gosub convert_to_bin
         year=bcd_to_bin_byte
                                 
        return
       
convert_to_bin:
            select bcd_to_bin_byte
            
                 case 16 to 25
                 bcd_to_bin_byte=bcd_to_bin_byte-6
            
                 case 32 to 41
                 bcd_to_bin_byte=bcd_to_bin_byte-12
            
                 case 48 to 57
                 bcd_to_bin_byte=bcd_to_bin_byte-18
            
                 case 64 to 73
                 bcd_to_bin_byte=bcd_to_bin_byte-24
            
                 case 80 to 89
                 bcd_to_bin_byte=bcd_to_bin_byte-30
            
                 case 96 to 105
                 bcd_to_bin_byte=bcd_to_bin_byte-36
            
                 case 112 to 121
                 bcd_to_bin_byte=bcd_to_bin_byte-42
            
                 case 128 to 137
                 bcd_to_bin_byte=bcd_to_bin_byte-48
            
                 case 144 to 153
                 bcd_to_bin_byte=bcd_to_bin_byte-54
            
            endselect         
               return

' BINARY to BCD conversion
' The byte to be converted is loaded into the variable bcd_to_bin_byte
' and is returned in the same variable bcd_to_bin_byte

convert_to_bcd:
            low_bits=bcd_to_bin_byte//10                        'get lsb,same for Bin and BCD
               high_bits=bcd_to_bin_byte/10                        'get msb
            bcd_to_bin_byte=high_bits*16                     'covert msb to BCD
            bcd_to_bin_byte=bcd_to_bin_byte+low_bits            'add BCD msb and lsb together   
   
               return                  
                     
print_eeprom:
         repeat
              if read_data=0 then character=eread printaddress         'use eeprom for data retrieval
              if read_data=1 then character=lread menu_list+printaddress   'use ldata for data retrieval
              
              print at row,printposition,character               'print to the LCD
   
              inc printposition                              'move print position one to the right
              inc printaddress                              'point to the next position in the table

         until printposition=printend+1                        'end loop when all characters have been printed
         
         return                                      
print_time:
         print at 1,11,dec2 second
        
print_min:
         print at 1,8,dec2 minute,":"
        
print_hour:     
         print at 1,5,dec2 hour,":"
                  
print_day:      
         read_data=0                      'use eeprom for data reading
         row=2                            'print on line 2 of LCD
         printposition=1               'initial position of "day" on LCD
         printend=3                     'position of last letter to be printed   
         printaddress=day*3            'work out address of data in the eeprom(minimum is 3)

         gosub print_eeprom            'goto LCD print routine
        
print_date:
         print at 2,5,dec2 date
                 
print_month:
         read_data=0                    'use eeprom for data reading
         row=2                     'print on line 2 of LCD
         printposition=8               'initial position of "month" on LCD
         printend=10                     'position of last letter to be printed   
         printaddress=month*3         'work out address of data in the eeprom(minimum is 3)
         printaddress=printaddress+21   'first month data is at address 24 (21+3)in eeprom
         
         gosub print_eeprom               'goto LCD print routine

print_year:
         print at 2,12,"20",dec2 Year
        
         return
        

'This routine sets the time.
'variables "minvalue" and "maxvalue" set the low and high values for year(0-99),month(1-12),
'date(1-31,1-30,1-28 and leap year 1-29),day(1-7,mon to sun),hour(0-23)and minute(0-59).

time_set:print AT 1,1,"SET"
      if setup=0 then goto time_set  'debounce button if still pressed from previous routine
      cls
      
      
      
      print at 1,1,"Set"
      
      buttonvalue=year:index=0:maxvalue=99:minvalue=0:gosub buttons:year=buttonvalue     'work on the YEAR first
      buttonvalue=month:index=1:maxvalue=12:minvalue=1:gosub buttons:month=buttonvalue  'next to the MONTH
               
      monthlength=31                        'if the months are JAN,MAR,MAY,JUL,AUG,OCT and DEC then "monthlength" will be 31
      
      select month                           
      
            case 4,6,9,11                  'if the months are APR,JUN,SEP or NOV then "monthlength" will be 30
            monthlength=30
           
            case 2                         'if it is FEB then set "monthlength" to 28
            monthlength=28
            leap=year//4                      'tests for a leap year
            if leap=0 then monthlength=29      'if it is a leap year then set FEB "monthlength" to 29
           
      endselect
      
      buttonvalue=date:index=2:maxvalue=monthlength:minvalue=1:gosub buttons:date=buttonvalue        'change the DATE
      buttonvalue=day:index=3:maxvalue=7:minvalue=1:gosub buttons:day=buttonvalue           'change the DAY
      buttonvalue=hour:index=4:maxvalue=23:minvalue=0:gosub buttons:hour=buttonvalue           'change the HOUR
      buttonvalue=minute:index=5:maxvalue=59:minvalue=0:gosub buttons:minute=buttonvalue        'change the MINUTE
      buttonvalue=second:index=6:maxvalue=59:minvalue=0:gosub buttons:second=buttonvalue
                        
      print at 2,1,"'Setup' to Start"
      

      
restart:
      'wait until the "setup" button is pressed before starting the clock
      if setup=0 then
       cls
       gosub set_time
       gosub start_clock
       goto start
      endif
      goto restart


'this routine uses the "up" and "down" buttons to select the values you require when setting the clock and prints the setup menu

buttons:
      if up=0 then inc buttonvalue:delayms 200                          'if up button is pressed then increase "buttonvalue" by one
      if buttonvalue>maxvalue then buttonvalue=minvalue            'if "buttonvalue" goes above its maximum then make it equal to "minvalue"
      if down=0 then dec buttonvalue:delayms 200                  'if down button is pressed then decrease "buttonvalue" by one
      if buttonvalue<minvalue or buttonvalue=255 then buttonvalue=maxvalue   'if "buttonvalue" goes below its minimum, or 255 if the minimum is 0, then make it equal to "maxvalue"
                          
        read_data=1               'use ldata table for print routine
      row=1               'print on line 1 of LCD
      printposition=13      'start position on LCD for the menu
      printend=16            'last character position on LCD for the menu      
      printaddress=index*4   'work out start position of data in ldata table
      gosub print_eeprom      'jump to LCD print routine
                     
       
       if index=0 then year=buttonvalue:gosub print_year
      if index=1 then month=buttonvalue:gosub print_month
      if index=2 then date=buttonvalue:gosub print_date
      if index=3 then day=buttonvalue:gosub print_day
      if index=4 then hour=buttonvalue:gosub print_hour
      if index=5 then minute=buttonvalue:gosub print_min
      if index=6 then second=buttonvalue:gosub print_time      
                                           
       if setup=0 then delayms 200:return                            
       goto buttons      

       edata 0,0,0,"MonTueWedThuFriSatSunJanFebMarAprMayJunJulAugSepOctNovDec"
      
      menu_list:ldata "YearMnthDateDay HourMin  Sec"
              
       end         

oku:
          RST = 1         ' Ready for transfer
       shout IO, SCLK, LSBFIRST, [$bf]      ' Read all 8 RTC registers in burst mode
       shin IO, SCLK, LSBPRE, [second, minute, hour, date, month, day, year, control]
       RST = 0         ' Reset RTC                                
        return
yaz:
       RST = 1         ' Ready for transfer
       ' Enable write
       shout IO, SCLK, LSBFIRST, [$8e, 0]
       RST = 0         ' Reset RTC
       RST = 1         ' Ready for transfer
       ' Write all 8 RTC registers in burst mode
       shout IO, SCLK, LSBFIRST, [$be, second, minute, hour, date, month, day, year, 0]
       RST = 0         ' Reset RTC                  
        return
       

       
  sec:  if setup=0 then sec
   cls: sel=0 :print at 1,3,"**SETUP**"
     
sec1:  delayms 5 :      
      if setup=0 then bekle1
      goto sec1
bekle1: delayms 50
      if setup=1 then
      inc sel:say=0:endif
      if sel>2 then sel=1
      if say>250 then say=0
      'print at 1,1,dec2 sel
      if sel=1 then  print at 2,3,"set_time"
      if sel=2 then  print at 2,3,"set_alrm"        
     
      if setup=0 and sel>=1 then inc say
      'print at 1,13,dec say
      if sel=1 and say>20 then return 'then print at 1,3,"****time" 'return
      if sel=2 and say>20 then return 'then print at 1,3,"***alarm" 'return
       
       goto sec1
     
     
     

'***********************************************************************************************
'***********************************************************************************************
'***********************************************************************************************


print_eeprom1:
         repeat
              if read_data=0 then character=eread printaddress         'use eeprom for data retrieval
              if read_data=1 then character=lread menu_list1+printaddress   'use ldata for data retrieval
              
              print at row,printposition,character               'print to the LCD
   
              inc printposition                              'move print position one to the right
              inc printaddress                              'point to the next position in the table

         until printposition=printend+1                        'end loop when all characters have been printed
         
         return                    

print_timealr:
         print at 1,11,dec2 secondalr
        
print_minalr:
         print at 1,8,dec2 minutealr,":"
        
print_houralr:     
         print at 1,5,dec2 houralr,":"
                  
print_dayalr:      
         read_data=0                      'use eeprom for data reading
         row=2                            'print on line 2 of LCD
         printposition=1               'initial position of "day" on LCD
         printend=3                     'position of last letter to be printed   
         printaddress=dayalr*3            'work out address of data in the eeprom(minimum is 3)

         gosub print_eeprom1            'goto LCD print routine
        
         return
       '**************************************************************************  
alr_set: print at 1,1,"SET"  
       if setup=0 then goto alr_set  'debounce button if still pressed from previous routine
      cls      
            
      print at 2,13,"ALR"
                  
      buttonvalue=dayalr:index=0:maxvalue=7:minvalue=1:gosub buttons1:dayalr=buttonvalue           'change the DAY
      buttonvalue=houralr:index=1:maxvalue=23:minvalue=0:gosub buttons1:houralr=buttonvalue           'change the HOUR
      buttonvalue=minutealr:index=2:maxvalue=59:minvalue=0:gosub buttons1:minutealr=buttonvalue        'change the MINUTE
      buttonvalue=secondalr:index=3:maxvalue=59:minvalue=0:gosub buttons1:secondalr=buttonvalue
                        
      print at 2,1,"'Setup' to Start"
      
restart1:
      'wait until the "setup" button is pressed before starting the clock
      if setup=0 then
       cls
       gosub epromyaz                      
       goto display_time      
       endif
       goto restart1        
     
     epromyaz:    
               ewrite $78,[secondalr,minutealr,houralr,dayalr]
        return
     
     epromoku:
              secondalr=eread $78
              minutealr=eread $79
              houralr=eread $7a
              dayalr=eread $7b
         return
                                                                 
     alrmkont:
             if  secondalr=second and minutealr=minute and houralr=hour and dayalr=day then  alert                                  
              return
   
    alert: cls
          print at 1,1,"A-L-A-R-M"
          led=1
          delayms 700
           led=0
          cls
          RETURN              
         
   buttons1: if setup=0 then buttons1
      if up=0 then inc buttonvalue:delayms 200                          'if up button is pressed then increase "buttonvalue" by one
      if buttonvalue>maxvalue then buttonvalue=minvalue            'if "buttonvalue" goes above its maximum then make it equal to "minvalue"
      if down=0 then dec buttonvalue:delayms 200                  'if down button is pressed then decrease "buttonvalue" by one
      if buttonvalue<minvalue or buttonvalue=255 then buttonvalue=maxvalue   'if "buttonvalue" goes below its minimum, or 255 if the minimum is 0, then make it equal to "maxvalue"
      
      
      read_data=1               'use ldata table for print routine
      row=1               'print on line 1 of LCD
      printposition=14      'start position on LCD for the menu
      printend=16            'last character position on LCD for the menu      
      printaddress=index*4   'work out start position of data in ldata table
      gosub print_eeprom1      'jump to LCD print routine
                              
      if index=0 then dayalr=buttonvalue:gosub print_dayalr
      if index=1 then houralr=buttonvalue:gosub print_houralr
      if index=2 then minutealr=buttonvalue:gosub print_minalr
      if index=3 then secondalr=buttonvalue:gosub print_timealr                                 
       
       if setup=0 then delayms 200:return                            
       goto buttons1      
      
      menu_list1:ldata "Day HourMin Sec  "
              
       end   
       
test:
     if up=0 then led=1:return
   
teststop:      
         if down=0 then led=0:return

mmengi

DS1302 nin data sheet ini tekrar bir gözden geçirmeni öneririm. Programına baktım ama şunlarla ilgili bir ayar göremedim.

Alıntı YapCLOCK HALT FLAG
Bit 7 of the seconds register is defined as the clock halt flag. When this bit is set to logic 1, the clock
oscillator is stopped and the DS1302 is placed into a low-power standby mode with a current drain of less
than 100 nanoamps. When this bit is written to logic 0, the clock will start. The initial power on state is
not defined.


Alıntı Yap
TRICKLE CHARGE REGISTER
This register controls the trickle charge characteristics of the DS1302. The simplified schematic of
Figure 5 shows the basic components of the trickle charger. The trickle charge select (TCS) bits
(bits 4–7) control the selection of the trickle charger. In order to prevent accidental enabling, only a
pattern of 1010 will enable the trickle charger. All other patterns will disable the trickle charger. The DS1302 powers up with the trickle charger disabled. The diode select (DS) bits (bits 2–3) select whether
one diode or two diodes are connected between VCC2 and VCC1. If DS is 01, one diode is selected or if DS
is 10, two diodes are selected. If DS is 00 or 11, the trickle charger is disabled independently of TCS.
The RS bits (bits 0–1) select the resistor that is connected between VCC2 and VCC1.


1302 de şarj olabilen pil kullanılabilmekte ve bunun şarjı ile ilgili register düzenlemesini yapman gerekmekte. Ayrıca clock un durduğunu belirten bir register daha var bunuda programın başında kontrol etmen gerekli olurya pille çalışırken bir yerden bir işaret kapıp clock durabilir. Önce bunu bir kontrol et herşeye eminsen yani clock duruyormu.

tapir

sayın mmengi
 ilgine teşekkürler aşagıdaki komut satırını yazıp programın başında gosub ile buraya yolladığımda sorun çözüldü aslında daha öncede bu satırları yazıp denemiştim ama olmamıştı belkide bir yanlışlık yapmıştım neyse şimdi herşey tamam
çalışmanızda başarılar





trickle:
   RST = 1 ' Ready for transfer
Shout IO, SCLK, LSBFIRST, [$8E, $0] ' Enable write, control = 0
RST = 0 ' Reset RTC
RST = 1 ' Ready for transfer
Shout IO, SCLK, LSBFIRST, [$90,$A5] 'Write trickle = %10100101
RST = 0
   return