See attached, my lib for the pca8565, would need tuning for ds1307, but these rtc have similarities.
I never used the alarm code, so it is untested.
Hopefully this helps.
[code:1:53b6d38433]'-------------------------------------------------------------------------------
' Author : Rick Savas
' copyright : 2012-Feb-18
' file : PCA8565_lib.inc
' date : 2014-Jan-15
' micro : ATMEL xmega series
' compiler : BASCOM-AVR by MCS Electronics
' compiler version : 2.0.5.0 & above
' compiler build : 2.0.5.0.0 & above
' updates :'Pca8565_second = Makebcd(second_)
'References: UM10301:User Manual for NXP Real Time Clocks PCF85x3, PCA8565 and PCF2123, PCA2125
' NXP PCA8565 Real time clock/calendar
'derived from: example from BASCOM-AVR forum User "MAK3" titled "Using PCF8583 with XMEGA" Thanks!!
'-------------------------------------------------------------------------------
'Assumes:
' That TWIC is setup on PortC using a ATxmega
'-------------------------------------------------------------------------------
$nocompile
'-------------------------------------------------------------------------------
'NXP PCA8565 defined constants
'PCA8565 Register address constants(word address), auto incrementing
Const Pca8565_ctrl_1 = &H00
Const Pca8565_ctrl_2 = &H01
Const Pca8565_second_reg = &H02
Const Pca8565_minute_reg = &H03
Const Pca8565_hour_reg = &H04
Const Pca8565_day_reg = &H05
Const Pca8565_weekday_reg = &H06
Const Pca8565_month_cent_reg = &H07
Const Pca8565_year_reg = &H08
Const Pca8565_alarm_min_reg = &H09
Const Pca8565_alarm_hour_reg = &H0A
Const Pca8565_alarm_day_reg = &H0B
Const Pca8565_alarm_weekday_reg = &H0C
Const Pca8565_clock_out_reg = &H0D
Const Pca8565_timer_cntrl_reg = &H0E
Const Pca8565_timer_reg = &H0F
Const Pca8565 = &B1010_001 'i2c address 1010_001_0(w)|1(r)
Const Pca8565_w = &B1010_001_0 'i2c write addr 0100_001_0(w) (A2h,162d)
Const Pca8565_r = Pca8565_w + 1 'i2c read addr 0100_001_1(r) (A3h,163d)
Dim Pca8565_alarm_array(4) As Byte
Dim Pca8565_second As Byte
Dim Pca8565_second_temp As Byte
Dim Pca8565_minute As Byte
Dim Pca8565_minute_temp As Byte
Dim Pca8565_hour As Byte
Dim Pca8565_hour_temp As Byte
Dim Pca8565_day As Byte
Dim Pca8565_day_temp As Byte
Dim Pca8565_weekday As Byte
Dim Pca8565_weekday_temp As Byte
Dim Pca8565_month As Byte
Dim Pca8565_month_temp As Byte
Dim Pca8565_cent As Byte
Dim Pca8565_vl As Byte
Dim Pca8565_cent_month As Byte
Dim Pca8565_year As Byte
Dim Pca8565_year_temp As Byte
Dim Pca8565_cnt As Byte , Pca8565_i As Byte
Dim Second_temp As Byte
Dim Minute_temp As Byte
Dim Op_state As Byte 'Poerational Mode:0=Normal, 1=Set Clock, 2=Setup Menu
Op_state = 0
Dim Setup_count As Integer
Dim Setup_menu As Integer 'Setup Menu function
Setup_menu = 0
Dim Setup_mode As Integer
Dim Pca8565_minute_count As Integer
Dim Pca8565_hour_count As Integer
Dim Pca8565_day_count As Integer
Dim Pca8565_weekday_count As Integer
Dim Pca8565_month_count As Integer
Dim Pca8565_year_count As Integer
Dim Alarm_min_set As Integer 'Set for "7:00 AM" as default
Alarm_min_set = 0
Dim Alarm_hour_set As Integer
Alarm_hour_set = 7
Dim Alarm_am_pm As Integer 'Set for "AM" as default
Alarm_am_pm = 0
Dim Alarm_state As Integer
Alarm_state = 0 'Set for "Off" as default
Dim Alarm_active As Byte
Alarm_active = 0 'Set alarm as inactive
Dim Alarm_active_min As Integer
Dim Snooze_count As Byte
Dim Snooze_count_max As Byte
Dim Alarm_active_min_count As Byte
Sub Pca8565_settime(byval Second_ As Byte , Byval Minute_ As Byte , Byval Hour_ As Byte , Byval Day_ As Byte , Byval Weekday_ As Byte , Byval Month_ As Byte , Byval Cent_ As Byte , Byval Year_ As Byte)
' 40 , 59 , 23 , 31 , 4 , 12 , 0 , 99) 'set time and date (24 hour format) as default
' sec min hr day wkdy mon cen yr
'Pca8565_second = Makebcd(second_) 'use current seconds as read by seconds change counter in main loop
Reset Pca8565_second.7 'vl bit set for clock integrity is guaranteed
Pca8565_minute = Makebcd(minute_) 'minutes
Pca8565_hour = Makebcd(hour_) 'hours
Pca8565_day = Makebcd(day_) 'days
Pca8565_weekday = Makebcd(weekday_) 'weekdays
Pca8565_cent_month = Makebcd(month_) 'months
If Cent_ = 1 Then
Set Pca8565_cent_month.7
Else
Reset Pca8565_cent_month.7
End If
Pca8565_year = Makebcd(year_) 'years
I2cstart #10 'generate start
I2cwbyte Pca8565_w , #10 'I2cwbyte &HA2 'write mode
I2cwbyte Pca8565_ctrl_1 , #10 'select seconds Register, (word address)
I2cwbyte &B00101_000
' ^--------- Normal Mode
' ^------- RTC clock is stopped
I2crepstart #10 'generate start
I2cwbyte Pca8565_w , #10 'I2cwbyte &HA2 'write mode
I2cwbyte Pca8565_second_reg , #10 'select seconds Register, (word address)
I2cwbyte Pca8565_second , #10 'write seconds
I2cwbyte Pca8565_minute , #10 'write minutes
I2cwbyte Pca8565_hour , #10 'write hours
I2cwbyte Pca8565_day , #10 'write days
I2cwbyte Pca8565_weekday , #10 'write weekdays
I2cwbyte Pca8565_cent_month , #10 'write months
I2cwbyte Pca8565_year , #10 'write years
I2crepstart #10 'generate start
I2cwbyte Pca8565_w , #10 'I2cwbyte &HA2 'write mode
I2cwbyte Pca8565_ctrl_1 , #10 'select seconds Register, (word address)
I2cwbyte &B00001_000
' ^--------- Normal Mode
' ^------- RTC clock runs
I2cstop #10
End Sub
'Recommended method for reading (writing) the time from spec:
'1. Send a START condition and the slave address for write (A2h).
'2. Set the address pointer to registers Seconds (02h).
'3. Send a RESTART condition or STOP followed by START.
'4. Send the slave address for read (A3h).
'5. Read the register Seconds.
'6. Read the register Minutes.
'7. Read the register Hours.
'8. Read the register Days.
'9. Read the register Weekdays.
'10. Read the register Months_century.
'11. Read the register Years.
'12. Send a STOP condition.
Sub Pca8565_gettime()
I2cstart #10 'generate start
I2cwbyte Pca8565_w , #10
I2cwbyte Pca8565_second_reg , #10 'select seconds Register, (word address) will auto-increment from here
I2crepstart #10 'generate repeated start
I2cwbyte Pca8565_r , #10 'write address to start reading from
I2crbyte Pca8565_second , Ack , #10 'Read register 02 - seconds
I2crbyte Pca8565_minute , Ack , #10 'Read register 03 - minutes
I2crbyte Pca8565_hour , Ack , #10 'Read register 04 - hours
I2crbyte Pca8565_day , Ack , #10 'Read register 05 - days
I2crbyte Pca8565_weekday , Ack , #10 'Read register 06 - weekday
I2crbyte Pca8565_cent_month , Ack , #10 'Read register 07 - century and month
I2crbyte Pca8565_year , Nack , #10 'Read register 08 - year
I2cstop #10 'generate stop
If Err = 1 Then Lcd "Error:Pca8565 not responding"
If Pca8565_cent_month.7 = 1 Then
Pca8565_cent = 1 '21xx
Else
Pca8565_cent = 0 '20xx
End If
If Pca8565_second.7 = 1 Then
Pca8565_vl = 1 'integrity of the clock information is not guaranteed
Else
Pca8565_vl = 0 'clock integrity is guaranteed
End If
Pca8565_second = Pca8565_second And &B0111_1111 'mask out VL bit 7 (clock integrity)
Pca8565_minute = Pca8565_minute And &B0111_1111 'mask out unused bits
Pca8565_hour = Pca8565_hour And &B0011_1111 'mask out unused bits
Pca8565_day = Pca8565_day And &B0011_1111 'mask out unused bits
Pca8565_month = Pca8565_cent_month And &B0001_1111 'mask out century & unused bits to get month
Pca8565_weekday = Pca8565_weekday And &B0000_0111 'mask out unused bits
End Sub
'Set Alarm
Sub Pca8565_set_alarm(byval Alarm_minute As Byte , Byval Alarm_hour As Byte , Byval Alarm_day As Byte , Byval Alarm_weekday As Byte)
Pca8565_alarm_array(1) = Makebcd(alarm_minute) 'minutes
Pca8565_alarm_array(1) = Pca8565_alarm_array(1) Or &B1000_0000 'Enable minute alarm as well
Pca8565_alarm_array(2) = Makebcd(alarm_hour) 'hours
Pca8565_alarm_array(2) = Pca8565_alarm_array(2) Or &B1000_0000 'Enable hours alarm as well
Pca8565_alarm_array(3) = Makebcd(alarm_day) 'days
Pca8565_alarm_array(3) = Pca8565_alarm_array(3) Or &B1000_0000 'Enable days alarm as well
Pca8565_alarm_array(4) = Makebcd(alarm_weekday) 'weekday
Pca8565_alarm_array(4) = Pca8565_alarm_array(4) Or &B1000_0000 'Enable weekday alarm as well
I2cstart #10 'generate start
I2cwbyte Pca8565_w , #10 'write address
I2cwbyte Pca8565_ctrl_2 , #10 'select Control register 2
I2cwbyte &B0000_1010 , #10 'enable Alarm Flag & Int, disable Timer Flag & Int bits
'^---------Alarm Flag active
'^--------timer flag inactive
'^-------Alarm Interrupt Enable
'^------timer interrupt disabled
I2crepstart #10 'generate repeated start
I2cwbyte Pca8565_alarm_min_reg , #10 'start with alarm minutes reg & auto-increment
I2cwbyte Pca8565_alarm_array(1) , #10 'minutes
I2cwbyte Pca8565_alarm_array(2) , #10 'hours
I2cwbyte Pca8565_alarm_array(3) , #10 'days
I2cwbyte Pca8565_alarm_array(4) , #10 'weekday
I2cstop #10
End Sub
Sub Display_time_print()
Select Case Pca8565_weekday
Case 0 : 'Lcd "Sun "
Print #1 , "Sun "; 'need semicolon at the end to suppress lf and cr
Case 1 : 'Lcd "Mon "
Print #1 , "Mon ";
Case 2 : 'Lcd "Tue "
Print #1 , "Tue ";
Case 3 : 'Lcd "Wed "
Print #1 , "Wed ";
Case 4 : 'Lcd "Thu "
Print #1 , "Thu ";
Case 5 : 'Lcd "Fri "
Print #1 , "Fri ";
Case 6 : 'Lcd "Sat "
Print #1 , "Sat ";
End Select
Select Case Pca8565_month
Case &B000_0001 : 'Lcd "Jan "
Print #1 , "Jan ";
Case &B000_0010 : 'Lcd "Feb "
Print #1 , "Feb ";
Case &B000_0011 : 'Lcd "Mar "
Print #1 , "Mar ";
Case &B000_0100 : 'Lcd "Apr "
Print #1 , "Apr ";
Case &B000_0101 : 'Lcd "May "
Print #1 , "May ";
Case &B000_0110 : 'Lcd "Jun "
Print #1 , "Jun ";
Case &B000_0111 : 'Lcd "Jul "
Print #1 , "Jul ";
Case &B000_1000 : 'Lcd "Aug "
Print #1 , "Aug ";
Case &B000_1001 : 'Lcd "Sep "
Print #1 , "Sep ";
Case &B001_0000 : 'Lcd "Oct "
Print #1 , "Oct ";
Case &B001_0001 : 'Lcd "Nov "
Print #1 , "Nov ";
Case &B001_0010 : 'Lcd "Dec "
Print #1 , "Dec ";
End Select
Print #1 , Bcd(pca8565_day) ; " " ; "2" ; Pca8565_cent ; Bcd(pca8565_year) ; " " ; Bcd(pca8565_hour) ; ":" ; Bcd(pca8565_minute) ; ":" ; Bcd(pca8565_second) ' ; Chr(13);
End Sub
[/code:1:53b6d38433]
↧