ich hab ein Byte, da stehen die ganzen Ereignisse drin. Bei mir ist das immer MB7
SYSCLK_evtSEC M 7.0 BOOL Systemuhr: Ereignis Sekunde
SYSCLK_evtMIN M 7.1 BOOL Systemuhr: Ereignis Minute
SYSCLK_evtHOUR M 7.2 BOOL Systemuhr: Ereignis Stunde
SYSCLK_evtDAY M 7.3 BOOL Systemuhr: Ereignis Tag
SYSCLK_evtWEEK M 7.4 BOOL Systemuhr: Ereignis Woche
SYSCLK_evtMONTH M 7.5 BOOL Systemuhr: Ereignis Monat
SYSCLK_evtYEAR M 7.6 BOOL Systemuhr: Ereignis Jahr
SYSCLK_RESERVE M 7.7 BOOL Systemuhr: Reserve
hier der Code für SysClk-Events in Step7 classic. In TIA hab ich den einfach konvertiert
und minimal angepasst. Aus TIA bekomm ich den Baustein aber leider nicht mehr als
Quelle raus.
Code:
FUNCTION_BLOCK "m7d_SYSCLK_EVENTS"
TITLE =Standard SystemClock EVENTS
//Fires an 1 cycle Event when the SystemClock changes it's values.
//Provides each event as single BOOL and all combined as evtFLAGs in
//a Byte.
//
//[IN]
//StartWeekOnSunMon : Start week on Sunday/Monday (configuration input)
// FALSE:= week start on Sunday
// TRUE := week starts on Monday
//
//[OUT]
//EVENTS as BOOL:
//evt_sec : Second changed
//evt_min : minute changed
//evt_hour : hour changed
//evt_day : day changed
//evt_week : week changed (on sunday or monday as configured
// with 'StartWeekOnMonday'
//evt_month: month changed
//evt_year: year changed
//
//evtFLAGs : Events combined as byte
// Bit 0: evt_sec
// ...
// Bit 6: evt_year
// Bit 7: not used (FALSE)
//
//AUTOR: S.Maag
//DATUM: 7/2013
//
//AENDERUNGSVERMERKE:
//--------------------------------------------------------------------------------
//DATUM NAME AENDERUNG
//--------------------------------------------------------------------------------
//16.10.2016 S.Maag fatalen Fehler P##Buffer Berechnung behoben:
// Falsche Bereichskennung ausgeblendet. FB funktionierte
// nicht mit Instanz-DB Aufruf, nur über Multiinstanz.
//
// Bereichskennung muss aus rel. Adresse aus AR2
// entfernt werden, da diese 84 DB ist. Wir benötigen
// aber 85 Instanz-DB.
// Code getestet mit FB1141: direkter Instanz-DB und
// Multinstanz mit 2x Verschachtelung. Funktion I.O.
//
//20.05.2014 S.Maag Fehler WeekChange behoben, da ms-Anteil vom falschen
// Datensatz (memSYSCLK_BCD) entfernt wurde, konnte
// der Wochentag von SYSCLK_BCD nicht erkannt werden.
//--------------------------------------------------------------------------------
//
//HINWEISE:
AUTHOR : 'S.Maag'
FAMILY : Maagic7
VERSION : 0.1
VAR_INPUT
StartWeekOnSunMon : BOOL ; //StartWeekOn Sunday/Monday: FALSE: week starts sunday; TRUE: week starts monday
END_VAR
VAR_OUTPUT
evt_sec : BOOL ; //Event second changed
evt_min : BOOL ; //Event minute changed
evt_hour : BOOL ; //Event hour changed
evt_day : BOOL ; //Event day changed
evt_week : BOOL ; //Event weed changed
evt_month : BOOL ; //Event month changed
evt_year : BOOL ; //Event year changed
evtFLAGs : BYTE ; //Event flags as byte: bit0: evt_sec .. bit6: evt_year
END_VAR
VAR
memSYSCLK_BCD : STRUCT //Speicher letzter Wert SystemUhr BCD Format
year : BYTE ;
month : BYTE ;
day : BYTE ;
hour : BYTE ;
min : BYTE ;
sec : BYTE ;
ms_1 : BYTE ;
weekday : BYTE ; //Millisekunden ohne Einerstelle
END_STRUCT ;
FP_evt_sec : BOOL ;
FP_evt_min : BOOL ;
FP_evt_hour : BOOL ;
FP_evt_day : BOOL ;
FP_evt_week : BOOL ;
FP_evt_month : BOOL ;
FP_evt_year : BOOL ;
END_VAR
VAR_TEMP
DATE_TIME : DATE_AND_TIME ;
iRET : INT ;
tmpFirstWeekday : INT ;
SYSCLK_BCD : STRUCT
year : BYTE ;
month : BYTE ;
day : BYTE ;
hour : BYTE ;
min : BYTE ;
sec : BYTE ;
ms_1 : BYTE ;
weekday : BYTE ;
END_STRUCT ;
END_VAR
BEGIN
NETWORK
TITLE =Copy system clock to temp memory
//Das DATE_AND_TIME Format benötigt 8 Byte im BCD-Format
//Der Wertebereich geht von DT#1990-1-1-0:0:0.0 bis DT#2089-12-31-23:59:59.999
//
//BYTE 0: Jahr (year)
//BYTE 1: Monat (month)
//BYTE 2: Tag (day)
//BYTE 3: Stunde (hour)
//BYTE 4: Minute (minute)
//BYTE 5: Sekunde (second)
//BYTE 6: 100er und 10er Stelle von Millisekunden
//BYTE 7: Bit 4..7: 1er Stelle von Millisekunden
//BYTE 7: Bit 0..3: Wochentag (1=Sonntag, 2=Montag, ..., 7=Samstag)
CALL "READ_CLK" (
RET_VAL := #iRET,
CDT := #DATE_TIME);
NOP 0;
NETWORK
TITLE =copy the system clock into a useable CLOCK-Structure
//System DateTime auf verwertbare Struktur kopieren
CALL "BLKMOV" (
SRCBLK := #DATE_TIME,
RET_VAL := #iRET,
DSTBLK := #SYSCLK_BCD);
NOP 0;
NETWORK
TITLE =remove milliseond information from weekday
//Wochtag ist nur Bit 0..3
//
//20.05.2012 S.Maag (Fehler behoben, war memSYSCLK_BCD)
L #SYSCLK_BCD.weekday;
L W#16#F;
UW ;
T #SYSCLK_BCD.weekday;
NOP 0;
NETWORK
TITLE =Event second changed
U( ;
L #SYSCLK_BCD.sec;
L #memSYSCLK_BCD.sec;
<>I ;
) ;
FP #FP_evt_sec;
= #evt_sec;
NETWORK
TITLE =Event minute changed
U( ;
L #SYSCLK_BCD.min;
L #memSYSCLK_BCD.min;
<>I ;
) ;
FP #FP_evt_min;
= #evt_min;
NETWORK
TITLE =Event hour changed
U( ;
L #SYSCLK_BCD.hour;
L #memSYSCLK_BCD.hour;
<>I ;
) ;
FP #FP_evt_hour;
= #evt_hour;
NETWORK
TITLE =Event day changed
U( ;
L #SYSCLK_BCD.day;
L #memSYSCLK_BCD.day;
<>I ;
) ;
FP #FP_evt_day;
= #evt_day;
NETWORK
TITLE =Event month changed
U( ;
L #SYSCLK_BCD.month;
L #memSYSCLK_BCD.month;
<>I ;
) ;
FP #FP_evt_month;
= #evt_month;
NETWORK
TITLE =Event year changed
//weekday:
//
//1 : sunday
//2 : monday
//3 : thuesday
//4 : wednesday
//5 : thursday
//6 : friday
//7 : saturday
U( ;
L #SYSCLK_BCD.year;
L #memSYSCLK_BCD.year;
<>I ;
) ;
FP #FP_evt_year;
= #evt_year;
NETWORK
TITLE =Select no of first weekday according to 'StartWeekOnSunMon'
//IF StartWeekOnSunMon=TRUE THEN
// FirstWeekDay = 2 // Monday
//ELSE
// FirstWeekDay = 1 // Sunday
//ENDIF
U( ;
L 1;
T #tmpFirstWeekday;
SET ;
SAVE ;
CLR ;
U BIE;
) ;
U #StartWeekOnSunMon;
SPBNB _001;
L 2;
T #tmpFirstWeekday;
_001: NOP 0;
NETWORK
TITLE =Event week changed
//Fires the WeekChange_Event on sunday or monday (at midnight)
U( ;
L #SYSCLK_BCD.weekday;
L #tmpFirstWeekday;
==I ;
) ;
U( ;
L #SYSCLK_BCD.weekday;
L #memSYSCLK_BCD.weekday;
<>I ;
) ;
FP #FP_evt_week;
= #evt_week;
NETWORK
TITLE =save the last clock state in static memory
CALL "BLKMOV" (
SRCBLK := #SYSCLK_BCD,
RET_VAL := #iRET,
DSTBLK := #memSYSCLK_BCD);
NOP 0;
NETWORK
TITLE =Transfer the single events into output byte
//ACHTUNG: indirektes kopieren der Daten von Multiinstanzen über Pointer
//ist nur mit Berücksichtigung des absoluten Instanz-Pointers möglich, da
//die P#-Funktion von Step7 den Pointer nur relativ zu den Daten der aktuelen
//Instanz ermittelt. Dieser relative Pointer muss zum Instanzpointer aus AR2
//addiert werden.
//18.10.2016 S.Maag
//Achtung: Es muss zuerst das Adressregister 2 geladen werden und von dort die
//Bereichskennung ausgeblendet: TAR2 liefert immer Bereichskennung 84 des
//Datenbausteins. P##evt_sec liefert 85 "Instanzdatenbaustein als
//Bereichskennung", was direkt die Instanzdaten adressiert.
//
TAR2 ; // load akku with instance pointer
UD DW#16#FFFFFF; // Bereichskennung (84 "DB") ausblenden
L P##evt_sec; // load relative pointer of EVENT-Outputs
+D ; // add instance and relative data pointer
LAR1 ; // load it into AR1
L B [AR1,P#0.0]; // load the 8 BOOL outputs as complete byte
T #evtFLAGs; // transfer the EVENTS into the byte 'evtFLAGs
NETWORK
TITLE =
SET ;
SAVE ;
CLR ;
END_FUNCTION_BLOCK
Wenn es um komplette Jahresarchive für Zählerablesungen z.B. Strom oder Wärmeverbräuche, dann geht das mit
dem einfachen Statistikzähler nicht.
Für die Jahresarchive ist das etwas komplexer, dafür müsste ich erst ein Demoprojekt erstellen, sonst kann man
das ohne Vorahnung nicht verwenden. Die Jahresarchive erlauben tägliche und monatliche Ablesungen zu
automatisieren und die Werte einzeln für 366 Tage und 12 Monate zu speichern. Am Jahresende dann automatisch
das archiv sichern, so dass in der CPU immer noch alle Werte vom letzten Jahr vorhanden sind.