Mit I2C RTC PCF8583 interne Uhr setzen und umgekehrt Kategorie: Programmierung Basic (von Ernst H. - 20.11.2010 22:08) | ||
| ||
'Mit I2C RTC PCF8583 interne Uhr setzen und umgekehrt 'RTC PCF8583 setzen und auslesen 'Test von Schaltjahr und Jahresübergang 'Wochentag wurde hier nicht berücksichtigt, da ich den aus dem Datum 'eindeutig generiere - später. 'u.U. müssen Vorkehrungen getroffen werden, wenn exakt zwischen den Transfer 'ein �berlauf entsteht - von RTC kann 1/100 sec abgefragt werden dh. vor ' 90/100sec ausführen. ' ' Frage kann man von der internen Uhr auch die 1/100sec abfragen? ' ' fertiges Programm einfach starten! Dim zeile1(17), zeile2(17) As Char '2*16 char display Dim Text(20) As Char Dim minute, hour, second As Byte Dim day, month, year As Byte Dim Schleife As Byte Dim cnt As Integer '--------------------------------------------------------------------------- Sub main() LCD_Init() LCD_ClearLCD() I2C_Init(I2C_100kHz) AbsDelay(100) Do cnt=cnt+1 second = Read_PCF(0x02) 'Sekunden second=((second>>4)*10)+(second And 0x0F) ' BCD to Dezimal minute = Read_PCF(0x03) 'Minuten minute=((minute>>4)*10)+(minute And 0x0F) hour = Read_PCF(0x04) hour = hour And &H3F 'Stunden mit Bitmaske hour=((hour>>4)*10)+(hour And 0x0F) day = Read_PCF(0x05) year = Read_PCF(0x10)+ ((day And 0b11000000)>>6)'Klammer für Schiebebefehl! day = day And 0x3F 'Tag mit Bitmaske day=((day>>4)*10)+(day And 0x0F) month = Read_PCF(0x06) month = month And 0x1F 'Monat mit Bitmaske month=((month>>4)*10)+(month And 0x0F) Msg_WriteInt(cnt) Msg_WriteChar(9) 'mit Tab Msg_WriteText("RTC= " ) If day<10Then :Msg_WriteChar(32):End If Msg_WriteInt(day) Msg_WriteChar(46) 'Punkt If month<10Then :Msg_WriteChar(32):End If Msg_WriteInt(month) Msg_WriteChar(46) 'mit Tab If year<10Then :Msg_WriteChar(32):End If Msg_WriteInt(year) Msg_WriteChar(32) 'mit Tab If hour<10Then :Msg_WriteChar(32):End If Msg_WriteInt(hour) Msg_WriteChar(58) ' Doppelpunkt 'Msg_WriteInt((second/10)*16 + second Mod 10) If minute<10Then :Msg_WriteChar(32):End If Msg_WriteInt(minute) Msg_WriteChar(58) If second<10Then :Msg_WriteChar(32):End If Msg_WriteInt(second) Msg_WriteChar(9) Msg_WriteText("Intern= " ) If Clock_GetVal(CLOCK_DAY )<10Then :Msg_WriteChar(32):End If Msg_WriteInt(Clock_GetVal(CLOCK_DAY)+1) '+1 ...0 basiert Msg_WriteChar(46) 'Punkt If Clock_GetVal(CLOCK_MON)<10Then :Msg_WriteChar(32):End If Msg_WriteInt(Clock_GetVal(CLOCK_MON)+1) '+1 ...0 basiert Msg_WriteChar(46) 'mit Tab If Clock_GetVal(CLOCK_YEAR)<10Then :Msg_WriteChar(32):End If Msg_WriteInt(Clock_GetVal(CLOCK_YEAR)) Msg_WriteChar(32) 'mit Tab If Clock_GetVal(CLOCK_HOUR)<10Then :Msg_WriteChar(32):End If Msg_WriteInt(Clock_GetVal(CLOCK_HOUR)) Msg_WriteChar(58) ' Doppelpunkt If Clock_GetVal(CLOCK_MIN)<10Then :Msg_WriteChar(32):End If Msg_WriteInt(Clock_GetVal(CLOCK_MIN)) Msg_WriteChar(58) If Clock_GetVal(CLOCK_SEC)<10Then :Msg_WriteChar(32):End If Msg_WriteInt(Clock_GetVal(CLOCK_SEC)) Msg_WriteChar(32) ' neue Zeile Display_Buffer_Set() 'Convert to 2 text lines LCD_CursorOff() LCD_CursorPos(0x00+0) LCD_WriteText(zeile1) LCD_CursorPos(0x40+0) LCD_WriteText(zeile2) AbsDelay(1000) Select Case Schleife Case 8 Clock_SetTime(23,59,55,0 ) Clock_SetDate(30,11,10 ) 'Tag und Monat -1 ..da 0-basiert!!!!! IntUhr_to_RTC () Case 17 Clock_SetTime(12,34,57,0 ) Clock_SetDate(12,5,10 ) 'Tag und Monat -1 ..da 0-basiert!!!!! Msg_WriteText("intern verändert" ) Case 20 RTC_to_IntUhr( ) Case 30 Clock_SetTime(23,59,55,0 ) Clock_SetDate(27,1,10 ) 'Tag und Monat -1 ..da 0-basiert!!!!! Msg_WriteText("intern verändert-Schaltjahrtest" ) Case 32 IntUhr_to_RTC () Case 40 RTC_to_IntUhr( ) Case 50 Clock_SetTime(23,59,55,0 ) Clock_SetDate(27,1,12 ) 'Tag und Monat -1 ..da 0-basiert!!!!! Msg_WriteText("intern verändert-Schaltjahrtest" ) Case 52 IntUhr_to_RTC () Case 60 Clock_SetTime(12,34,57,0 ) Clock_SetDate(12,5,10 ) 'Tag und Monat -1 ..da 0-basiert!!!!! Msg_WriteText("intern verändert" ) Case 62 RTC_to_IntUhr( ) End Select ++Schleife Msg_WriteChar(13 ) Loop While(1) End Sub ' '---------------------------------------------------------------------------- ' Sub Display_Buffer_Set() 'Source: http://ccpro.cc2net.de/forum/index.php?show=2988 'Converted from C to Basic Dim sep(2) As Char sep=":" Str_WriteWord(hour,10,zeile1,0,2) ' LCD erste Zeile xx:xx:xx Str_Copy(zeile1,sep,STR_APPEND) Str_WriteWord(minute,10,zeile1,STR_APPEND,2) Str_Copy(zeile1,sep,STR_APPEND) Str_WriteWord(second,10,zeile1,STR_APPEND,2) sep="." Str_WriteWord(day,10,zeile2,0,2) ' LCD zweite Zeile xx.xx.xx Str_Copy(zeile2,sep,STR_APPEND) Str_WriteWord(month,10,zeile2,STR_APPEND,2) Str_Copy(zeile2,sep,STR_APPEND) Str_WriteWord(year,10,zeile2,STR_APPEND,2) End Sub ' '--------------------------------------------------------------------------- 'Read out PCF8583 (Real time clock) Sub Read_PCF(adr As Byte) As Byte Dim PCF_DATA As Byte I2C_Start() I2C_Write(0xA0) 'Adresse des PCF 8583 (Pin A0 =1 address 0xA2, ' ist Pin A0=0 dann 0xA0) I2C_Write(adr) 'Adresse des zu lesenden Byte I2C_Stop() I2C_Start() I2C_Write(0xA1) 'Adresse des PCF mit Lesebit gesezt (* 0xA1) PCF_DATA=I2C_Read_NACK() 'lesen des Bytes Adresse adr I2C_Stop() Return PCF_DATA ' return I2C Data Register End Sub Sub Write_PCF(adr As Byte,Daten As Byte) 'Dim PCF_DATA As Byte I2C_Start() I2C_Write(0xA0) 'Adresse des PCF 8583 (Pin A0=1 address 0xA2, 'ist Pin A0=0 dann 0xA0) Schreibadresse I2C_Write(adr) 'Adresse des zu schreibenden Byte I2C_Write(Daten ) 'Daten an diese Adresse I2C_Stop() End Sub '#define CLOCK_SEC 0 ' Sekunde 'nicht nötig da bereits definiert '#define CLOCK_MIN 1 ' Minute '#define CLOCK_HOUR 2 ' Stunde '#define CLOCK_DAY 3 ' Tag '#define CLOCK_MON 4 ' Monat '#define CLOCK_YEAR 5 ' Jahr Sub IntUhr_to_RTC () 'interne Uhr wird in RTC gespeichert Dim Zwischen As Byte 'sollte nicht in der 59.sec wegen u.U. �berlauf erfolgen! Zwischen = Clock_GetVal(CLOCK_SEC) Write_PCF(2,(Zwischen/10)*16 + Zwischen Mod 10) 'SEC im BCD Format speichern Zwischen = Clock_GetVal(CLOCK_MIN) Write_PCF(3,(Zwischen/10)*16 + Zwischen Mod 10) 'MIN im BCD Format speichern Zwischen = Clock_GetVal(CLOCK_HOUR) Write_PCF(4,(Zwischen/10)*16 + Zwischen Mod 10) 'Std im BCD Format speichern Zwischen = Clock_GetVal(CLOCK_DAY)+1 '+1...da Tag 0-basiert 'in PCF Adr 5 ist Tag und 0-3 Jahr codiert (Schaltjahre) Rest von Jahr in Adr16 Write_PCF(5,(Zwischen/10)*16+Zwischen Mod 10+(Clock_GetVal(CLOCK_YEAR)Mod 4)*64) 'Rest von Jahr ... Jahr - Jahr Mod 4 ...in Adr 0x10 bzw Dezimal Adr 16 Write_PCF(0x10,Clock_GetVal(CLOCK_YEAR)- Clock_GetVal(CLOCK_YEAR)Mod 4) Zwischen = Clock_GetVal(CLOCK_MON)+1 '+1...da Monat 0-basiert Write_PCF(6,(Zwischen/10)*16 + Zwischen Mod 10) Msg_WriteText("RTC neu mit Interner Clock gesetzt") End Sub Sub RTC_to_IntUhr() 'nicht in den letzten 90/100sec machen! �berlaufgefahr! second = Read_PCF(0x02) 'Sekunden second=((second>>4)*10)+(second And 0x0F) ' BCD to Dezimal minute = Read_PCF(0x03) 'Minuten minute=((minute>>4)*10)+(minute And 0x0F) hour = Read_PCF(0x04) hour = hour And &H3F 'Stunden mit Bitmaske hour=((hour>>4)*10)+(hour And 0x0F) Clock_SetTime(hour,minute,second,0 ) day = Read_PCF(0x05) year = Read_PCF(0x10)+((day And 0b11000000)>>6)'Klammer für Schiebebefehl! day = day And 0x3F 'Tag mit Bitmaske day=((day>>4)*10)+(day And 0x0F) month = Read_PCF(0x06) month = month And 0x1F 'Monat mit Bitmaske month=((month>>4)*10)+(month And 0x0F) Clock_SetDate(day-1, month-1,year ) 'Tag und Monat -1 ..da 0-basiert!!!! Msg_WriteText("Interne Clock neu mit RTC gesetzt") End Sub | ||
Antwort schreiben Antworten: |
Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum