Sevgili dostlar. Sizlerden ricam , Piyasada rahatça bulabileceğimiz , mikroişlemci ile haberleşmesi kolay , ucuz Real time clock entegreleri biliyorsanız yazarsanız sevinirim. Daha önce kullandığım Oki m6242 entegresi artık yokmuş , tasarımı ona göre yaptığım için problem oluştu. DS1302 piyasada yok olduğunu söylediler. Aslında dallasın entegreleri güzel ama bulabilirmiyiz bilmiyorum. İlginiz için teşekkürler.
ds serisi alıp denemiştim.Standart sapması çok fazla %2 idi hatırladığım kadarıyla.ben pcf8583 kullanıyorum çok güzel hem de I2c.takvim kullanacaksan (otomatik gün takibi yani) pcf için rutin kullanman gerekli çünkü yıl yazacı yalnızca artıkyıl (4 yıl) kaydı tutuyor.ucuzluğu konusunda bir şey söyleyemem.bana göre çok ucuz.sanıyorum 1,5 dolar civarı.
dostum mhk dediğin gibi DS1302 piyasa bulmak zor ben türkiye temsilcisinden numune aldım.Onun yerine DS1307 de kullanabilirsin.Piyasada bulunuyor fakat backup pilini şarj etmiyor ama pekte gerek kalmıyor lityum pil ile 5 seneden fazla bilgi koruması sağlıyor.BABA'nın dediği gibi pcf8583 daha akıllı alarm özelliğide olması gerekiyor.
iyi çalışmalar.
Selam beyler
DS1302 bulunmaz bir entegre değil isteyene kıyamet gibi bulabiliriz.
Eğer moderatör arkadaşlar reklam saymazlarsa
İzmirde 2.Onur handa İNT-KOM Elektronikte var.
Tel 232-4259865
Ben onu kullanıyorum. Pek sapmasını göremedim. Eğer datasheetindeki kristal bağlantı önerilerini takip ederseniz sorunsuz çalışıyor. 1 faratlık bie süper kapasitör ile 2000 saat bilgiyi saklayabiliyor...
Tüm açıklamalar için teşekkür ederim. İyi çalışmalar dilerim.
arkadaslarında soyledigi gibi pcf8583 güzel. Picbasic pronun I2C komutuyla gayet guzel calısıyor. RTC veya Counter modu var , Yıllara gore alarm kura biliyorsun. tek sorun yılı artık yıl olarak vermesi onuda Program kodu içine basit bir dongu ekleyerek
çözebilirsin.
Lazım olursa:4'e tam olarak bölünebilen yıllar artık yıldır. Ayrıca bir sayının son iki rakamı dörde bölünebiliyorsa tamamı da bölünür. Örneğin 1916 artık yıldır.
I2c haberleşmisi yapan bu rtc elemanlarının hızı jakkında ne yazabilirsiniz. Örneğin yüksek hızlı bir taramalı sistemde ( 1000 hz gibi ) okuma ve yazma için ne kadar süre gerekli. Sonuçta bunlar seri olarak haberleştikleri için hızda bir düşme olacaktır. Seri eeprom kulanırken yazmak için minimum 2 msn gerekli . 8 Kbyte (8192byte ) yazmak için gerekli süre , 16384 msn= 16,384 saniye. Uzun bir bekleme süresi. Bu taramalı sistemde bu bekleme çok fazla. Bu rtc yi kullanan arkadaşlar, seri eepromdaki özelliğe mi sahip. Yani okuma ve yazma için min 2 msn mi gerekli? Umarım anlatabilmişimdir. Teşekkürler.
dallas ın ds12887 cipi ne bakın cmos ram ve realtimer dır ve alarm özellipği var.
Sevgili Arkadaşlar. DS1307 yada PCF8583 RTC chiplerininin pic basic pro ile yazılmış örnek programlar varsa yazabilirseniz sevinirim. Ben yeni aldığım için okutup yazamadım. Sorunun parazitten kaynaklandığını sanıyorum. SDA ve SCL uçlarına eğer taktıysanız , taktığınız kondansatörün değeri nedir. Teşekkürler.
dostum scl ve sda uçlarına bir şey bağlamıyorsun pic in ilgili portuna direk giriyorsun sadece bu portları 10K ile pullup yapıyorsun. aşağıdaki kod biraz uzun ama incelersen çok faydalı olacağına inanıyorum. programda BCD çevrimide var.
'
' Project MN1307
' ==============
' Embedded Software Version 1.00
' Target Processor PIC16F628-04/SP
' Target PCB - BB-01
' Created 12/06/02
' Last Updated 12/06/02
' Written by Melanie Newman
'
' DS1307 RTC Program
' Includes Setting the Date and Time
' 3 Buttons Control Setting...
' 12/24 hour Clock Mode
' Year
' Month
' Day of Month (also accounting for Leap Years)
' Hour
' Minute
' Second
'
' Written for 2 line 16 Character LCD
'
' This program is designed to "hold your hand" and prevent you
' from setting any invalid data combinations into the DS1307
'
' It's a crude program, but demonstrates how to set the clock
' with control buttons
'
' You will be automatically returned to the Time & Date display if
' you are in the Setup and don't touch any Buttons for 20 seconds
'
'
' Device Programming Options
' --------------------------
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT
' System Clock Options
@ DEVICE pic16F628, WDT_ON
' Watchdog Timer
@ DEVICE pic16F628, PWRT_ON
' Power-On Timer
@ DEVICE pic16F628, BOD_ON
' Brown-Out Detect
@ DEVICE pic16F628, MCLR_OFF
' Master Clear Options (Internal)
@ DEVICE pic16F628, LVP_OFF
' Low-Voltage Programming
@ DEVICE pic16F628, CPD_OFF
' Data Memory Code Protect
@ DEVICE pic16F628, PROTECT_OFF
' Program Code Protection
'
' Hardware Assignments
' --------------------
'
' System LCD
' ----------
' No Resistors required on any line
' RA0-RA3 Data bits DB0-DB3
' RA6 RS-bit
' RA7 E-Bit
'
Define LCD_DREG PORTA ' Port for LCD Data
Define LCD_DBIT 0 ' Use lower 4 bits of Port
Define LCD_RSREG PORTA ' Port for RegisterSelect (RS) bit
Define LCD_RSBIT 6 ' Port Pin for RS bit
Define LCD_EREG PORTA ' Port for Enable (E) bit
Define LCD_EBIT 7 ' Port Pin for E bit
Define LCB_BITS 4 ' Using 4-bit bus
Define LCD_LINES 2 ' Using 2 line Display
Define LCD_COMMANDUS 2000
' Command Delay (uS)
Define LCD_DATAUS 50 ' Data Delay (uS)
'
' DS1307 Connections
' ------------------
' 10K Resistors required from PORTB.1 and PORTB.2 to Vdd
' PORTB.0 relies on weak pull-up's (for future use)
'
SQWpin var PORTB.0
' You don't actually need to wire this pin... but...
' If you're observant, you'll notice I've wired the DS1307's
' SQW to RB0. Rather than 'poll' and display the time/date
' as in this example code, you can have an interrupt
' on RB0 each second to do this. In fact if you look at
' my code for setting the DS1307 you'll see I've already
' programmed it for a 1 second 'Tick' for exactly this
' purpose...
SCLpin var PORTB.1
SDApin var PORTB.2
'
' Setting Buttons
' ---------------
' Buttons are connected between PORTB.4, 5 & 6 down to Vss
' No Resistors required - we're using weak pull-up's
'
DecButton var PORTB.4 ' Press to Decrement Button
SetButton var PORTB.5 ' Press to Set/memorise Button
IncButton var PORTB.6 ' Press to Increment Button
'
' Unused Ports
' ------------
' RA4
' RA5
' RB3
' RB7
'
' EEPROM Locations
' ----------------
Data @0,74,97,110,70,101,98,77,97,114,65,112,114
' Jan Feb Mar Apr
Data 77,97,121,74,117,110,74,117,108,65,117,103
' May Jun Jul Aug
Data 83,101,112,79,99,116,78,111,118,68,101,99
' Sep Oct Nov Dec
Data 84,117,101,87,101,100,84,104,117,70,114,105
' Tue Wed Thu Fri
Data 83,97,116,83,117,110,77,111,110
' Sat Sun Mon
'
' RAM Assignments and Variables
' -----------------------------
CounterA var byte ' General purpose Variable
CounterB var byte ' General purpose Variable
CounterC var byte ' General purpose Variable
CounterD var byte ' General purpose Variable
RTCSec var byte ' Seconds
RTCMin var byte ' Minutes
RTCHour var byte ' Hours
RTCWDay var byte ' Weekday
RTCDay var byte ' Day
RTCMonth var byte ' Months
RTCYear var byte ' Year
RTCCtrl var byte ' Control
SetTime var byte ' 12/24 Hour Clock
SetSec var byte ' Seconds
SetMin var byte ' Minutes
SetHour var byte ' Hours
SetDay var byte ' Day
SetMonth var byte ' Months
SetYear var byte ' Year
TimeOut var word ' Variable for SetUp Menu Time-Out
'
' Program Constants
' -----------------
ButtonRepeat con 200 ' Timeperiod (in mS for Edit Buttons auto-repeat
' should you want to hold them down...
'
' Start Program
' =============
goto JumpStart
'
' Subroutine Nest Area
' ====================
'
' Subroutine Converts back to BCD
' -------------------------------
' CounterA is the entry variable
' CounterB holds the converted BCD result on exit
ConvertBCD:
CounterB=CounterA DIG 1
CounterB=CounterB<<4
CounterB=CounterB+CounterA DIG 0
Return
'
' Subroutine Displays Month at current Cursor Position
' ----------------------------------------------------
' CounterB holds Month (1-12) this value is destroyed by the routine
' additionally uses CounterA and CounterD variables
DisplayMonth:
CounterB=CounterB*3-3 ' Convert BCD Month to EEPROM Start Address
DisplaySequence:
For CounterA=CounterB to CounterB+2
' Read and Display Month
Read CounterA,CounterD
LCDOut CounterD
Next CounterA
Return
'
' Subroutine works out Number of Days in the Month
' ------------------------------------------------
' SetYear - entry variable containing year (0-99)
' SetMonth - entry Variable Containing Month (1-12)
' CounterA - exits with number of days
FindDays:
LookUp SetMonth-1,[31,28,31,30,31,30,31,31,30,31,30,31],CounterA
' Above line gives the 'usual' days of the Month
' Section below adjusts for Leap-Year
If SetMonth=2 then
If (SetYear&$03)=0 then CounterA=29
endif
Return
'
' Subroutine waits until user reseases Set Button
' -----------------------------------------------
SetButtonRelease:
LCDOut $FE,1
While SetButton=0:Wend
Pause 250 ' Small pause to kill any Key-Bounce
Return
'
' End of Subroutine Nest Area
' ---------------------------
'
' Actual Start of Real Program
' ============================
JumpStart:
'
' Set Hardware Directions
' -----------------------
CMCON=%00000111 ' Disable Comparators
TRISA=%00000000 ' PORTA all set to Output
TRISB=%11111111 ' PORTB all set to Input
OPTION_REG.7=0 ' Enable Weak Pull-Ups
'
' Reset Hardware
' --------------
Pause 200 ' Timeout for LCD to settle
'
' Time & Date Display Loop
' ========================
ReDisplay:
LCDOut $FE,1 ' Clear LCD
ReDisplayLoop:
'
' Read RTC
' --------
I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl]
'
' Decide if Setup Required/Wanted
' -------------------------------
If RTCSec.7=1 then goto SetUpPreset
' Hands-Up who noticed the fact that when the DS1307
' powers-up initially from cold, and all it's
' registers are potentially "unpredictable", that
' Seconds bit 7 is always high?
' We can use this feature to automatically jump to
' our 'Setup' routine on initial power-up if the user
' forgets to keep 'Setup' depressed and so prevent
' any 'undesriable' Time & Date displays...
If SetButton=0 then
' If Set Button is pressed, User will be taken to
' the Setup Menu. If the Set Button is pressed at
' Power-Up, then the User will be taken to the Setup
' Menu directly without any intermediate display
Gosub SetButtonRelease
goto Setup
endif
'
' Display RTC
' -----------
' Displayed on 2-line 16 character LCD in the form...
' 10:15:00 AM
' Wed 12 Jun 2002
' Note - AM/PM indicator only shows in 12 hour mode.
' Additionally there is Hours leading Zero Surpression in 12-Hour Mode
' after-all, you don't display 07pm do you?
'
'
' Display Time on Line 1
' ----------------------
LCDOut $FE,$80
If RTCHour.6=1 then
' Work-Out 12 or 24 hour Display for Hours
CounterA=(RTCHour>>4)&$01
else
CounterA=(RTCHour>>4)&$03
endif
CounterA=CounterA*10+(RTCHour&$0F)
If RTCHour.6=1 then
' Display Hours appropriately for 12 or 24 hour Mode
LCDOut #CounterA
else
LCDOut #CounterA Dig 1,#CounterA Dig 0
endif
LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,":"
LCDOut #(RTCSec>>4)&$0F,#RTCSec&$0F," "
IF RTCHour.6=1 then
If RTCHour.5=1 then
LCDOut "PM"
else
LCDOut "AM"
endif
endif
'
' Display Day of Week on Line 2
' -----------------------------
' Let's face it... the DS1307 doesn't calculate the Day of Week,
' all it does is increment a number at each mignight from
' 1 thru 7 and roll back to start from 1 all over again.
' It's really up to you to work out the DOW and program it in.
' This is a tough nut for integer math to do... see the
' 'Calculate Day of Week' routine in the setup section.
LCDOut " ",$FE,$C0
CounterB=RTCWDay*3+33 ' Convert BCD WeekDay to EEPROM Start Address
Gosub DisplaySequence ' Display 3 character sequence from EEPROM
'
' Display Date on Line 2
' ----------------------
LCDOut " ",#(RTCDay>>4)&$0F,#RTCDay&$0F," "
CounterB=((RTCMonth>>4)&$0F)*10+(RTCMonth&$0F)
Gosub DisplayMonth
LCDOut " 20",#(RTCYear>>4)&$0F,#RTCYear&$0F,$FE,$80
'
Pause 250 ' Repeat about 4 times/sec
Goto ReDisplayLoop
'
' Clock and Calandar Settings
' ===========================
'
' Initial Default Settings
' ------------------------
' Default setting preset to the moment this program first born
'
SetupPreset:
RTCSec=$00 ' Seconds preset to 00
RTCMin=$15 ' Minutes preset to 15
RTCHour=$13 ' Hours preset to 13'00
RTCWDay=$01 ' Weekday preset to 01
RTCDay=$12 ' Day preset 12
RTCMonth=$06 ' Months preset to June
RTCYear=$02 ' Year preset to 2002
RTCCtrl=$10 ' Control preset to output 1 second 'Tick' on SQWpin
'
' Convert the Current BCD Data to Something easier to Edit
' --------------------------------------------------------
Setup:
SetTime=RTCHour.6 ' Determines 12/24 Hour mode
If SetTime=1 then
' Regardless of 12/24 options, SetHour always
' contains the hours in 24 hour clock format
' otherwise there's twice the amount of work
' to keep track in the edit routines
SetHour=(RTCHour>>4)&$01
' if 12-hour mode
else
SetHour=(RTCHour>>4)&$03
' if 24 hour mode
endif
SetHour=SetHour*10+(RTCHour&$0F)
If SetTime=1 then
If RTCHour.5=1 then
If SetHour<12 then SetHour=SetHour+12
' Add-in the AM/PM indicator
else
If SetHour=12 then SetHour=0
endif
endif
SetMin=((RTCMin>>4)&$0F)*10+(RTCMin&$0F)
SetSec=((RTCSec>>4)&$0F)*10+(RTCSec&$0F)
SetYear=((RTCYear>>4)&$0F)*10+(RTCYear&$0F)
SetMonth=((RTCMonth>>4)&$0F)*10+(RTCMonth&$0F)
SetDay=((RTCDay>>4)&$0F)*10+(RTCDay&$0F)
'
' Setup Menu Loop
' ---------------
CounterC=0 ' Set to Start of Setup (seven steps from 0 to 6)
TimeOut=0 ' Zero the Time-Out counter
SetupLoop:
LCDOut $FE,1,"Set "
'
' First Display the Menu Prompts
' ------------------------------
' This is a crude way of doing the entry Menu's but it was
' pretty fast and quite mindless to program this lunch-hour
'
If CounterC=0 then
LCDOut "Mode"
endif
If CounterC=1 then
LCDOut "Hours"
endif
If CounterC=2 then
LCDOut "Minutes"
endif
If CounterC=3 then
LCDOut "Seconds"
endif
If CounterC=4 then
LCDOut "Year : 20"
endif
If CounterC=5 then
LCDOut "Month"
endif
If CounterC=6 then
LCDOut "Day"
endif
If CounterC<>4 then LCDOut " :"
'
' Now Display the Data
' --------------------
SetupDisplayLoop:
'
' 12/24 Hour Option
' -----------------
If CounterC=0 then
LCDOut $FE,$8B
If SetTime=0 then
LCDOut "24HR"
else
LCDOut "12HR"
endif
LCDOut $FE,$8B
endif
' Hours
' -----
' Hours are tricky because of the 12/24 & AM/PM bit
' so we have to reconvert 1-24 back to 1-12 plus AM/PM
If CounterC=1 then
CounterA=SetHour
If SetTime=1 then
LCDOut $FE,$8E
' Display AM/PM bit
If CounterA<12 then
LCDOut "AM"
else
LCDOut "PM"
endif
If CounterA=0 then CounterA=12
If CounterA>12 then CounterA=CounterA-12
endif
LCDOut $FE,$8C,#CounterA
If CounterA<10 then LCDOut " "
LCDOut $FE,$8C
endif
'
' Minutes
' -------
If CounterC=2 then
LCDOut $FE,$8E,#SetMin
If SetMin<10 then LCDOut " "
LCDOut $FE,$8E
endif
'
' Seconds
' -------
If CounterC=3 then
LCDOut $FE,$8E,#SetSec
If SetSec<10 then LCDOut " "
LCDOut $FE,$8E
endif
'
' Year
' ----
If CounterC=4 then
LCDOut $FE,$8D,#SetYear DIG 1,#SetYear Dig 0
LCDOut $FE,$8D
endif
'
' Month
' -----
' Here's a nice touch to setting the month rather
' than the usual number entry method...
'
If CounterC=5 then
LCDOut $FE,$8C
CounterB=SetMonth
Gosub DisplayMonth
LCDOut $FE,$8C
endif
'
' Day
' ---
If CounterC=6 then
LCDOut $FE,$8A,#SetDay
If SetDay<10 then LCDOut " "
LCDOut $FE,$8A
endif
'
' The Data-Entry Bit
' ------------------
SetupEntryLoop:
'
' Decrement Button Pressed
' ------------------------
If DecButton=0 then
'
' 12/24 Clock Selection
' ---------------------
If CounterC=0 then
If SetTime=0 then
SetTime=1
else
SetTime=0
endif
endif
'
' Decrement Hours
' ---------------
If CounterC=1 then
If SetHour=0 then
SetHour=23
else
SetHour=SetHour-1
endif
endif
'
' Decrement Minutes
' -----------------
If CounterC=2 then
If SetMin=0 then
SetMin=59
else
SetMin=SetMin-1
endif
endif
'
' Decrement Seconds
' -----------------
' Kinda overkill to include setting seconds,
' but if you got codespace to burn...
If CounterC=3 then
If SetSec=0 then
SetSec=59
else
SetSec=SetSec-1
endif
endif
'
' Decrement Years
' ---------------
If CounterC=4 then
If SetYear=0 then
SetYear=99
else
SetYear=SetYear-1
endif
endif
'
' Decrement Month
' ---------------
If CounterC=5 then
If SetMonth=1 then
SetMonth=12
else
SetMonth=SetMonth-1
endif
'
' Changing the Month has a bearing on the
' days, especially if you've got days preset
' to 31 and you now select a month with fewer
' days... so this bit here just prevents that
Gosub FindDays
If SetDay>CounterA then SetDay=CounterA
endif
'
' Decrement Days
' --------------
' Tricky one here... go work-out the days
' of the month first...
If CounterC=6 then
Gosub FindDays
If SetDay=1 then
SetDay=CounterA
else
SetDay=SetDay-1
endif
endif
Pause ButtonRepeat
TimeOut=0
Goto SetUpDisplayLoop
endif
'
' Increment Button Pressed
' ------------------------
' This is just like Decrement but opposite...
If IncButton=0 then
'
' 12/24 Clock Selection
' ---------------------
If CounterC=0 then
If SetTime=1 then
SetTime=0
else
SetTime=1
endif
endif
'
' Increment Hours
' ---------------
If CounterC=1 then
If SetHour=23 then
SetHour=0
else
SetHour=SetHour+1
endif
endif
'
' Increment Minutes
' -----------------
If CounterC=2 then
If SetMin=59 then
SetMin=0
else
SetMin=SetMin+1
endif
endif
'
' Increment Seconds
' -----------------
' Kinda overkill to include setting seconds,
' but if you got codespace to burn...
If CounterC=3 then
If SetSec=59 then
SetSec=0
else
SetSec=SetSec+1
endif
endif
'
' Increment Years
' ---------------
If CounterC=4 then
If SetYear=99 then
SetYear=0
else
SetYear=SetYear+1
endif
endif
'
' Increment Month
' ---------------
If CounterC=5 then
If SetMonth=12 then
SetMonth=1
else
SetMonth=SetMonth+1
endif
'
' Changing the Month has a bearing on the
' days, especially if you've got days preset
' to 31 and you now select a month with fewer
' days... so this bit here just prevents that
Gosub FindDays
If SetDay>CounterA then SetDay=CounterA
endif
'
' Increment Days
' --------------
' Tricky one here... go work-out the days
' of the month first...
If CounterC=6 then
Gosub FindDays
If SetDay=>CounterA then
SetDay=1
else
SetDay=SetDay+1
endif
endif
Pause ButtonRepeat
TimeOut=0
Goto SetupDisplayLoop
endif
'
' Set Button Pressed
' ------------------
If SetButton=0 then
CounterC=CounterC+1
' Increment Menu Item
TimeOut=0
If CounterC>6 then
' Save Data if all edit items exhaused
LCDOut $FE,1,"Memorised"
' Make the User feel happy
'
' Save 12/24 Hours to BCD DS1307's Format
' ---------------------------------------
CounterA=SetHour
If SetTime=1 then
If CounterA>12 then CounterA=CounterA-12
If CounterA=0 then CounterA=12
endif
Gosub ConvertBCD
RTCHour=CounterB
' Save the Hours Value
If SetTime=1 then
RTCHour.6=1
' Save the 12 Hour Mode Flag
If SetHour=>12 then RTCHour.5=1
' Save the 'PM' Flag
endif
'
' Save Minutes
' ------------
CounterA=SetMin
Gosub ConvertBCD
RTCMin=CounterB
'
' Save Seconds
' ------------
CounterA=SetSec
Gosub ConvertBCD
RTCSec=CounterB
'
' Save Year
' ---------
CounterA=SetYear
Gosub ConvertBCD
RTCYear=CounterB
'
' Save Month
' ----------
CounterA=SetMonth
Gosub ConvertBCD
RTCMonth=CounterB
'
' Save Day
' --------
CounterA=SetDay
Gosub ConvertBCD
RTCDay=CounterB
'
' Calculate Day of Week & Save
' ----------------------------
' Melanie's fudge for calculating Days of Week
' using PBP's integer math...
' by the time someone's clock displays the
' the wrong Day of Week, I'll hopefully have long
' retired and be past caring...
' I wouldn't however go stick this routine in a
' Nuclear Power Station to purge the reactor
' every Monday morning without checking how far it
' will work before the integer math overflows...
' In my routine RTCWDay=1 is a Tuesday (the
' start of my week) and continues sequentially
' until RTCWDay=7 which is a Monday
CounterA=SetYear+4
CounterB=SetMonth
If SetMonth<3 then
CounterA=CounterA-1
CounterB=CounterB+12
endif
CounterD=(SetDay+(153*CounterB-457)/5+365*CounterA+CounterA/4-CounterA/100+CounterA/400+2) MOD 7
RTCWDay=CounterD+1
'
' Do the Business
' ---------------
I2CWrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl]
Pause 1000
Gosub SetButtonRelease
Goto ReDisplay
endif
Gosub SetButtonRelease
Goto SetupLoop ' Loop for Next Menu Item
endif
'
' Menu TimeOut Counter
' --------------------
Pause 1 ' Kill 1mS
TimeOut=TimeOut+1
If TimeOut>20000 then goto ReDisplay
' User paused too long
' Return User to Time & Date Display
' This will however bounce the User to the original
' Setup Menu start point if the DS1307 has not
' been initialised
Goto SetupEntryLoop ' Loop for Button Press
'
End
başka bir örnek daha
;-----------------------Copyright 2002, High-TechGarage.com-----------------------
;
; This program will interface with the DS1307, I2C Real-Time Clock from
; Dallas Semiconductor. P0 is used as SDA (serial data) and P1 is used as
; SCL (serial clock). This ATOM software is part of a tutorial available
; on our website: http://www.high-techgarage.com/tutorial/ds1307.php
;
; The RTC will set if memory location 0 on the ATOM is set to 0. To set
; the clock run a program which sets EEPROM location 0 to 0. The program is
; only 1 line: write 0,0. Finally change the time and date below and run this
; program.
;
; Revision: 1.0
; Date: 03/22/02
;
;-----------------------------------DS1307.bas------------------------------------
clear ; clear all variables
SDA con P0 ; 2-wire serial data
SCL con P1 ; 2-wire serial clock
; --{ I2C Definitions }-----------------------------------------------------------
RTC con %11010000 ; RTC device address (byte addressing)
; --{ RTC definitions }-----------------------------------------------------------
SecReg con $00 ; seconds address (00 - 59)
; MSB of SecReg must be set to a 0 to enable RTC
MinReg con $01 ; minutes address (00 - 59)
HourReg con $02 ; hours address (01 - 12) or (00 - 23)
DayReg con $03 ; day address (1 - 7)
DateReg con $04 ; date address (01 - 28/29, 30, 31)
MonthReg con $05 ; month address (01 - 12)
YearReg con $06 ; year address (00 - 99)
ContReg con $07 ; control register
RTCflag con 0 ; RTC flag (location 0 of BS2 EEPROM)
RTCset var bit ; bit to check if RTC has been set
; The constants below set the RTC to: 12:35:00 on Friday, March 22nd, 2002
_sec con $00 ; set seconds to 00 (enables the oscillator)
_min con $35 ; set minutes to 35
_hr con $12 ; set hour to 12 (noon)
_day con $06 ; set day to 6 (Friday)
_date con $22 ; set date to 22 (22nd)
_mon con $03 ; set month to 3 (March)
_yr con $02 ; set year to 2002
; The control register is used to control the operation of the SQW/OUT pin
; Starting with the MSB (Bit 7) -> OUT x x SQWE x x RS1 RS0 <- (Bit 0)
; OUT: if SQWE=0, the logic level on SQW/OUT pin is 1 if OUT=1 and is 0 if OUT=0.
; SQWE: square wave enable. 1->enabled 0->disabled
; RS1, RS0: rate select. 00->1Hz, 01->4.096kHz, 10->8.192kHz, 11->32.768kHz
cntrl con %00010000 ; sets the SQW/OUT to 1Hz pulse, logic level low
; --{ General Variables }---------------------------------------------------------
sec var byte ; seconds
min var byte ; minutes
hr var byte ; hours
day var byte ; day
date var byte ; date
mon var byte ; month
yr var byte ; year
; --{ Check to see if clock is set }----------------------------------------------
pause 100 ; let everything settle down
write 0, 0
read RTCflag, RTCset ; check to see if the clock has already been set
if RTCset = 0 then SetTimeAndDate ; if it is 0, we need to set the clock
;===[ MAIN PROGRAM STARTS HERE ]==================================================
; The main program is just a loop which gets the current time, then displays it
; on the debug screen.
Loop: ; Loop to display the time
i2cin SDA, SCL, RTC, SecReg, [sec,min,hr,day,date,mon,yr]
debug ["Current Time:", 13]
debug ["-------------------", 13]
debug [hex hr, ":", hex min, ":", hex sec, 13]
pause 1000
goto Loop
end
;===[ MAIN PROGRAM ENDS HERE ]=====================================================
;--{ Set time and date on RTC subroutine }-----------------------------------------
SetTimeAndDate:
i2cout SDA, SCL, RTC, SecReg, [_sec,_min,_hr,_day,_date,_mon,_yr,cntrl]
pause 10
write RTCflag, 1 ; set the flag so we don't reset the clock
goto Loop
ds 1302 için örnek
' LCD clock program using Dallas1202/1302 RTC
' Define LOADER_USED to allow use of the boot loader.
' This will not affect normal program operation.
Define LOADER_USED 1
Include "MODEDEFS.BAS" ' Include Shiftin/out modes
Define LCD_DREG PORTD ' Define LCD connections
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
' Alias pins
RST var PORTA.2
IO var PORTC.1
SCLK var PORTC.3
' Allocate variables
rtcyear var byte
rtcday var byte
rtcmonth var byte
rtcdate var byte
rtchr var byte
rtcmin var byte
rtcsec var byte
rtccontrol var byte
Low RST ' Reset RTC
Low SCLK
ADCON1 = 7 ' PORTA and E digital
Low PORTE.2 ' LCD R/W low = write
Pause 100 ' Wait for LCD to startup
' Set initial time to 8:00:00AM 07/16/99
rtcyear = $99
rtcday = $06
rtcmonth = $07
rtcdate = $16
rtchr = $08
rtcmin = 0
rtcsec = 0
Gosub settime ' Set the time
Goto mainloop ' Skip subroutines
' Subroutine to write time to RTC
settime:
RST = 1 ' Ready for transfer
' Enable write
Shiftout IO, SCLK, LSBFIRST, [$8e, 0]
RST = 0 ' Reset RTC
RST = 1 ' Ready for transfer
' Write all 8 RTC registers in burst mode
Shiftout IO, SCLK, LSBFIRST, [$be, rtcsec, rtcmin, rtchr, rtcdate, rtcmonth, rtcday, rtcyear, 0]
RST = 0 ' Reset RTC
Return
' Subroutine to read time from RTC
gettime:
RST = 1 ' Ready for transfer
Shiftout IO, SCLK, LSBFIRST, [$bf] ' Read all 8 RTC registers in burst mode
Shiftin IO, SCLK, LSBPRE, [rtcsec, rtcmin, rtchr, rtcdate, rtcmonth, rtcday, rtcyear, rtccontrol]
RST = 0 ' Reset RTC
Return
' Main program loop - in this case, it only updates the LCD with the time
mainloop:
Gosub gettime ' Read the time from the RTC
' Display time on LCD
Lcdout $fe, 1, hex2 rtcmonth, "/", hex2 rtcdate, "/" , hex2 rtcyear,_
" ", hex2 rtchr, ":", hex2 rtcmin, ":", hex2 rtcsec
Pause 300 ' Do it about 3 times a second
Goto mainloop ' Do it forever
End
ÇOK YER KAPLADIM AMA BİR ÖRNEK DAHA DS1302 İÇİN
' LCD clock program using Dallas1202/1302 RTC
Include "MODEDEFS.BAS" ' Include Shiftin/out modes
Define LCD_DREG PORTD ' Define LCD connections
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
' Alias pins
RST var PORTA.2
IO var PORTC.1
SCLK var PORTC.3
' Allocate variables
rtcyear var byte
rtcday var byte
rtcmonth var byte
rtcdate var byte
rtchr var byte
rtcmin var byte
rtcsec var byte
rtccontrol var byte
Low RST ' Reset RTC
Low SCLK
ADCON1 = 7 ' PORTA and E digital
Low PORTE.2 ' LCD R/W low = write
Pause 100 ' Wait for LCD to startup
' Set initial time to 8:00:00AM 07/16/99
rtcyear = $99
rtcday = $06
rtcmonth = $07
rtcdate = $16
rtchr = $08
rtcmin = 0
rtcsec = 0
Gosub settime ' Set the time
Goto mainloop ' Skip subroutines
' Subroutine to write time to RTC
settime:
RST = 1 ' Ready for transfer
' Enable write
Shiftout IO, SCLK, LSBFIRST, [$8e, 0]
RST = 0 ' Reset RTC
RST = 1 ' Ready for transfer
' Write all 8 RTC registers in burst mode
Shiftout IO, SCLK, LSBFIRST, [$be, rtcsec, rtcmin, rtchr, rtcdate,
rtcmonth, rtcday, rtcyear, 0]
RST = 0 ' Reset RTC
Return
' Subroutine to read time from RTC
gettime:
RST = 1 ' Ready for transfer
Shiftout IO, SCLK, LSBFIRST, [$bf] ' Read all 8 RTC registers
in burst mode
Shiftin IO, SCLK, LSBPRE, [rtcsec, rtcmin, rtchr, rtcdate, rtcmonth,
rtcday, rtcyear, rtccontrol]
RST = 0 ' Reset RTC
Return
' Main program loop - in this case, it only updates the LCD with the time
mainloop:
Gosub gettime ' Read the time from the RTC
' Display time on LCD
Lcdout $fe, 1, hex2 rtcmonth, "/", hex2 rtcdate, "/" , hex2
rtcyear,_
" ", hex2 rtchr, ":", hex2 rtcmin, ":", hex2 rtcsec
Pause 300 ' Do it about 3 times a second
Goto mainloop ' Do it forever
End
Dostum mmengi ilgin için gerçekten teşekkür ederim. Lakin verdiğin örnekler bende var. Kendimde kod geliştirdim lakin olmadı. Yani olmamasının nedenini biliyorum. Parazit... Çünkü başka bir devrede eepromu okuttuğum halde bu devrede eepromu bile okutamadım. Kaldıki RTC yi okutayım. Bunun için SDA ve SCL uçlarına paralel kondansatör girmeyi denedim lakin olmadı. Bunu şunun için yazıyorum, böyle parazitlerden çok kolay etkileniyorsa işimiz var. Belkide GND yi iyi yapamadığımızdan kaynaklanıyordur. Ayrıca I2c haberleşmesi yapan sistemleri mümkün mertebe bağlanacak uçlara yakın yapmak gerekiyor. Yinede ilgelendiğin için teşekkür ederim. İyi çalışmalar.
dostum beslemende bir problem olmasın lakin ben yukarıda verdiğim programları bread board üzerinde çalıştırdım pcb ye bile koymadım parazitten etkileniyor olsa illa sorun yaşardım aylarca bread bord üzerinde çalıştırdım. geri kalma vardı onuda 32khz lik kristali değiştirince sorun kalmadı. besleme devren eger trafolu ise GND sini şebekenin toprağına yada nötrüne bağla çünkü problem olabiliyor.
kolay gelsin.
http://undongle.newmail.ru/
burda pcf8583ün proteus model dosyası var.
Sevgili mmengi, sorunun ne olduğunu çözemedim. Aynı hat üzerinden At24c64 eepromu kolaylıkla okuyorum ve yazıyorum. İki adet RTC var elimde , biri DS1307 , diğeri PCF 8583 , ikisinde de olmuyor. Kendi yaptığım 16F877 deney setinde bunları kullanıyorum. yani PCB li, besleme devresine gelince onda da bir problem yok, benim kafam şu I2C protokolüne takıldı. Senin ve bendeki örnekler bu protokolü kullanıyor. Lakin olmadı. Senden ricam vereceğim aşağıdaki örnekleri bir incelemen. Hata yapmadığımı sanıyorum. Lakin olmazsa bende devreyi ilk önce bread board 'a kuracağım. ;)
' LCD clock program using Dallas1202/1302 RTC
Define osc 20
DEFINE I2C_SLOW 1
@ device WDT_OFF & pwrt_on
Define LCD_DREG PORTD ' Define LCD connections
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
'trisc=0
DEFINE I2C_SCL PORTC,3 ' For 12-bit core only
DEFINE I2C_SDA PORTC,4 ' For 12-bit core only
' Alias pins
'RST var PORTA.2
'IO var PORTC.1
'SCLK var PORTC.3
SCL var PORTC.3
SDA var PORTC.4
' Allocate variables
rtcyear var byte
rtcday var byte
rtcmonth var byte
rtcdate var byte
rtchr var byte
rtcmin var byte
rtcsec var byte
rtccontrol var byte
' Low RST ' Reset RTC
Low SCL
ADCON1 = 7 ' PORTA and E digital
Low PORTE.2 ' LCD R/W low = write
Pause 100 ' Wait for LCD to startup
' Set initial time to 8:00:00AM 07/16/99
rtcyear = $99
rtcday = $06
rtcmonth = $07
rtcdate = $16
rtchr = $08
rtcmin = 0
rtcsec = 0
GoSub settime ' Set the time
GoTo mainloop ' Skip subroutines
' Subroutine to write time to RTC
settime:
' RST = 1 ' Ready for transfer
' Enable write
' Shiftout SDA, SCL, LSBFIRST, [$8e, 0]
' RST = 0 ' Reset RTC
' RST = 1 ' Ready for transfer
' Write all 8 RTC registers in burst mode
Shiftout SDA, SCL, LSBFIRST, [$be, rtcsec, rtcmin, rtchr, rtcdate, rtcmonth, rtcday, rtcyear, 0]
' RST = 0 ' Reset RTC
Return
' Subroutine to read time from RTC
gettime:
' RST = 1 ' Ready for transfer
Shiftout SDA, SCL, LSBFIRST, [$bf] ' Read all 8 RTC registers in burst mode
Shiftin SDA, SCL, LSBPRE, [rtcsec, rtcmin, rtchr, rtcdate, rtcmonth, rtcday, rtcyear, rtccontrol]
' RST = 0 ' Reset RTC
Return
' Main program loop - in this case, it only updates the LCD with the time
mainloop:
GoSub gettime ' Read the time from the RTC
' Display time on LCD
Lcdout $fe, 1, hex2 rtcmonth, "/", hex2 rtcdate, "/" , hex2 rtcyear,_
" ", hex2 rtchr, ":", hex2 rtcmin, ":", hex2 rtcsec
Pause 300 ' Do it about 3 times a second
GoTo mainloop ' Do it forever
End
' LCD clock program using Dallas1202/1302 RTC
'Define osc 20
'
' Project MN1307
' ==============
' Embedded Software Version 1.00
' Target Processor PIC16F628-04/SP
' Target PCB - BB-01
' Created 12/06/02
' Last Updated 12/06/02
' Written by Melanie Newman
'
' DS1307 RTC Program
' Includes Setting the Date and Time
' 3 Buttons Control Setting...
' 12/24 hour Clock Mode
' Year
' Month
' Day of Month (also accounting for Leap Years)
' Hour
' Minute
' Second
'
' Written for 2 line 16 Character LCD
'
' This program is designed to "hold your hand" and prevent you
' from setting any invalid data combinations into the DS1307
'
' It's a crude program, but demonstrates how to set the clock
' with control buttons
'
' You will be automatically returned to the Time & Date display if
' you are in the Setup and don't touch any Buttons for 20 seconds
'
'
' Device Programming Options
' --------------------------
'@ DEVICE pic16F877, INTRC_OSC_NOCLKOUT
' System Clock Options
@ DEVICE pic16F877, WDT_ON
' Watchdog Timer
@ DEVICE pic16F877, PWRT_ON
' Power-On Timer
@ DEVICE pic16F877, BOD_ON
' Brown-Out Detect
'@ DEVICE pic16F877, MCLR_OFF
' Master Clear Options (Internal)
@ DEVICE pic16F877, LVP_OFF
' Low-Voltage Programming
@ DEVICE pic16F877, CPD_OFF
' Data Memory Code Protect
@ DEVICE pic16F877, PROTECT_OFF
' Program Code Protection
'
' Hardware Assignments
' --------------------
'
' System LCD
' ----------
' No Resistors required on any line
' RA0-RA3 Data bits DB0-DB3
' RA6 RS-bit
' RA7 E-Bit
'
' Include "MODEDEFS.BAS" ' Include Shiftin/out modes
Define LCD_DREG PORTD ' Define LCD connections
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
DEFINE I2C_SCL PORTC,3 ' For 12-bit core only
DEFINE I2C_SDA PORTC,4 ' For 12-bit core only
'DEFINE I2C_SLOW 1
ADCON1 = 7 ' PORTA and E digital
Low PORTE.2 ' LCD R/W low = write
Pause 100 ' Wait for LCD to startup
'
' DS1307 Connections
' ------------------
' 10K Resistors required from PORTB.1 and PORTB.2 to Vdd
' PORTB.0 relies on weak pull-up's (for future use)
'
' SQWpin var PORTB.0
' You don't actually need to wire this pin... but...
' If you're observant, you'll notice I've wired the DS1307's
' SQW to RB0. Rather than 'poll' and display the time/date
' as in this example code, you can have an interrupt
' on RB0 each second to do this. In fact if you look at
' my code for setting the DS1307 you'll see I've already
' programmed it for a 1 second 'Tick' for exactly this
' purpose...
SCLpin var PORTC.3
SDApin var PORTC.4
'
' Setting Buttons
' ---------------
' Buttons are connected between PORTB.4, 5 & 6 down to Vss
' No Resistors required - we're using weak pull-up's
'
DecButton var PORTB.4 ' Press to Decrement Button
SetButton var PORTB.5 ' Press to Set/memorise Button
IncButton var PORTB.6 ' Press to Increment Button
'
' Unused Ports
' ------------
' RA4
' RA5
' RB3
' RB7
'
' EEPROM Locations
' ----------------
Data @0,74,97,110,70,101,98,77,97,114,65,112,114
' Jan Feb Mar Apr
Data 77, 97, 121, 74, 117, 110, 74, 117, 108, 65, 117, 103
' May Jun Jul Aug
Data 83, 101, 112, 79, 99, 116, 78, 111, 118, 68, 101, 99
' Sep Oct Nov Dec
Data 84, 117, 101, 87, 101, 100, 84, 104, 117, 70, 114, 105
' Tue Wed Thu Fri
Data 83, 97, 116, 83, 117, 110, 77, 111, 110
' Sat Sun Mon
'
' RAM Assignments and Variables
' -----------------------------
CounterA var byte ' General purpose Variable
CounterB var byte ' General purpose Variable
CounterC var byte ' General purpose Variable
CounterD var byte ' General purpose Variable
RTCSec var byte ' Seconds
RTCMin var byte ' Minutes
RTCHour var byte ' Hours
RTCWDay var byte ' Weekday
RTCDay var byte ' Day
RTCMonth var byte ' Months
RTCYear var byte ' Year
RTCCtrl var byte ' Control
SetTime var byte ' 12/24 Hour Clock
SetSec var byte ' Seconds
SetMin var byte ' Minutes
SetHour var byte ' Hours
SetDay var byte ' Day
SetMonth var byte ' Months
SetYear var byte ' Year
TimeOut var word ' Variable for SetUp Menu Time-Out
'
' Program Constants
' -----------------
ButtonRepeat con 200 ' Timeperiod (in mS for Edit Buttons auto-repeat
' should you want to hold them down...
'
' Start Program
' =============
GoTo JumpStart
'
' Subroutine Nest Area
' ====================
'
' Subroutine Converts back to BCD
' -------------------------------
' CounterA is the entry variable
' CounterB holds the converted BCD result on exit
ConvertBCD:
CounterB=CounterA DIG 1
CounterB=CounterB<<4
CounterB=CounterB+CounterA DIG 0
Return
'
' Subroutine Displays Month at current Cursor Position
' ----------------------------------------------------
' CounterB holds Month (1-12) this value is destroyed by the routine
' additionally uses CounterA and CounterD variables
DisplayMonth:
CounterB = CounterB * 3 - 3 ' Convert BCD Month to EEPROM Start Address
DisplaySequence:
For CounterA = CounterB To CounterB + 2
' Read and Display Month
Read CounterA, CounterD
LCDOut CounterD
Next CounterA
Return
'
' Subroutine works out Number of Days in the Month
' ------------------------------------------------
' SetYear - entry variable containing year (0-99)
' SetMonth - entry Variable Containing Month (1-12)
' CounterA - exits with number of days
FindDays:
LookUp SetMonth - 1, [31,28,31,30,31,30,31,31,30,31,30,31], CounterA
' Above line gives the 'usual' days of the Month
' Section below adjusts for Leap-Year
If SetMonth = 2 Then
If (SetYear&$03)=0 then CounterA=29
End If
Return
'
' Subroutine waits until user reseases Set Button
' -----------------------------------------------
SetButtonRelease:
LCDOut $FE,1
While SetButton = 0: Wend
Pause 250 ' Small pause to kill any Key-Bounce
Return
'
' End of Subroutine Nest Area
' ---------------------------
'
' Actual Start of Real Program
' ============================
JumpStart:
'
' Set Hardware Directions
' -----------------------
'CMCON=%00000111 ' Disable Comparators
TRISC=%00000000 ' PORTA all set to Output
TRISB=%11111111 ' PORTB all set to Input
OPTION_REG 0.7 = 0 ' Enable Weak Pull-Ups
'
' Reset Hardware
' --------------
Pause 200 ' Timeout for LCD to settle
'
' Time & Date Display Loop
' ========================
ReDisplay:
LCDOut $FE,1 ' Clear LCD
ReDisplayLoop:
'
' Read RTC
' --------
I2CRead SDApin,SCLpin,$D1,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl]
'
' Decide if Setup Required/Wanted
' -------------------------------
If RTCSec.7=1 then goto SetUpPreset
' Hands-Up who noticed the fact that when the DS1307
' powers-up initially from cold, and all it's
' registers are potentially "unpredictable", that
' Seconds bit 7 is always high?
' We can use this feature to automatically jump to
' our 'Setup' routine on initial power-up if the user
' forgets to keep 'Setup' depressed and so prevent
' any 'undesriable' Time & Date displays...
If SetButton = 0 Then
' If Set Button is pressed, User will be taken to
' the Setup Menu. If the Set Button is pressed at
' Power-Up, then the User will be taken to the Setup
' Menu directly without any intermediate display
GoSub SetButtonRelease
GoTo Setup
End If
'
' Display RTC
' -----------
' Displayed on 2-line 16 character LCD in the form...
' 10:15:00 AM
' Wed 12 Jun 2002
' Note - AM/PM indicator only shows in 12 hour mode.
' Additionally there is Hours leading Zero Surpression in 12-Hour Mode
' after-all, you don't display 07pm do you?
'
'
' Display Time on Line 1
' ----------------------
LCDOut $FE,$80
If RTCHour.6=1 then
' Work-Out 12 or 24 hour Display for Hours
CounterA=(RTCHour>>4)&$01
Else
CounterA=(RTCHour>>4)&$03
End If
CounterA=CounterA*10+(RTCHour&$0F)
If RTCHour.6=1 then
' Display Hours appropriately for 12 or 24 hour Mode
LCDOut #CounterA
Else
LCDOut #CounterA Dig 1,#CounterA Dig 0
End If
LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,":"
LCDOut #(RTCSec>>4)&$0F,#RTCSec&$0F," "
IF RTCHour.6=1 then
If RTCHour.5=1 then
LCDOut "PM"
Else
LCDOut "AM"
End If
End If
'
' Display Day of Week on Line 2
' -----------------------------
' Let's face it... the DS1307 doesn't calculate the Day of Week,
' all it does is increment a number at each mignight from
' 1 thru 7 and roll back to start from 1 all over again.
' It's really up to you to work out the DOW and program it in.
' This is a tough nut for integer math to do... see the
' 'Calculate Day of Week' routine in the setup section.
LCDOut " ",$FE,$C0
CounterB = RTCWDay * 3 + 33 ' Convert BCD WeekDay to EEPROM Start Address
GoSub DisplaySequence ' Display 3 character sequence from EEPROM
'
' Display Date on Line 2
' ----------------------
LCDOut " ",#(RTCDay>>4)&$0F,#RTCDay&$0F," "
CounterB=((RTCMonth>>4)&$0F)*10+(RTCMonth&$0F)
GoSub DisplayMonth
LCDOut " 20",#(RTCYear>>4)&$0F,#RTCYear&$0F,$FE,$80
'
Pause 250 ' Repeat about 4 times/sec
GoTo ReDisplayLoop
'
' Clock and Calandar Settings
' ===========================
'
' Initial Default Settings
' ------------------------
' Default setting preset to the moment this program first born
'
SetupPreset:
RTCSec=$00 ' Seconds preset to 00
RTCMin=$15 ' Minutes preset to 15
RTCHour=$13 ' Hours preset to 13'00
RTCWDay=$01 ' Weekday preset to 01
RTCDay=$12 ' Day preset 12
RTCMonth=$06 ' Months preset to June
RTCYear=$02 ' Year preset to 2002
RTCCtrl=$10 ' Control preset to output 1 second 'Tick' on SQWpin
'
' Convert the Current BCD Data to Something easier to Edit
' --------------------------------------------------------
Setup:
SetTime=RTCHour.6 ' Determines 12/24 Hour mode
If SetTime = 1 Then
' Regardless of 12/24 options, SetHour always
' contains the hours in 24 hour clock format
' otherwise there's twice the amount of work
' to keep track in the edit routines
SetHour=(RTCHour>>4)&$01
' if 12-hour mode
Else
SetHour=(RTCHour>>4)&$03
' if 24 hour mode
End If
SetHour=SetHour*10+(RTCHour&$0F)
If SetTime = 1 Then
If RTCHour.5=1 then
If SetHour < 12 Then SetHour = SetHour + 12
' Add-in the AM/PM indicator
Else
If SetHour = 12 Then SetHour = 0
End If
End If
SetMin=((RTCMin>>4)&$0F)*10+(RTCMin&$0F)
SetSec=((RTCSec>>4)&$0F)*10+(RTCSec&$0F)
SetYear=((RTCYear>>4)&$0F)*10+(RTCYear&$0F)
SetMonth=((RTCMonth>>4)&$0F)*10+(RTCMonth&$0F)
SetDay=((RTCDay>>4)&$0F)*10+(RTCDay&$0F)
'
' Setup Menu Loop
' ---------------
CounterC = 0 ' Set to Start of Setup (seven steps from 0 to 6)
TimeOut = 0 ' Zero the Time-Out counter
SetupLoop:
LCDOut $FE,1,"Set "
'
' First Display the Menu Prompts
' ------------------------------
' This is a crude way of doing the entry Menu's but it was
' pretty fast and quite mindless to program this lunch-hour
'
If CounterC = 0 Then
LCDOut "Mode"
End If
If CounterC = 1 Then
LCDOut "Hours"
End If
If CounterC = 2 Then
LCDOut "Minutes"
End If
If CounterC = 3 Then
LCDOut "Seconds"
End If
If CounterC = 4 Then
LCDOut "Year : 20"
End If
If CounterC = 5 Then
LCDOut "Month"
End If
If CounterC = 6 Then
LCDOut "Day"
End If
If CounterC <> 4 Then LCDOut " :"
'
' Now Display the Data
' --------------------
SetupDisplayLoop:
'
' 12/24 Hour Option
' -----------------
If CounterC = 0 Then
LCDOut $FE,$8B
If SetTime = 0 Then
LCDOut "24HR"
Else
LCDOut "12HR"
End If
LCDOut $FE,$8B
End If
' Hours
' -----
' Hours are tricky because of the 12/24 & AM/PM bit
' so we have to reconvert 1-24 back to 1-12 plus AM/PM
If CounterC = 1 Then
CounterA = SetHour
If SetTime = 1 Then
LCDOut $FE,$8E
' Display AM/PM bit
If CounterA < 12 Then
LCDOut "AM"
Else
LCDOut "PM"
End If
If CounterA = 0 Then CounterA = 12
If CounterA > 12 Then CounterA = CounterA - 12
End If
LCDOut $FE,$8C,#CounterA
If CounterA < 10 Then LCDOut " "
LCDOut $FE,$8C
End If
'
' Minutes
' -------
If CounterC = 2 Then
LCDOut $FE,$8E,#SetMin
If SetMin < 10 Then LCDOut " "
LCDOut $FE,$8E
End If
'
' Seconds
' -------
If CounterC = 3 Then
LCDOut $FE,$8E,#SetSec
If SetSec < 10 Then LCDOut " "
LCDOut $FE,$8E
End If
'
' Year
' ----
If CounterC = 4 Then
LCDOut $FE,$8D,#SetYear DIG 1,#SetYear Dig 0
LCDOut $FE,$8D
End If
'
' Month
' -----
' Here's a nice touch to setting the month rather
' than the usual number entry method...
'
If CounterC = 5 Then
LCDOut $FE,$8C
CounterB = SetMonth
GoSub DisplayMonth
LCDOut $FE,$8C
End If
'
' Day
' ---
If CounterC = 6 Then
LCDOut $FE,$8A,#SetDay
If SetDay < 10 Then LCDOut " "
LCDOut $FE,$8A
End If
'
' The Data-Entry Bit
' ------------------
SetupEntryLoop:
'
' Decrement Button Pressed
' ------------------------
If DecButton = 0 Then
'
' 12/24 Clock Selection
' ---------------------
If CounterC = 0 Then
If SetTime = 0 Then
SetTime = 1
Else
SetTime = 0
End If
End If
'
' Decrement Hours
' ---------------
If CounterC = 1 Then
If SetHour = 0 Then
SetHour = 23
Else
SetHour = SetHour - 1
End If
End If
'
' Decrement Minutes
' -----------------
If CounterC = 2 Then
If SetMin = 0 Then
SetMin = 59
Else
SetMin = SetMin - 1
End If
End If
'
' Decrement Seconds
' -----------------
' Kinda overkill to include setting seconds,
' but if you got codespace to burn...
If CounterC = 3 Then
If SetSec = 0 Then
SetSec = 59
Else
SetSec = SetSec - 1
End If
End If
'
' Decrement Years
' ---------------
If CounterC = 4 Then
If SetYear = 0 Then
SetYear = 99
Else
SetYear = SetYear - 1
End If
End If
'
' Decrement Month
' ---------------
If CounterC = 5 Then
If SetMonth = 1 Then
SetMonth = 12
Else
SetMonth = SetMonth - 1
End If
'
' Changing the Month has a bearing on the
' days, especially if you've got days preset
' to 31 and you now select a month with fewer
' days... so this bit here just prevents that
GoSub FindDays
If SetDay > CounterA Then SetDay = CounterA
End If
'
' Decrement Days
' --------------
' Tricky one here... go work-out the days
' of the month first...
If CounterC = 6 Then
GoSub FindDays
If SetDay = 1 Then
SetDay = CounterA
Else
SetDay = SetDay - 1
End If
End If
Pause ButtonRepeat
TimeOut = 0
GoTo SetupDisplayLoop
End If
'
' Increment Button Pressed
' ------------------------
' This is just like Decrement but opposite...
If IncButton = 0 Then
'
' 12/24 Clock Selection
' ---------------------
If CounterC = 0 Then
If SetTime = 1 Then
SetTime = 0
Else
SetTime = 1
End If
End If
'
' Increment Hours
' ---------------
If CounterC = 1 Then
If SetHour = 23 Then
SetHour = 0
Else
SetHour = SetHour + 1
End If
End If
'
' Increment Minutes
' -----------------
If CounterC = 2 Then
If SetMin = 59 Then
SetMin = 0
Else
SetMin = SetMin + 1
End If
End If
'
' Increment Seconds
' -----------------
' Kinda overkill to include setting seconds,
' but if you got codespace to burn...
If CounterC = 3 Then
If SetSec = 59 Then
SetSec = 0
Else
SetSec = SetSec + 1
End If
End If
'
' Increment Years
' ---------------
If CounterC = 4 Then
If SetYear = 99 Then
SetYear = 0
Else
SetYear = SetYear + 1
End If
End If
'
' Increment Month
' ---------------
If CounterC = 5 Then
If SetMonth = 12 Then
SetMonth = 1
Else
SetMonth = SetMonth + 1
End If
'
' Changing the Month has a bearing on the
' days, especially if you've got days preset
' to 31 and you now select a month with fewer
' days... so this bit here just prevents that
GoSub FindDays
If SetDay > CounterA Then SetDay = CounterA
End If
'
' Increment Days
' --------------
' Tricky one here... go work-out the days
' of the month first...
If CounterC = 6 Then
GoSub FindDays
If SetDay >= CounterA Then
SetDay = 1
Else
SetDay = SetDay + 1
End If
End If
Pause ButtonRepeat
TimeOut = 0
GoTo SetupDisplayLoop
End If
'
' Set Button Pressed
' ------------------
If SetButton = 0 Then
CounterC = CounterC + 1
' Increment Menu Item
TimeOut = 0
If CounterC > 6 Then
' Save Data if all edit items exhaused
LCDOut $FE,1,"Memorised"
' Make the User feel happy
'
' Save 12/24 Hours to BCD DS1307's Format
' ---------------------------------------
CounterA = SetHour
If SetTime = 1 Then
If CounterA > 12 Then CounterA = CounterA - 12
If CounterA = 0 Then CounterA = 12
End If
GoSub ConvertBCD
RTCHour = CounterB
' Save the Hours Value
If SetTime = 1 Then
RTCHour 0.6 = 1
' Save the 12 Hour Mode Flag
If SetHour >= 12 Then RTCHour 0.5 = 1
' Save the 'PM' Flag
End If
'
' Save Minutes
' ------------
CounterA = SetMin
GoSub ConvertBCD
RTCMin = CounterB
'
' Save Seconds
' ------------
CounterA = SetSec
GoSub ConvertBCD
RTCSec = CounterB
'
' Save Year
' ---------
CounterA = SetYear
GoSub ConvertBCD
RTCYear = CounterB
'
' Save Month
' ----------
CounterA = SetMonth
GoSub ConvertBCD
RTCMonth = CounterB
'
' Save Day
' --------
CounterA = SetDay
GoSub ConvertBCD
RTCDay = CounterB
'
' Calculate Day of Week & Save
' ----------------------------
' Melanie's fudge for calculating Days of Week
' using PBP's integer math...
' by the time someone's clock displays the
' the wrong Day of Week, I'll hopefully have long
' retired and be past caring...
' I wouldn't however go stick this routine in a
' Nuclear Power Station to purge the reactor
' every Monday morning without checking how far it
' will work before the integer math overflows...
' In my routine RTCWDay=1 is a Tuesday (the
' start of my week) and continues sequentially
' until RTCWDay=7 which is a Monday
CounterA = SetYear + 4
CounterB = SetMonth
If SetMonth < 3 Then
CounterA = CounterA - 1
CounterB = CounterB + 12
End If
CounterD = (SetDay + (153 * CounterB - 457) / 5 + 365 * CounterA + CounterA / 4 - CounterA / 100 + CounterA / 400 + 2) Mod 7
RTCWDay = CounterD + 1
'
' Do the Business
' ---------------
I2CWrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl]
Pause 1000
GoSub SetButtonRelease
GoTo ReDisplay
End If
GoSub SetButtonRelease
GoTo SetupLoop ' Loop for Next Menu Item
End If
'
' Menu TimeOut Counter
' --------------------
Pause 1 ' Kill 1mS
TimeOut = TimeOut + 1
If TimeOut > 20000 Then GoTo ReDisplay
' User paused too long
' Return User to Time & Date Display
' This will however bounce the User to the original
' Setup Menu start point if the DS1307 has not
' been initialised
GoTo SetupEntryLoop ' Loop for Button Press
'
End
' LCD clock program using Dallas1202/1302 RTC
Define osc 20
Include "MODEDEFS.BAS" ' Include Shiftin/out modes
Define LCD_DREG PORTD ' Define LCD connections
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
DEFINE I2C_SCL PORTC,4 ' For 12-bit core only
DEFINE I2C_SDA PORTC,3 ' For 12-bit core only
'DEFINE I2C_SLOW 1
ADCON1 = 7 ' PORTA and E digital
Low PORTE.2 ' LCD R/W low = write
pause 100 ' Wait for LCD to startup
;-----------------------Copyright 2002, High-TechGarage.com-----------------------
;
; This program will interface with the DS1307, I2C Real-Time Clock from
; Dallas Semiconductor. P0 is used as SDA (serial data) and P1 is used as
; SCL (serial clock). This ATOM software is part of a tutorial available
; on our website: http://www.high-techgarage.com/tutorial/ds1307.php
;
; The RTC will set if memory location 0 on the ATOM is set to 0. To set
; the clock run a program which sets EEPROM location 0 to 0. The program is
; only 1 line: write 0,0. Finally change the time and date below and run this
; program.
;
; Revision: 1.0
; Date: 03/22/02
;
;-----------------------------------DS1307.bas------------------------------------
clear ; clear all variables
SDA var portc.3 ; 2-wire serial data
SCL var portc.4 ; 2-wire serial clock
; --{ I2C Definitions }-----------------------------------------------------------
RTC con %11010000 ; RTC device address (byte addressing)
; --{ RTC definitions }-----------------------------------------------------------
SecReg con $00 ; seconds address (00 - 59)
; MSB of SecReg must be set to a 0 to enable RTC
MinReg con $01 ; minutes address (00 - 59)
HourReg con $02 ; hours address (01 - 12) or (00 - 23)
DayReg con $03 ; day address (1 - 7)
DateReg con $04 ; date address (01 - 28/29, 30, 31)
MonthReg con $05 ; month address (01 - 12)
YearReg con $06 ; year address (00 - 99)
ContReg con $07 ; control register
RTCflag con 0 ; RTC flag (location 0 of BS2 EEPROM)
RTCset var bit ; bit to check if RTC has been set
; The constants below set the RTC to: 12:35:00 on Friday, March 22nd, 2002
_sec con $00 ; set seconds to 00 (enables the oscillator)
_min con $35 ; set minutes to 35
_hr con $12 ; set hour to 12 (noon)
_day con $06 ; set day to 6 (Friday)
_date con $22 ; set date to 22 (22nd)
_mon con $03 ; set month to 3 (March)
_yr con $02 ; set year to 2002
; The control register is used to control the operation of the SQW/OUT pin
; Starting with the MSB (Bit 7) -> OUT x x SQWE x x RS1 RS0 <- (Bit 0)
; OUT: if SQWE=0, the logic level on SQW/OUT pin is 1 if OUT=1 and is 0 if OUT=0.
; SQWE: square wave enable. 1->enabled 0->disabled
; RS1, RS0: rate select. 00->1Hz, 01->4.096kHz, 10->8.192kHz, 11->32.768kHz
cntrl con %00010000 ; sets the SQW/OUT to 1Hz pulse, logic level low
; --{ General Variables }---------------------------------------------------------
sec var byte ; seconds
minute var byte ; minutes
hr var byte ; hours
day var byte ; day
date var byte ; date
mon var byte ; month
yr var byte ; year
; --{ Check to see if clock is set }----------------------------------------------
pause 100 ; let everything settle down
write 0, 0
read RTCflag, RTCset ; check to see if the clock has already been set
if RTCset = 0 then SetTimeAndDate ; if it is 0, we need to set the clock
;===[ MAIN PROGRAM STARTS HERE ]==================================================
; The main program is just a loop which gets the current time, then displays it
; on the debug screen.
Loop: ; Loop to display the time
i2cread SDA, SCL, RTC, SecReg, [sec,minute,hr,day,date,mon,yr]
LCDOUT $FE,2,"Current Time:"
LCDOUT $FE,$C0,"-------------------"
' debug ["Current Time:", 13]
' debug ["-------------------", 13]
LCDOUT $FE,$D4,hex hr, ":", hex minute, ":", hex sec
'debug [hex hr, ":", hex minute, ":", hex sec, 13]
pause 100
goto Loop
End
;===[ MAIN PROGRAM ENDS HERE ]=====================================================
;--{ Set time and date on RTC subroutine }-----------------------------------------
SetTimeAndDate:
' i2cwrite SDA, SCL, RTC, SecReg, [_sec,_minute,_hr,_day,_date,_mon,_yr,cntrl]
i2cwrite SDA, SCL, RTC, SecReg, [sec,minute,hr,day,date,mon,yr,cntrl]
pause 10
write RTCflag, 1 ; set the flag so we don't reset the clock
goto Loop
' LCD clock program using Dallas1202/1302 RTC
Include "MODEDEFS.BAS" ' Include Shiftin/out modes
'Define osc 20
'DEFINE I2C_SLOW 1
'DEFINE I2C_HOLD 1
'DEFINE I2C_SCLOUT 1
Define LCD_DREG PORTD ' Define LCD connections
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
TRISB=%11111111
OPTION_REG = 0
TRISC=%00000000
TRISA=%11111111
DEFINE I2C_SCL PORTC,3 ' For 12-bit core only
DEFINE I2C_SDA PORTC,4 ' For 12-bit core only
' Alias pins
'RST var PORTA.2
'IO var PORTC.1
'SCLK var PORTC.3
SCL var PORTC.3
SDA var PORTC.4
' Allocate variables
rtcyear var byte
rtcday var byte
rtcmonth var byte
rtcdate var byte
rtchr var byte
rtcmin var byte
rtcsec var byte
rtccontrol var byte
' Low RST ' Reset RTC
Low SCL
ADCON1 = 7 ' PORTA and E digital
Low PORTE.2 ' LCD R/W low = write
Pause 100 ' Wait for LCD to startup
' Set initial time to 8:00:00AM 07/16/99
rtcyear = $99
rtcday = $06
rtcmonth = $07
rtcdate = $16
rtchr = $08
rtcmin = 0
rtcsec = 0
GoSub settime ' Set the time
GoTo mainloop ' Skip subroutines
' Subroutine to write time to RTC
settime:
' Shiftout SDA, SCL, LSBFIRST, [$8e, 0]
' Write all 8 RTC registers in burst mode
' Shiftout SDA, SCL, LSBFIRST, [$be, rtcsec, rtcmin, rtchr, rtcdate, rtcmonth, rtcday, rtcyear, 0]
' RST = 0 ' Reset RTC
Return
' Subroutine to read time from RTC
gettime:
'I2CRead SDA,SCL,$D0,$00,[rtcsec, rtcmin, rtchr, rtcdate, rtcmonth, rtcday, rtcyear, rtccontrol]
' Shiftout SDA, SCL, LSBFIRST, [$bf] ' Read all 8 RTC registers in burst mode
'I2CRead SDA,SCL,$D0,$00,[rtcsec, rtcmin, rtchr, rtccontrol]
Shiftin SDA, SCL, LSBPRE, [rtcsec, rtcmin, rtchr, rtcdate, rtcmonth, rtcday, rtcyear, rtccontrol]
Return
' Main program loop - in this case, it only updates the LCD with the time
mainloop:
GoSub gettime ' Read the time from the RTC
' Display time on LCD
Lcdout $fe, 1, hex2 rtcmonth, "/", hex2 rtcdate, "/" , hex2 rtcyear,_
" ", hex2 rtchr, ":", hex2 rtcmin, ":", hex2 rtcsec
portc.5=porta.0
Pause 50 ' Do it about 3 times a second
GoTo mainloop ' Do it forever
End
' LCD clock program using Dallas1202/1302 RTC
Include "MODEDEFS.BAS" ' Include Shiftin/out modes
'Define osc 20
'DEFINE I2C_SLOW 1
'DEFINE I2C_HOLD 1
'DEFINE I2C_SCLOUT 1
Define LCD_DREG PORTD ' Define LCD connections
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
TRISB=%11111111
OPTION_REG = 0
TRISC=%00000000
TRISA=%11111111
cntrl con %00010000 ; sets the SQW/OUT to 1Hz pulse, logic level low
DEFINE I2C_SCL PORTC,3 ' For 12-bit core only
DEFINE I2C_SDA PORTC,4 ' For 12-bit core only
' Alias pins
'RST var PORTA.2
'IO var PORTC.1
'SCLK var PORTC.3
SCL var PORTC.3
SDA var PORTC.4
' Allocate variables
rtcyear var byte
rtcday var byte
rtcmonth var byte
rtcdate var byte
rtchr var byte
rtcmin var byte
rtcsec var byte
rtccontrol var byte
' Low RST ' Reset RTC
Low SCL
ADCON1 = 7 ' PORTA and E digital
Low PORTE.2 ' LCD R/W low = write
Pause 100 ' Wait for LCD to startup
' Set initial time to 8:00:00AM 07/16/99
rtcyear = 99
rtcday = 6
rtcmonth = 7
rtcdate = 16
rtchr = 8
rtcmin = 0
rtcsec = 0
I2Cwrite SDA,SCL,$D0,$07,[cntrl]
Lcdout $fe, 1
GoSub settime ' Set the time
GoTo mainloop ' Skip subroutines
' Subroutine to write time to RTC
settime:
' Shiftout SDA, SCL, LSBFIRST, [$8e, 0]
' Write all 8 RTC registers in burst mode
' Shiftout SDA, SCL, LSBFIRST, [$be, rtcsec, rtcmin, rtchr, rtcdate, rtcmonth, rtcday, rtcyear, 0]
' RST = 0 ' Reset RTC
Return
' Subroutine to read time from RTC
gettime:
'I2CRead SDA,SCL,$D0,$00,[rtcsec, rtcmin, rtchr, rtcdate, rtcmonth, rtcday, rtcyear, rtccontrol]
' Shiftout SDA, SCL, LSBFIRST, [$bf] ' Read all 8 RTC registers in burst mode
I2CRead SDA,SCL,$D0,$00,[rtcsec, rtcmin, rtchr]
' Shiftin SDA, SCL, LSBPRE, [rtcsec, rtcmin, rtchr, rtcdate, rtcmonth, rtcday, rtcyear, rtccontrol]
Return
' Main program loop - in this case, it only updates the LCD with the time
mainloop:
GoSub gettime ' Read the time from the RTC
' Display time on LCD
Lcdout $fe, 2, dec2 rtcmonth, "/", dec2 rtcdate, "/" , dec2 rtcyear,_
" ", dec2 rtchr, ":", dec2 rtcmin, ":", dec2 rtcsec
portc.5=portb.0
Pause 50 ' Do it about 3 times a second
GoTo mainloop ' Do it forever
End
@ device WDT_OFF & pwrt_on & protect_on & cpd_on
PCON=%00000000
define osc 20
Define LCD_DREG PORTD ' LCD bağlantılarını tanımla
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
ADCON1 = 7 ' PORTA ve E dijital giriş çıkış olarak ayarla
Low PORTE.2 ' LCD R/W low = yazma modu
PAUSE 300 ' LCD başlamak için bekle
option_reg = 0 'PORTB Pulluplar etkin.
'(Pullup=Portb' nin tüm uçlarını +5V a çekmektir.lojik 1)
TRISB=%11111111 'PORTB 7654 giriş 3210 çıkış olarak ayarlandı
TRISC=%10000000 'PORTC Tüm uçlar çıkış olarak ayarlandı
DEFINE I2C_SCL PORTC,0 'For 12-bit core only
DEFINE I2C_SDA PORTC,1 'For 12-bit core only
portb = 0: portc = 0 'PORTB ve PORTC yi 0 yap
lcdout $FE,1 'LCD ekranı sil
lcdout $FE,2,"LCD-KEYPAD uyg."
PAUSE 2000
'kontrol con %10100000
SDA var portc.1
SCLK var portc.0
'PAUSE 2000
'low porta.3
'RST var portb.3 ' Reset pin 10
WEnable con $00 ' Write enable
WCB con $BE ' Read clock burst
RCB con $BF ' Write clock burst
i var byte
IOSec var byte ' store register data for seconds
IOMin var byte ' store register data for minutes
IOHour var byte ' store register data for hours
IODay var byte ' store register data for day
IOMonth var byte ' store register data for month
IODCare var byte ' For day of week - don't care
IOYear var byte ' store register data for year
Tmonth1 var byte
Tmonth2 var byte
Tmonth3 var byte
'changetime:
' serout2 porta.3,16468,[" SET TIME YES NO "]
' For i = 0 To 40
' if porta.4 = 0 then gettime
' NAP 3
' Next i
' goto loop
'GETTIME:
' serout2 porta.3,16468,[254,1]
' serout2 porta.3,16468,[" CLOCK RS232 IN "]
' SERIN2 PORTA.2,16468,[hex2 IOMONTH,hex2 IODAY,hex2 IOYEAR,hex2 IOHOUR,hex2 IOMIN,hex2 IOSEC]
' serout2 porta.3,16468,[254,1]
'set:
' PAUSE 500
' high RST ' tell 1302 that we want to write a clock burst
' shiftout IO, SCLK, 0, [WCB] ' write everything in a burst
' shiftout IO, SCLK, 0, [IOSec,IOMin,IOhour,IOday,IOmonth,IODcare,IOyear,Wenable]
' low RST
Loop:
' NAP 5
PAUSE 420
'high RST ' tell 1302 that we want to read a clock burst
shiftout SDA, SCLK, 0, [RCB] ' read everything in a burst
Shiftin SDA, SCLK, 1, [IOSec\8,IOMin\8,IOhour\8,IOday\8,IOmonth\8,IODcare\8,IOyear\8]
' low RST
GoSub display
goto loop
display:
LCDOUT $FE,1,"TIME=",hex2 IOHour,":",hex2 IOMin,":",hex2 IOSec,13
' serout2 porta.3,16468,[254,1]
' serout2 porta.3,16468,[" TIME ",hex2 IOHour,":",hex2 IOMin,":",hex2 IOSec,13]
' serout2 porta.3,16468,[254,190]
' serout2 porta.3,16468,[" DATE ",HEX2 IOMONTH,"-",HEX2 IODAY,"-",HEX2 IOYEAR,13,13]
Return
End
' LCD clock program using Dallas1202/1302 RTC
' Include "MODEDEFS.BAS" ' Include Shiftin/out modes
Define osc 20
'DEFINE I2C_HOLD 1
'DEFINE I2C_SCLOUT 1
'DEFINE I2C_SLOW 1
'SSPCON=
'DEFINE I2C_HOLD 1
'DEFINE I2C_SCLOUT 1
@ device WDT_OFF & pwrt_on
TRISD=%11111111
Define LCD_DREG PORTD ' Define LCD connections
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
ADCON1 = 7 ' PORTA and E digital
Low PORTE.2 ' LCD R/W low = write
Pause 100 ' Wait for LCD to startup
TRISB=%11111100
OPTION_REG = 0
TRISC=%11011111
TRISA=%11111111
DEFINE I2C_SCL PORTC,3 ' For 12-bit core only
DEFINE I2C_SDA PORTC,4 ' For 12-bit core only
' Alias pins
'RST var PORTA.2
'IO var PORTC.1
'SCLK var PORTC.3
SCL var PORTC.3
SDA var PORTC.4
' Low RST ' Reset RTC
'Low SCL
addr var word
klockaw CON %11010001 'controlbyte
klockar CON %11010000
san var byte
dak var byte
saa var byte
hafg var byte
gun var byte
ay var byte
yil var byte
eksik var byte
deger var byte
lcdout $FE,1
san = 1
dak = 13
saa = 23
addr = 0
GoSub setclk
anaprogram:
lcdout $FE,2,hex2 san,":",hex2 dak,":",hex2 saa
portc.5=porta.0:deger=deger+1:lcdout $FE,$C0,dec deger
GoSub getclk
'pause 300
GoTo anaprogram
'---------------------------
' saat ve takvim kur ve oku
getclk:
I2CRead SDA,SCL,$D1,addr,[san,dak,saa,hafg,gun,ay,yil]
Pause 10
Return
setclk:
I2CWrite SDA, SCL, klockaw, addr, [san,dak,saa]
Pause 10
I2CWrite SDA, SCL, klockaw, addr + 3, [hafg,gun,ay,yil,0]
Pause 10
Return
End
'DECLARE SLOW_BUS 0 'ON '- OFF or 1 - 0
' Program - TIMETEST.BAS
' Display the time and date on an LCD
' using the DALLAS DS1307 RTC
' The DS1307 uses BCD, therefore, two assembler subroutines are used
' to convert BINARY to BCD and vice-versa
'
' To enable the clock's internal oscillator, write 00 to address 0
' to enable the Squarewave oscillator, set bit-4 of address 7
' bits-0..1 control the frequency of the squarewave
' 0..0 1Hz (ticks in rythm with the seconds counter)
' 0..1 4KHz
' 1..0 8KHz
' 1..1 32KHz
' If the squarewave is disabled, then setting bit-7 of address 7
' will output the oscillator pin HIGH, while clearing bit-7 will output LOW.
' This pin is open collector output, therefor a pullup resistor should be used.
'DS1307 pin arangement
' Pin Connection
' 1 32.768KHz Xtal
' 2 32.768KHz Xtal
' 3 3 Volt Backup Battery Input(leave unconnected)
' 4 Ground
' 5 SDA line (with 10k pullup resistor)
' 6 SCL line (with 10k pullup resistor)
' 7 Squarewave output (requires pullup resistor if used)
' 8 +5 Volts
Include "PROTON_4.INC"
' Device 16F84 ' We are using a PIC16F84
' ** Load the LCD and I2C routines **
'Include LCD,I2CBUS
' Init LCD,PortB ' Place the LCD on PortB
' Symbol EN=B.2 ' Assign the LCD's RS line
' Symbol RS=B.3 ' Assign the LCD's EN line
' ** Initialise the I2C routine **
' Init I2CBUS
' * Declare the variables used by the BCD/BIN and DS1307 subroutines
Dim Freq ' Frequency of oscillation from SQW/OUT pin
Dim BCDByte ' Transfer data to and from BCD routines
Dim RAMByte ' The value placed into and from the RAM
Dim LSD ' Low byte for Binary to BCD routine
Dim MSD ' High byte for Binary to BCD routine
Dim DSAddr ' DS1307 register address pointer
Dim Seconds ' Holds the Seconds
Dim Minutes ' Holds the Minutes
Dim Hours ' Holds the Hours
Dim Day ' Holds the Days
Dim Date ' Holds the Date
Dim Month ' Holds the Month
Dim Year ' Holds the Year
' *********** THE MAIN PROGRAM STARTS HERE****************
' *** DUMMY TIME and DATE VALUES for TEST PURPOSES ***
Seconds = 0 ' Set the Seconds
Minutes = 50 ' Set the Minutes
Hours = 3 ' Set the Hours
Day = 4 ' Set the Days
Date = 26 ' Set the Date
Month = 10 ' Set the Month
Year = 0 ' Set the Year
'Define PortD %00000011 ' Configure PortB's direction
Cls ' Clear the Display
GoSub Coff
GoSub Init ' Enable the DS1307's oscillator
GoSub SetTime ' Set the time and date
Again: GoSub GetTime ' Read the time from the DS1307
Cursor 1, 1 ' Place the cursor on line 1
Print Hours, ":", Minutes, ":", Seconds, " " ' Display the Hours
' Print Minutes,":" ' Display the Minutes
' Print Seconds," " ' Display the Seconds
Cursor 1, 2 ' Place the cursor on line 2
Print Date, ":", Month, ":", Year, " " ' Display the Date
' Print Month,":" ' Display the Month
' Print Year," " ' Display the Year
GoTo Again ' Continue reading/displaying
' ********** DS1307 RTC SUBROUTINES ************
' *******************************************
' * Enable the DS1307's crystal oscillator *
' *******************************************
Init: Bstart ' Send a START condition
Busout (%11010000) ' Send slave address and Write command
Busout (0) ' Point to register 0 (Seconds)
Busout (0) ' Clear the register's contents
Bstop ' Send a STOP condition
' Allow the subroutine to fall through to the FreqOFF routine
' ****************************
' * Disable the SQW/OUT pin *
' ****************************
SQWOff:
Bstart ' Send a START condition
Busout (%11010000) ' Send slave address and Write command
Busout (7) ' Point to register 7 (Control)
Busout (0) ' Clear the register's contents
Bstop ' Send a STOP condition
Return
' *************************************
' * Enable the SQW/OUT pin *
' * For a frequency governed *
' * by the contents of variable FREQ *
' *************************************
FreqOn: Freq=Freq |16 ' Enable the SQW pin with the frequency
Bstart ' Send a START condition
Busout (%11010000) ' Send slave address and Write command
Busout (7) ' Point to register 7 (Control)
Busout (Freq) ' Enable the squarewave oscillator
Bstop ' Send a STOP condition
Return
' ***************************
' * Enable the SQW/OUT pin *
' * For a Logic high *
' ***************************
SQWOn: Bstart ' Send a START condition
Busout (%11010000) ' Send slave address and Write command
Busout (7) ' Point to register 7 (Control)
Busout (%10000000) ' Bring the SQW pin HIGH
Bstop ' Send a STOP condition
Return
' *******************************************
' * Load the time and date into the DS1307 *
' *******************************************
SetTime:
' ** Convert the binary time and date format into BCD format **
BCDByte = Minutes: GoSub BINBCD: Minutes = BCDByte
BCDByte = Hours: GoSub BINBCD: Hours = BCDByte
BCDByte = Day: GoSub BINBCD: Day = BCDByte
BCDByte = Date: GoSub BINBCD: Date = BCDByte
BCDByte = Month: GoSub BINBCD: Month = BCDByte
BCDByte = Year: GoSub BINBCD: Year = BCDByte
Bstart ' Send a START condition
Busout (%11010000) ' Send slave address and Write command
Busout (1) ' Point to register 01 (minutes)
Busout (Minutes) ' Write the time/date bytes
Busout (Hours)
Busout (Day)
Busout (Date)
Busout (Month)
Busout (Year)
Bstop ' Send a STOP condition
Return
' *******************************************
' * Read the time and date from the DS1307 *
' *******************************************
GetTime:
DSAddr = 0: GoSub RTime ' Read the seconds reg
Seconds = BCDByte ' Convert it to binary
DSAddr = 1: GoSub RTime ' Read the minutes reg
Minutes = BCDByte ' Convert it to binary
DSAddr = 2: GoSub RTime ' Read the hours reg
Hours = BCDByte ' Convert it to binary
DSAddr = 3: GoSub RTime ' Read the days reg
Day = BCDByte ' Convert it to binary
DSAddr = 4: GoSub RTime ' Read the date reg
Date = BCDByte ' Convert it to binary
DSAddr = 5: GoSub RTime ' Read the month reg
Month = BCDByte ' Convert it to binary
DSAddr = 6: GoSub RTime ' Read the year reg
Year = BCDByte ' Convert it to binary
Return
' ** Read the data from address pointed to by DSADDR **
' ** The data read is place into the variable BCDBYTE **
RTime: Bstart ' Send a START condition
Busout (%11010000) ' Send slave address and Write command
Busout (DSAddr) ' Point to internal address (register)
Bstop ' Send a STOP condition
Bstart ' Send a START condition
Busout (%11010001) ' Send slave address and Read command
BCDByte = Busin ' Read the byte from address DSADDR
GoSub BCDBIN ' Convert the byte to binary
Bstop ' Send a STOP condition
Return
' ********************************************************
' ** Write to the internal RAM (08 to 63) *
' ** The address to write is held in the variable DSADDR *
' ** The data to write is held in the variable RAMBYTE *
' ********************************************************
RAMOUT: Bstart ' Send a START condition
Busout (%11010000) ' Send slave address and Write command
Busout (DSAddr) ' Point to RAM address
Busout (RAMByte) ' Write the data to the RAM
Bstop ' Send a STOP condition
Return
' *******************************************************
' ** Read from the internal RAM (08 to 63) *
' ** The address to read is held in the variable DSADDR *
' ** The data read is returned in the variable RAMBYTE *
' *******************************************************
RAMIN: Bstart ' Send a START condition
Busout (%11010000) ' Send slave address and Write command
Busout (DSAddr) ' Point to RAM address
Bstop ' Send a STOP condition
Bstart ' Send a START condition
Busout (%11010001) ' Send slave address and Read command
RAMByte = Busin ' Read the byte from address DSADDR
Bstop ' Send a STOP condition
Return
' BCD to BINARY conversion
' The byte to be converted is loaded into the variable BCDBYTE
' and is returned in the same variable BCDBYTE
BCDBIN: Movlw 0
Btfsc BCDByte, 0
Addlw 1
Btfsc BCDByte, 1
Addlw 2
Btfsc BCDByte, 2
Addlw 4
Btfsc BCDByte, 3
Addlw 8
Btfsc BCDByte, 4
Addlw 10
Btfsc BCDByte, 5
Addlw 20
Btfsc BCDByte, 6
Addlw 40
Btfsc BCDByte, 7
Addlw 80
Movwf BCDByte
Return
' BINARY to BCD conversion
' The byte to be converted is loaded into the variable BCDBYTE
' and is returned in the same variable BCDBYTE
BINBCD: Movf BCDByte, w
Clrf MSD
Movwf LSD
Gtenth: Movlw 10
Subwf LSD, w
Btfss 3, 0
GoTo Over
Movwf LSD
Incf MSD, F
GoTo Gtenth
Over: Swapf MSD, F
Movf LSD, w
Iorwf MSD, w
Movwf BCDByte
Return
' Turn off the LCD's flashing cursor
Coff: PortB = 0 ' Place the first 4-bits on PortB
High PORTE.1 ' Strobe the EN line High - Low
Low PORTE.1
PortB=%11000000 ' Place the next 4-bits on PortB 11000000
High PORTE.1 ' Strobe the EN line High - Low
Low PORTE.1
High PORTE.0 ' Back into character mode
Return ' Exit the subroutine
End ' Mandatory END statement
İlginiz iiçin teşekkür ediyorum. Bu son verdiğim program picbasic plus ile yazılmış. Diğerleri pic basic pro. Donanımda hata yaptığımı sanmıyorum lakin şekil çizemediğim için yazayım. DS 1307 için 1-2 uçlarına 32.768 Khz kristal bağladım. 3 nolu uç 3 volt batery (bu uygulamada koymadım daha sonra yerleştireceğim) 4 - GND, 5-SDA, 6-SCL, 7 SQW/OUT ( kullanmadım) ,8- Vcc, PCF 8583 te DS nin hemen hemen aynısı, sadece 3 numaralı uç A0 ucu, 7 numaralı ucu ise INT çıkışı. Sevgili mmengi bunu denerken , I2C rutini mi kullandın, Kullandığın rutini aynen yazabilirsen , en azından hatayı donanımda arayacağım. kullandığım 16F877 20 Mhz, şu anda 4Mhz de çalıştırıyırum sırf okutabilmek için ( 100Khz için), Ayrıca yaptığın donanımı çizip, sadece RTC programını http://groups.yahoo.com/group/PicProjeUP/files adresine yükleyebilirsen çok çok teşekkür ederim. İyi çalışmalar.
Re : mhk
Ben DS1307 yi bir proje icin kullanmıstım.
en son yazdıgın nota kadar sorunun ne oldugunu anlamadım ancak son yazdıgın notta hersey acıga cıktı(bence)...
DS1307'nin battery ucunu bosta bıramazsın.
gerci datasheet inde boyle birsey gormedim ama yaptıgım denemlerden biliyorumki bu ucu bos bıraktıgında problemler ortaya cıkıyor.
eger simdilik pil baglamayı dusunmuyorsan o ucun GND ye bagla calısacaktır.
Ben 8051 kullandıgım ve koduda C ile yazdıgım icin ornek kod veremiyorum.
ancak yinede gorelim ornegi derseniz paste ederim kodu..
İyi calısmalar.
DerWish.
Yazilarinizi hizli bir sekilde baktım RTC de bazi problemlerle karşılaşmışsınız ben RTC olarak MK41T56N kullaniyorum Gayet güzel çalişiyor 8051 ile çalıştırıyorum.
sevgili mhk yukarıda verdiğin programların bazılarını ben daha önce denemiştim ve çalışmıştı. SDA SCL uclarını 10K ile PULLUP yaptığını belirtmemişsin. belki backup pili devrede olmadığından sorun çıkıyordur.tekrar inceleyip sonucu yazarım.
kolay gelsin
dostum aşağıdaki adreste benim çalıştırıp denediğim program ve proteus da çizilmiş şeması var. DS1307 uçlarını belirttim ds1307 nin diğer uçları data sheet indeki gibi olacak. Bir dene istersen. program 16f628 için hazırlanmış.
http://groups.yahoo.com/group/PicProjeUP/files/mmengi/
Teşekkür ederim arkadaşlar. Tavsiyelerinizi deneyeceğim. İnşaallah olur. DS 1307 yerine PCF 8583 denemiştim onda da aynı sonuç olmuştu. İyi çalışmalar.
ben NJU6355 kullanmayi dusunuyorum. Nereden bulabiliriz?
Sevgili arkadaşlar. sorun adresteymiş. PCF için bulduğum kodta adres bilgisi diğerlerinden ( DS1307 ) farklı. Saat ve tarih tamam. Aşağıda denenmiş çalışan programı inceleyebilirsiniz. Sevgili Erol PCF8583 ü bir dene istersen kod olarak çok basit ve sorunsuz.SCL ve SDA hattında iki eleman ( PCF8583 ve AT24C64 ) bağlı olduğunu ve test için en alttaki eeprom kodunuda yazdım.
' LCD saat programı using PCF8583 RTC
define osc 20
@ device WDT_OFF & pwrt_on
Define LCD_DREG PORTD ' Define LCD connections
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
ADCON1 = 7 ' PORTA and E digital
Low PORTE.2 ' LCD R/W low = write
Pause 100 ' Wait for LCD to startup
symbol Up=portb.3
symbol Down=portb.2
symbol Set=portb.1
symbol SCL=portc.0
symbol SDA=portc.1
kontrol con %10100000
sec var bit
B0 var byte
S var byte
M var byte
H var byte
D var byte
Mn var byte
Y var byte
addr var word
linedeg var byte
addr=0
linedeg=0
OPTION_REG=$7F
Lcdout $FE,1
main:
toggle sec
I2CREAD SDA,SCL,%10100001,2,[S,M,H,D,Mn,Y]
Lcdout $FE,2
Lcdout "Saat: ",hex2(H),":",hex2(M)," ",hex2(S)
Lcdout $FE,$C0
Lcdout "Tarih: ",hex2(D),".",hex2(Mn),".20",hex2(Y)
if sec=0 then
Lcdout $FE,$8B," "
else
Lcdout $FE,$8B,":"
endif
I2cread SCL,SDA,kontrol,addr,[linedeg]
addr=addr+1
if addr>20 then addr=0
Lcdout $FE,$D4,"Eep addr=",dec addr," Ok=",dec linedeg," "
pause 500
goto main
end
Pcf8583'un guncel fiyati nedir? Nerelerden bulabiliriz?
Sevgili Erol ben istanbuldan getirtmiştim sanırım 4.000.000 TL idi kadıköyden alınmış. Diğer arkadaşlar 1,5 dolar civarında diyorlardı. Tam bilmiyorum.
pcf 8583 te yıl ve gün aynı adreste saklanıyor yukarıda verilen kod çalışmaz.
bende pcf8583 üzerinde çalışıyorum sadece
yılı okutmada problem yaşıyorum
2 bit ile nasıl yıl okutulacağını bilen varsa cevap yazsın.Yılı okuttuğumda kodu koyacağım.
Dogru PCF 8583 te yıl-gün hafta günleri ile ay aynı adreste saklanıyor. bu nu maskeleyip shift ederek çözebilirsin. PCF 8583
yıl ı iki bit olarak veriyor. 4 yılda bir kez şubat 29 çekiyor, PCF de şubatın 29 çektiği yıllarda o iki biti sıfırlıyor yıllar arttıkça 1,2,3 ve sonra yine 0 oluyor. sen yazdıgın program içine küçük bir rutin
ekleyerek tarihi bu bitlere bakarak kandin hesaplaya bilirsin. PCF serisinin yılı tam olarak vereni de var ama ismini hatırlayamıyorum. ama onunda counter modu yok counter kullanmayacaksan
sorun olmaz. bende sevgili MHK nin ki gibi bir sorunla karsılasmıstım. PCF 8583 ün kristal bağladıgımız 2 nolu ucuna aynı zamanda 22pF kondansatörle VCC ye vermek gerekiyormuş
yapmadıgım zaman PCF tarihi arttırmıyordu. aklınızda bulunsun. basarılar.