How can you read out the date and time with SFC1 (READ_CLK) and set them with SFC0 (SET_CLK)?
You can use the system functions SFC1 (READ_CLK) and SFC0 (SET_CLK) respectively to read out and set the system clock of a CPU. The system clock is stored in a variable of the data type "DATE_AND_TIME". The data type DATE_AND_TIME occupies 8 bytes which contain the information in BCD format about the year, month, day, hour, etc. The range covered is:
- DT#1990-1-1-0:0:0.0 to DT#2089-12-31-23:59:59.999
The table below shows the occupation of the bytes in the data type DATE_AND_TIME taking an example for Thursday, January 2, 2014 3:05:11.854 AM.
|Byte 6 + 4 MSB* of Byte 7 |
|Byte 7 (4 LSB*)|
* 12 bits are required to display the maximum millisecond value range of 999 in BCD format. For this reason the millisecond content occupies Byte 6 and the 4 most significant bits (MSB) of Byte 7. The remaining 4 least significant bits (LSB) of Byte 7 are used to code the day of the week.
Access to the content of a single variable of the data type DATE_AND_TIME is made via pointer arithmetic. The procedure for this when reading out or setting the system clock is shown in the following instructions taking a sample program with 4 networks in the OB1.
Instructions for reading out the system clock with SFC1 (READ_CLK)
- Call the system function SFC1 (READ_CLK) to read out the system clock (Fig. 1).
At the output parameter "CDT" you receive the current system clock time of the CPU. Interconnect the parameter "CDT" with a temporary variable (here "readDateAndTime") of the data type DATE_AND_TIME.
- Using the instruction "LAR1 P##readDateAndTime" (pointer) you download the address of the temporary variable "readDateAndTime" into the address register AR1 (Fig. 2). Then, via indirect load commands, you access the content of the separate bytes/words of the variable "readDateAndTime" and have them displayed via the operands provided for this.
- Example for the access to Byte 3 (hour) and output via the operand "Read".Hour (here DB1.DBB3):
Because of the overlapping in Bytes 6 and 7 for milliseconds and day of the week you have to access Word 6 for access to the milliseconds and shift the content 4 bits to the right before output (SRW 4). For output of the day of the week you have to mask the Byte 7 with B#16#F in order to obtain only the 4 LSB of Byte 7.
Instructions for setting the system clock with SFC0 (SET_CLK)
- You define a temporary variable of the data type DATE_AND_TIME, "writeDateAndTime", for example, and download the address of this variable into the address register AR1 using the instruction "LAR1 P##writeDateAndTime" (Fig. 3). Downloading and transferring the data to the separate bytes for year, month, day, hour, etc. is done via indirect addressing.
- Example for transferring the hour to be set "Write".Hour (here DB2.DBB3) to Byte 3 (Hour) in the temporary variable "writeDateAndTime":
T B[AR1, P#3.0]
Because of the overlapping in Bytes 6 and 7 for milliseconds and day of the week, before transfer of the value to be set for the milliseconds you have shift the content of the operand (here "Write".Millisecond, DB2.DBW6) 4 bits to the left (SLW 4).
You do not need to set the day of the week because this is derived from the date set.
Call the system function SFC0 (SET_CLK) to set the system clock and provide the input parameter "PDT" with the temporary variable "writeDateAndTime" (Fig. 4). It is important that the SFC0 is called only for one single cycle, otherwise the system clock would be set again at each cycle and would therefore remain on the time set.
In the example (Fig. 4) the operand "Write".setCLK (here DB2.DBX8.0) is checked for a positive edge. In the case of a positive edge the SFC0 is called and the system clock is set to the values given in the temporary variable "writeDateAndTime".