How do I set the year in the RTC module
How do I set the year in the RTC module
Hi,
Can someone please explain how to set the year in the RTC module. In the data sheet it states, memory location 05 (year/date), year (0 to 3 binary, read as 0 if the mask flag is set). What does this mean? In the mB example, memory location 05 is hex 24 which is binary 00100100 so according to the data sheet bits 7 and 6 (year) = 0, bits 5 and 4 (ten days) = dec 2, bits 3 - 0 (unit days BCD) = dec 4, all this gives us a date of the 24th. How do I change the year to 2006?
P.S. I assume that the date format displayed on the LCD is day/month/year if I'm wrong then I am totally confused.
Can someone please explain how to set the year in the RTC module. In the data sheet it states, memory location 05 (year/date), year (0 to 3 binary, read as 0 if the mask flag is set). What does this mean? In the mB example, memory location 05 is hex 24 which is binary 00100100 so according to the data sheet bits 7 and 6 (year) = 0, bits 5 and 4 (ten days) = dec 2, bits 3 - 0 (unit days BCD) = dec 4, all this gives us a date of the 24th. How do I change the year to 2006?
P.S. I assume that the date format displayed on the LCD is day/month/year if I'm wrong then I am totally confused.
Ken,
I don't use the PCF8583 but after looking at the datasheet I think I understand how to do this. Address locations 05 and 06 in the IC have double duty. Each of these addresses can be one of two things depending on how you set/reset Bit3 of the Control Register.
For instance, if you make Bit3 = 1 in the Control Register, address 05 is the DATE value and address 06 is the MONTH value. If Control Register Bit3 = 0, then address 05 is the YEAR value and address 06 is the WEEKDAY value. It's a shortcut method of addressing registers used by this IC.
Also note that each byte is made up of 2 BCD values. That means that the Lower Nybble (4-bits) of a byte is a value from 0 to 9 for the decimal 1's position, and the Upper Nybble is a value of 0 to 9 for decimal 10's position. So a value of HEX 24 ($24) is really equivalent to decimal 24.
I don't use the PCF8583 but after looking at the datasheet I think I understand how to do this. Address locations 05 and 06 in the IC have double duty. Each of these addresses can be one of two things depending on how you set/reset Bit3 of the Control Register.
For instance, if you make Bit3 = 1 in the Control Register, address 05 is the DATE value and address 06 is the MONTH value. If Control Register Bit3 = 0, then address 05 is the YEAR value and address 06 is the WEEKDAY value. It's a shortcut method of addressing registers used by this IC.
Also note that each byte is made up of 2 BCD values. That means that the Lower Nybble (4-bits) of a byte is a value from 0 to 9 for the decimal 1's position, and the Upper Nybble is a value of 0 to 9 for decimal 10's position. So a value of HEX 24 ($24) is really equivalent to decimal 24.
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]
[url=http://circuit-ed.com]CircuitED -[/url]
Hi Xor,
Thanks for taking the time to look over the data sheet. That didn't work. This is what I tried:
Thanks for taking the time to look over the data sheet. That didn't work. This is what I tried:
Code: Select all
main:
I2C_Init(10000) ' initialize full master mode
I2C_Start ' issue start signal
I2C_Wr($A0) ' address PCF8583
I2C_Wr(0) ' start from word at address 0 (configuration word)
I2C_Wr($80) '0 write $80 to config. (pause counter...)
I2C_Wr($0) '1 write 0 to cents word
I2C_Wr($0) '2 write 0 to seconds word
I2C_Wr($27) '3 write $30 to minutes word
I2C_Wr($11) '4 write $11 to hours word
I2C_Wr($24) '5 write $24 to year/date word
I2C_Wr($11) '6 write $08 to weekday/month
I2C_Stop ' issue stop signal
I2C_Start
I2C_Wr(0) ' start from word at address 0 (configuration word)
I2C_Wr($88) '0 write $88 to config. set bit 3
I2C_Wr(5) ' start from word at address 5 (year/date word)
I2C_Wr($86)
I2C_Stop ' issue stop signal
I2C_Start ' issue start signal
I2C_Wr($A0) ' address PCF8530
I2C_Wr(0) ' start from word at address 0
I2C_Wr(0) ' write 0 to config word (enable counting)
I2C_Stop ' issue stop signal
end.
Got it!
Found this in another post, I2C_Wr($80+$13), sorry I forget who's post it was.
Code: Select all
main:
I2C_Init(10000) ' initialize full master mode
I2C_Start ' issue start signal
I2C_Wr($A0) ' address PCF8583
I2C_Wr(0) ' start from word at address 0 (configuration word)
I2C_Wr($80) '0 write $80 to config. (pause counter...)
I2C_Wr($0) '1 write 0 to cents word
I2C_Wr($0) '2 write 0 to seconds word
I2C_Wr($27) '3 write $30 to minutes word
I2C_Wr($11) '4 write $11 to hours word
I2C_Wr($80+$13) ' 5 write $80=2006, +$13 to year/date word
I2C_Wr($08) '6 write $08 to weekday/month
I2C_Stop ' issue stop signal
I2C_Start ' issue start signal
I2C_Wr($A0) ' address PCF8530
I2C_Wr(0) ' start from word at address 0
I2C_Wr(0) ' write 0 to config word (enable counting)
I2C_Stop ' issue stop signal
end.
I'm still trying to figure out how $80 is equivalent to 2006 in Address 05. The datasheet is not much help here either. Somehow setting the year seems to still be a different read/write based on setting/resetting the mask bit (Bit3)
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]
[url=http://circuit-ed.com]CircuitED -[/url]
so is it. the pcf8583 can not handl the year fully.
you have to store the real year in one of the free eeprom and to correct if the yeare calendar is changed.
so there is only a counter 0 - 4 and you have to set them so thad the switch yeare was to yeare a go. remember every olympia year is a switch year.
the real count of 2006, 2007, 2008 and more have the software to do.
you have to store the real year in one of the free eeprom and to correct if the yeare calendar is changed.
so there is only a counter 0 - 4 and you have to set them so thad the switch yeare was to yeare a go. remember every olympia year is a switch year.
the real count of 2006, 2007, 2008 and more have the software to do.
-
- Posts: 361
- Joined: 14 Dec 2005 20:56
- Location: Slovenia
Look this code and help yourself.
Code: Select all
program ura2_usart
' 18F458-HS mikroBasic2.2
symbol OWP = PORTA
symbol PIN = 5
dim cnt, cnt1 as byte
dim txtmin as char[16]
dim K1 as integer
dim D0,D1,D2,D3,D4 as byte
dim Sec as byte
dim Min as byte
dim Hr as byte
dim Day as byte
dim Mn as byte
dim Year as byte
dim txt,txt1 as char[16]
dim minuta, ura, ura10, dan, mesec, leto as byte
sub procedure Set_Clk
Soft_I2C_Start ' issue start signal
Soft_I2C_Write($A0) ' address PCF8583
delay_ms(20)
Soft_I2C_Write(0) ' start from word at address 0 (configuration word)
delay_ms(20)
Soft_I2C_Write($80) '0 write $80 to config. (pause counter...)
delay_ms(20)
Soft_I2C_Write(0) '1 write 0 to cents word
delay_ms(20)
Soft_I2C_Write(0) '2 write 0 to seconds word
delay_ms(20)
Soft_I2C_Write(minuta) '3 write $56 to minutes word
delay_ms(20)
Soft_I2C_Write(ura10+ura) ' 4 $80 is 12hr mode A.M., write $10 to hours word '$20+$03 'ura10
delay_ms(20) ' $C0 is 12hr mode P.M.,
Soft_I2C_Write($80+dan) ' 5 write $80=2006, +$17 to year/date word
delay_ms(20)
Soft_I2C_Write(mesec) ' 6 write $02 to weekday/month
delay_ms(20)
Soft_I2C_Stop ' issue stop signal
Soft_I2C_Start ' issue start signal
Soft_I2C_Write($A0) ' address PCF8530
delay_ms(20)
Soft_I2C_Write(0) ' start from word at address 0
delay_ms(20)
Soft_I2C_Write(0) ' write 0 to config word (enable counting)
delay_ms(20)
Soft_I2C_Stop ' issue stop signal
end sub
sub procedure Set_Time
Lcd_Cmd(Lcd_Clear)
lcd_out(1,1,"Set Time Date")
D1 = TestBit(PORTD,1)
if D1 = 1
then inc(cnt1)
if cnt1 = 7 then cnt1 = 0 end if
end if
if cnt1 = 0 then lcd_out(2,1,"Time menu") end if
if cnt1 = 1
then lcd_out(2,1,"minute") ByteToStr(Min,txt) LCD_Out(2,9,txt)
D3 = TestBit(PORTD,3)
if D3 = 1
then Inc(K1)
if K1 > $59 then K1 = $1 end if
if K1 = 10 then K1 = 16 end if
if K1 = 26 then K1 = 32 end if
if K1 = 42 then K1 = 48 end if
if K1 = 58 then K1 = 64 end if
if K1 = 74 then K1 = 80 end if
end if
D4 = TestBit(PORTD,4)
if D4 = 1
then Dec(K1)
if K1 < $1 then K1 = $59 end if
if K1 = 15 then K1 = 9 end if
if K1 = 31 then K1 = 25 end if
if K1 = 47 then K1 = 41 end if
if K1 = 63 then K1 = 57 end if
if K1 = 79 then K1 = 73 end if
end if
minuta=K1 Set_Clk
end if
if cnt1 = 2
then lcd_out(2,1,"ura10") ByteToStr(Hr,txt) LCD_Out(2,9,txt)
D3 = TestBit(PORTD,3)
if D3 = 1
then Inc(K1)
if K1 > $23 then K1 = $1 end if
if K1 = 10 then K1 = 16 end if
end if
D4 = TestBit(PORTD,4)
if D4 = 1
then Dec(K1)
if K1 < $1 then K1 = $23 end if
if K1 = 15 then K1 = 9 end if
end if
ura10=K1 Set_Clk
end if
if cnt1 = 3
then lcd_out(2,1,"ura") ByteToStr(Hr,txt) LCD_Out(2,9,txt)
D3 = TestBit(PORTD,3)
if D3 = 1
then Inc(K1)
if K1 > $23 then K1 = $1 end if
if K1 = 10 then K1 = 16 end if
if K1 = 26 then K1 = 32 end if
end if
D4 = TestBit(PORTD,4)
if D4 = 1
then Dec(K1)
if K1 < $1 then K1 = $23 end if
if K1 = 15 then K1 = 9 end if
if K1 = 31 then K1 = 25 end if
end if
ura=K1 Set_Clk
end if
if cnt1 = 4
then lcd_out(2,1,"dan") ByteToStr(day,txt) LCD_Out(2,9,txt)
D3 = TestBit(PORTD,3)
if D3 = 1
then Inc(K1)
if K1 > $31 then K1 = $1 end if
if K1 = 10 then K1 = 16 end if
if K1 = 26 then K1 = 32 end if
if K1 = 42 then K1 = 48 end if
end if
D4 = TestBit(PORTD,4)
if D4 = 1
then Dec(K1)
if K1 < $1 then K1 = $31 end if
if K1 = 15 then K1 = 9 end if
if K1 = 31 then K1 = 25 end if
if K1 = 47 then K1 = 41 end if
end if
dan=K1 Set_Clk
end if
if cnt1 = 5
then lcd_out(2,1,"mesec") ByteToStr(Mn,txt) LCD_Out(2,9,txt)
D3 = TestBit(PORTD,3)
if D3 = 1
then Inc(K1)
if K1 > $12 then K1 = $1 end if
if K1 = 10 then K1 = 16 end if
end if
D4 = TestBit(PORTD,4)
if D4 = 1
then Dec(K1)
if K1 < $1 then K1 = $12 end if
if K1 = 15 then K1 = 9 end if
end if
mesec=K1 Set_Clk
end if
if cnt1 = 6
then lcd_out(2,1,"leto") ByteToStr(leto,txt1) LCD_Out(2,9,txt1)
D3 = TestBit(PORTD,3)
if D3 = 1
then Inc(K1)
if K1 > 9 then K1 = 0 end if
end if
D4 = TestBit(PORTD,4)
if D4 = 1
then Dec(K1)
if K1 < 0 then K1 = 9 end if
end if
leto=K1 Set_Clk
end if
end sub
sub procedure Zero_fill(dim byref value as char[10]) ' fill text representation
if length(value) = 1 then ' with leading zero
value[2] = value[1]
value[1] = 48
value[0] = 2
end if
end sub
sub procedure Read_time(dim byref Sec as byte,
dim byref Min as byte,
dim byref Hr as byte,
dim byref Day as byte,
dim byref Mn as byte)
soft_i2c_start
delay_us(20)
soft_i2c_write($A0)
delay_us(20)
soft_i2c_write(2)
delay_us(20)
soft_i2c_start
delay_us(20)
soft_i2c_write($A1)
delay_us(20)
sec=soft_i2c_read(1)
min = soft_i2c_read(1)
hr = soft_i2c_read(1)
day =soft_i2c_read(1)
mn = soft_i2c_read(0)
soft_I2C_Stop
end sub
sub procedure Transform_time(dim byref Sec as byte,
dim byref Min as byte,
dim byref Hr as byte,
dim byref Day as byte,
dim byref Mn as byte,
dim byref Year as byte)
sec = ((sec and $F0) >> 4)*10 + (sec and $0F) ' formats date and time
min = ((min and $F0) >> 4)*10 + (min and $0F)
hr = ((hr and $F0) >> 4)*10 + (hr and $0F)
year = ((day and $C0)) >> 6
day = ((day and $30) >> 4)*10 + (day and $0F)
mn = ((mn and $10) >> 4)*10 + (mn and $0F)
end sub
sub procedure Display_time_txt
Lcd_Cmd(Lcd_Clear)
txt = "Datum"
LCD_Out(1,1,txt)
txt = "Ura"
LCD_Out(2,1,txt)
txt = "200"
LCD_Out(1,13,txt)
end sub
sub procedure Display_time_txt1
Lcd_Chr(1,9,".")
Lcd_Chr(1,12,".")
Lcd_Chr(2,9,":")
Lcd_Chr(2,12,":")
end sub
sub procedure Display_time(dim Sec as byte,
dim Min as byte,
dim Hr as byte,
dim Day as byte,
dim Mn as byte,
dim Year as byte)
cnt1=0
ByteToStr(day,txt)
Zero_fill(txt)
LCD_Out(1,6,txt)
ByteToStr(mn,txt)
Zero_fill(txt)
LCD_Out(1,9,txt)
LCD_Chr(1,16,46+leto+year)
ByteToStr(hr,txt)
LCD_Out(2,6,txt)
ByteToStr(min,txtmin)
Zero_fill(txtmin)
LCD_Out(2,9,txtmin)
ByteToStr(sec,txt)
Zero_fill(txt)
LCD_Out(2,12,txt)
D2 = TestBit(PORTD,2)
if D2 = 1
then Set_Clk
end if
end sub
main:
'
adcon1 = 255 ' configure RA5 pin as digital I/O
CMCON = 7 ' comparators on portD off
PORTB = 0 ' initialize PORTB
PORTC = 0 ' initialize PORTC
PORTD = 255 ' initialize PORTD
PORTA = 255 ' initialize PORTA
TRISB = 0 ' designate PORTB as output
TRISC = 0 ' designate PORTC as output
TRISD = 255 ' designate PORTD as input
TRISA = 255 ' designate PORTA as input
soft_i2c_config(PORTE,1,0)
Lcd_Init(PORTB)
lcd_cmd( LCD_CURSOR_OFF)
Usart_Init(9600) ' Initialize USART module 2400
minuta = $59
ura = $03
ura10 = $20
dan = $17
mesec = $04
leto = 0
cnt = 1
cnt1= 0
K1 = $30
while true
SetBit(PORTC,0)
Delay_ms(200)
Read_Time(Sec, Min, Hr, Day, Mn) ' read time from RTC(PCF8583)
Transform_Time(Sec, Min, Hr, Day, Mn, Year)
D0 = TestBit(PORTD,0)
if D0 = 1
then inc(cnt)
if cnt = 3 then cnt = 1 end if
end if
if cnt = 1 then Display_time_txt Display_Time(Sec, Min, Hr, Day, Mn, Year)
Display_time_txt1 end if
if cnt = 2 then Set_Time end if
ClearBit(PORTC,0)
Delay_ms(100)
Usart_Write(sec) ' Send data via USART
wend
end.
Can you explain how $80 = 2006? How would you write the year 2007?
Code: Select all
Soft_I2C_Write($80+dan) ' 5 write $80=2006, +$17 to year/date word
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]
[url=http://circuit-ed.com]CircuitED -[/url]
Found it! The year is 00 to 99 and is written at address 08, not 05 and 06. This is from an application note: http://www.standardics.philips.com/supp ... clocks.pdf
8. Initialization
Setting the clock is a straight forward procedure, setting first the mode and then the actual time: e.g Friday, July 16 1999, 2’45 pm
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]
[url=http://circuit-ed.com]CircuitED -[/url]
You're right. There are some differences between the datasheet and the application notes. Hmmmm? If I were to take another guess, the year is not actually available except for user reference. It seems that it's 0 to 3 only, which may only be important to help identify a leap year. I think I'll stick to my DS1307.
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]
[url=http://circuit-ed.com]CircuitED -[/url]
i not undersoud wy you gays not axept thad the PCF8583 not have a full yeare calendar.
the sample code from wath you speak i never cared about.
i wrote selve one witch is made in order of the datasheet. and it works.
i not have to look about mistakte by copy it in know each line because i wrote it selve.
the sample code from wath you speak i never cared about.
i wrote selve one witch is made in order of the datasheet. and it works.
i not have to look about mistakte by copy it in know each line because i wrote it selve.