-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathFbDriverRTC.SCL
More file actions
206 lines (172 loc) · 6.39 KB
/
Copy pathFbDriverRTC.SCL
File metadata and controls
206 lines (172 loc) · 6.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
FUNCTION_BLOCK "FbDriverRTC"
TITLE = 'Áëîê ÷òåíèÿ ÷àñîâ ðåàëüíîãî âðåìåíè.'
{ S7_read_back := 'true' ;
S7_blockview := 'big' }
AUTHOR : VA
FAMILY : LIB_PLC
VERSION : '3.2'
VAR_INPUT // Âõîäíûå ïåðåìåííûå, ñîõðàíÿåìûå.
Reset :BOOL := FALSE; // Ñáðîñ ïðè ïåðåçàãðóçêå.
END_VAR
VAR_OUTPUT // Âûõîäíûå ïåðåìåííûå, ñîõðàíÿåìûå.
Year :INT := 0 ; // Òåêóùåå âðåìÿ- Ãîä 20xx.
Month :INT := 0 ; // Òåêóùåå âðåìÿ- Ìåñÿö 1...12.
Day :INT := 0 ; // Òåêóùåå âðåìÿ- Äåíü 1...31.
Hour :INT := 0 ; // Òåêóùåå âðåìÿ- ×àñ 0...23.
Minute :INT := 0 ; // Òåêóùåå âðåìÿ- Ìèíóòà 0...59.
Second :INT := 0 ; // Òåêóùåå âðåìÿ- Ñåêóíäà 0...59.
Millisecond :INT := 0 ; // Òåêóùåå âðåìÿ- Ìèëëèñåêóíäû 0...999.
Weekday :INT := 0 ; // Òåêóùåå âðåìÿ- Äåíü íåäåëè 1...7.
Ts_ms :DINT := 0 ; // Øàã äèñêðåòèçàöèè ïî âðåìåíè [ìñ].
Ts :REAL := 0.0 ; // Øàã äèñêðåòèçàöèè ïî âðåìåíè [ñ].
Ts_max :DINT := 0 ; // Ìàêñèìàëüíîå âðåìÿ ñêàíà [ìñ].
Blink1s :BOOL := FALSE; // Ìîðãàíèå 500ms ON + 500ms OFF.
END_VAR
VAR // Âíóòðåííèå ïåðåìåííûå, ñîõðàíÿåìûå.
// Ïåðåìåííûå äëÿ ÷àñîâ ðåàëüíîãî âðåìåíè.
DateAndTime:DATE_AND_TIME:=DT#1999-12-31-23:59:59.999; // Äàòà è âðåìÿ 64áèò.
StructDateAndTime AT DateAndTime: STRUCT // Ïðåäñòàâèòü 64 áèò DATE_AND_TIME êàê âîñåìü BYTE
ArrayByte:ARRAY[0..7] OF BYTE; // Ìàññèâ èç 8 áàéò.
// ArrayByte[0] Ãîä â ôîðìàòå BCD.
// ArrayByte[1] Ìåñÿö â ôîðìàòå BCD.
// ArrayByte[2] Äåíü â ôîðìàòå BCD.
// ArrayByte[3] ×àñ â ôîðìàòå BCD.
// ArrayByte[4] Ìèíóòà â ôîðìàòå BCD.
// ArrayByte[5] Ñåêóíäà â ôîðìàòå BCD.
// ArrayByte[6] Ìèëèñåêóíäà â ôîðìàòå BCD.
// ArrayByte[7] Ìèëèñåêóíäû è äåíü íåäåëè â ôîðìàòå BCD.
END_STRUCT;
Time_ms_previous :DINT := 0; // RTC ïðåäèäóùåå çíà÷åíèå 0...59999ms.
END_VAR
VAR_TEMP // Âðåìåííûå ïåðåìåííûå, íå ñîõðàíÿåìûå.
ErrorCode :INT ; // Êîä îøèêè SFC äîëæåí áûòü 0.
TmpBYTE :BYTE; // Âðåìåííàÿ ïåðåìåííàÿ.
ms_x10 :BYTE; // Âðåìåííàÿ ïåðåìåííàÿ 1.
ms_x100 :BYTE; // Âðåìåííàÿ ïåðåìåííàÿ 2.
ms_x1 :BYTE; // Âðåìåííàÿ ïåðåìåííàÿ 3.
Time_ms_current :DINT; // RTC 0...59999ms.
END_VAR
BEGIN
// Áëîê ÷òåíèÿ ÷àñîâ ðåàëüíîãî âðåìåíè.
// DbDriverRTC
// +-----------------+
// | FbDriverRTC |
// ->-|Reset Year|->-
// | Month|->-
// | Day|->-
// | Hour|->-
// | Minutes|->-
// | Seconds|->-
// | Millisecond|->-
// | Weekday|->-
// | Ts_ms|->-
// | Ts|->-
// | Ts_max|->-
// | Blink1s|->-
// +-----------------+
// ×òåíèå RTC.
ErrorCode := READ_CLK(CDT:=DateAndTime); // SFC1();
IF (ErrorCode = 0) THEN
// Ðàñøèôðîâêà BCD ôîðìàòà âðåìåíè- ãîä.
Year := 2000 + BCD_TO_INT(StructDateAndTime.ArrayByte[0]);
// Ðàñøèôðîâêà BCD ôîðìàòà âðåìåíè- ìåñÿö.
Month := BCD_TO_INT(StructDateAndTime.ArrayByte[1]);
// Ðàñøèôðîâêà BCD ôîðìàòà âðåìåíè- äåíü.
Day := BCD_TO_INT(StructDateAndTime.ArrayByte[2]);
// Ðàñøèôðîâêà BCD ôîðìàòà âðåìåíè- ÷àñ.
Hour := BCD_TO_INT(StructDateAndTime.ArrayByte[3]);
// Ðàñøèôðîâêà BCD ôîðìàòà âðåìåíè- ìèíóòà.
Minute := BCD_TO_INT(StructDateAndTime.ArrayByte[4]);
// Ðàñøèôðîâêà BCD ôîðìàòà âðåìåíè- ñåêóíäà.
Second := BCD_TO_INT(StructDateAndTime.ArrayByte[5]);
// Ðàñøèôðîâêà BCD ôîðìàòà âðåìåíè- ìèëëèñåêóíäà.
ms_x10 := StructDateAndTime.ArrayByte[6] AND 2#0000_1111; // ms x10
ms_x100 := ROR(IN:=StructDateAndTime.ArrayByte[6] AND 2#1111_0000,N:=4); // ms x100
ms_x1 := ROR(IN:=StructDateAndTime.ArrayByte[7] AND 2#1111_0000,N:=4); // ms x1
Millisecond := BYTE_TO_INT(ms_x100)*100 + BYTE_TO_INT(ms_x10)*10 + BYTE_TO_INT(ms_x1);
// Ðàñøèôðîâêà BCD ôîðìàòà âðåìåíè- äåíü íåäåëè.
Weekday := BYTE_TO_INT(StructDateAndTime.ArrayByte[7] AND 2#0000_1111);
ELSE
Year := 0;
Month := 0;
Day := 0;
Hour := 0;
Minute := 0;
Second := 0;
Millisecond := 0;
Weekday := 0;
END_IF;
//--------------------------------------------------------------------------------------------
// Ìîðãàíèå 500ms ON + 500ms OFF.
Blink1s := Millisecond <= 499;
//--------------------------------------------------------------------------------------------
// Ðàñ÷åò âðåìåíè ñêàíà ÏËÊ ñ òî÷êè çðåíèÿ RTC.
// Ìîæåò áûòü ïîëåçíà äëÿ OB1 â S7-1200 è äëÿ OB1 â CFC PCS7.
// RTC 0...59999ms
Time_ms_current := (INT_TO_DINT(Second) * 1000) + INT_TO_DINT(Millisecond);
// Èíèöèàëèçèðóåì âðåìÿ ïðè ïåðåçàãðóçêå.
IF (Reset) THEN
Time_ms_previous := Time_ms_current;
END_IF;
// Ðàçíîñòü âðåìåíè ñ ó÷åòîì ïåðåïîëíåíèÿ.
IF (Time_ms_current >= Time_ms_previous) THEN
Ts_ms := Time_ms_current - Time_ms_previous;
// Ts_ms = 7 - 2 = 5 ms
// 0
// 1
// 2 <- Time_ms_previous
// 3
// 4
// 5
// 6
// 7 <- Time_ms_current
// 8
// 9
ELSE
Ts_ms := (60000 - Time_ms_previous) + Time_ms_current;
// Ts_ms = (60000 - 59997) + 2 = 5 ms
// 59995
// 59996
// 59997 <- Time_ms_previous
// 59998
// 59999
// 0
// 1
// 2 <- Time_ms_current
// 3
// 4
END_IF;
// Çàïîìíèòü ïðåäèäóùåå âðåìÿ.
Time_ms_previous := Time_ms_current;
// Âðåìÿ ñêàíà íå ìîæåò áûòü áîëüøå 1000ms
// Çàùèòà íà ñëó÷àé åñëè ÏËÊ ïåðåâåäóò â ñòîï íà äëèòåëüíîå âðåìÿ.
// Çàùèòà îò âíåçàïíîé êîððåêòèðîâêè âðåìåíè RTC.
// Çàùèòà îò íåâåðíûõ âõîäíûõ äàííûõ.
IF ((Ts_ms >= 1000) OR (Ts_ms < 0)) THEN
Ts_ms := 0;
END_IF;
// Øàã äèñêðåòèçàöèè ïî âðåìåíè [ñ].
Ts := DINT_TO_REAL(Ts_ms) * 0.001;
//--------------------------------------------------------------------------------------------
// Ìàêñèìàëüíîå âðåìÿ ñêàíà [ìñ].
IF (Ts_ms >= Ts_max) THEN
Ts_max := Ts_ms;
END_IF;
IF (Reset) THEN
Ts_max := 0;
END_IF;
//--------------------------------------------------------------------------------------------
// @COPYLEFT ALL WRONGS RESERVED :)
// Author: VA
// Contacts: DIY.PLC.314@gmail.com
// Date start LIB_PLC: 2014
// License: GNU GPL-2.0-or-later
// https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
// https://www.youtube.com/watch?v=n1F_MfLRlX0
// https://www.youtube.com/@DIY_PLC
// https://github.com/DIYPLC/LIB_PLC
// https://oshwlab.com/diy.plc.314/PLC_HW1_SW1
// https://3dtoday.ru/3d-models/mechanical-parts/body/korpus-na-din-reiku
// https://t.me/DIY_PLC
// https://drive.google.com/drive/folders/16GDX0i07rwDrl_oPzL-lQAqMiAz3ouJV?usp=sharing
END_FUNCTION_BLOCK