Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum

Mit I2C RTC PCF8583 interne Uhr setzen und umgekehrt Kategorie: Programmierung Basic (von Ernst H. - 20.11.2010 22:08)
Ich nutze:
CC-Pro 128 Application Board, Pro-Bot128
'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: