source: trunk/fw_g473rct/SES/src/outputs.c@ 38

Last change on this file since 38 was 38, checked in by f.jahn, 7 weeks ago
File size: 15.7 KB
Line 
1/******************************************************************************
2*
3* @file outputs.c
4* @author ECS, Falko Jahn
5* @version V1.0.0
6* @date 2020-05-01
7* @brief
8*
9******************************************************************************/
10
11//--- INCLUDES -----------------------------------------------------------------
12#include "outputs.h"
13#include "main.h"
14#include "stdio.h"
15#include "sysdata.h"
16//--- EXTERNE VARIABLEN --------------------------------------------------------
17
18//--- LOKALE DEFINES - bitte hier dokumentieren --------------------------------
19
20//--- LOKALE TYPE DEFS - bitte hier dokumentieren-------------------------------
21
22//--- DEFINITIONEN GLOBALER VARIABLEN - Bitte in Header dokumentieren ----------
23
24//--- LOKALE VARIABLEN - bitte hier dokumentieren ------------------------------
25
26//--- LOKALE FUNKTIONS PROTOTYPEN ----------------------------------------------
27/*
28* @brief Heizungssteuerung
29* @param kein
30* @retval kein
31*/
32void AuxModeHeaterExec(void);
33
34
35//--- LOKALE FUNKTIONEN - bitte hier dokumentieren -----------------------------
36
37
38
39// --- GLOBALE FUNKTIONEN - bitte in Header dokumentieren------------------------
40void OUTPUTS_Init(void)
41{
42 sys_data.s.values.lvpState = OUTPUTS_LVP_UNKNOWN;
43 sys_data.s.values.ovpState = OUTPUTS_OVP_UNKNOWN;
44
45}
46
47/*
48* @brief Prüfen ob LVP Signal abgeschaltet werden muss
49* LVP Signal kommt vom BMS und schaltet die Lasten ab. Wird hier auch abgeschaltet wenn der Laststrom zu hoch ist,
50* oder wenn die Geräte Temperatur zu hoch oder zu niedrig ist.
51* @param kein
52* @retval kein
53*/
54void OUTPUTS_CheckLVP(void)
55{
56 static uint16_t lastMode;
57
58 if (sys_data.s.parameter.lvpMode == OUTPUTS_LVP_MODE_AUTO)
59 {
60 if (lastMode != OUTPUTS_LVP_MODE_AUTO)
61 {
62 sys_data.s.values.lvpState = OUTPUTS_LVP_UNKNOWN;
63 }
64
65 if ((sys_data.s.values.lvpState == OUTPUTS_LVP_OK) || (sys_data.s.values.lvpState == OUTPUTS_LVP_UNKNOWN))
66 {
67 if(sys_data.s.values.batteryVoltage < sys_data.s.parameter.lvpStart)
68 {
69 printf("OUTPUTS_LVP_BATTERY_UNDERVOLTAGE\n");
70 sys_data.s.values.lvpState = OUTPUTS_LVP_BATTERY_UNDERVOLTAGE;
71 HAL_GPIO_WritePin(DISCHARGE_ENABLE_GPIO_Port, DISCHARGE_ENABLE_Pin, OUTPUTS_DISCHARGE_NOT_ALLOWED);
72 }
73 else if(sys_data.s.values.batteryCurrent < ((int32_t)sys_data.s.parameter.loadCurrentLimit*1000))
74 {
75 printf("OUTPUTS_LVP_OVERCURRENT\n");
76 sys_data.s.values.lvpState = OUTPUTS_LVP_OVERCURRENT;
77 HAL_GPIO_WritePin(DISCHARGE_ENABLE_GPIO_Port, DISCHARGE_ENABLE_Pin, OUTPUTS_DISCHARGE_NOT_ALLOWED);
78 }
79 else if(sys_data.s.values.shuntTemperature > sys_data.s.parameter.dischargeStopHighTemperatureStart)
80 {
81 printf("OUTPUTS_LVP_SHUNT_OVERTEMPERATURE\n");
82 sys_data.s.values.lvpState = OUTPUTS_LVP_SHUNT_OVERTEMPERATURE;
83 HAL_GPIO_WritePin(DISCHARGE_ENABLE_GPIO_Port, DISCHARGE_ENABLE_Pin, OUTPUTS_DISCHARGE_NOT_ALLOWED);
84 }
85 else if(sys_data.s.values.chipTemperature > sys_data.s.parameter.dischargeStopHighTemperatureStart)
86 {
87 printf("OUTPUTS_LVP_CHIP_OVERTEMPERATURE\n");
88 sys_data.s.values.lvpState = OUTPUTS_LVP_CHIP_OVERTEMPERATURE;
89 HAL_GPIO_WritePin(DISCHARGE_ENABLE_GPIO_Port, DISCHARGE_ENABLE_Pin, OUTPUTS_DISCHARGE_NOT_ALLOWED);
90 }
91 else if(sys_data.s.values.shuntTemperature < sys_data.s.parameter.dischargeStopLowTemperatureStart)
92 {
93 printf("OUTPUTS_LVP_SHUNT_UNDERTEMPERATURE\n");
94 sys_data.s.values.lvpState = OUTPUTS_LVP_SHUNT_UNDERTEMPERATURE;
95 HAL_GPIO_WritePin(DISCHARGE_ENABLE_GPIO_Port, DISCHARGE_ENABLE_Pin, OUTPUTS_DISCHARGE_NOT_ALLOWED);
96 }
97 else if(sys_data.s.values.chipTemperature < sys_data.s.parameter.dischargeStopLowTemperatureStart)
98 {
99 printf("OUTPUTS_LVP_CHIP_OVERTEMPERATURE\n");
100 sys_data.s.values.lvpState = OUTPUTS_LVP_CHIP_UNDERTEMPERATURE;
101 HAL_GPIO_WritePin(DISCHARGE_ENABLE_GPIO_Port, DISCHARGE_ENABLE_Pin, OUTPUTS_DISCHARGE_NOT_ALLOWED);
102 }
103 }
104
105 if ((sys_data.s.values.lvpState != OUTPUTS_LVP_OK) &&
106 (sys_data.s.values.batteryVoltage > sys_data.s.parameter.lvpStop) &&
107 (sys_data.s.values.batteryCurrent > ((int32_t)sys_data.s.parameter.loadCurrentLimit * 1000)) &&
108 (sys_data.s.values.shuntTemperature < sys_data.s.parameter.dischargeStopHighTemperatureStop) &&
109 (sys_data.s.values.chipTemperature < sys_data.s.parameter.dischargeStopHighTemperatureStop) &&
110 (sys_data.s.values.shuntTemperature > sys_data.s.parameter.dischargeStopLowTemperatureStop) &&
111 (sys_data.s.values.chipTemperature > sys_data.s.parameter.dischargeStopLowTemperatureStop))
112 {
113 //Abschaltkriterien für LVP liegen nicht mehr vor
114 //Wenn Abschaltung aufgrund zu hohem Lade/Lastrom erfolgt ist, muss Fehler durch Geräte Reset zurück gesetzt werden
115 //Andere Fehler automatisches Reset, wenn Fehler nicht mehr vorliegt.
116 //Kunde könnte automatische Reset verhindern, indem er die Stop Werte anders programmiert
117 //z.B.
118 //Temperabschaltung Start 80°C
119 //Temperaturabschaltung Stop -99°C
120 if ((sys_data.s.values.lvpState != OUTPUTS_LVP_OVERCURRENT) && (sys_data.s.values.lvpState != OUTPUTS_LVP_SHORT_PROTECTION))
121 {
122 //Andere Fehler, automatisches zurücksetzen, wenn keine Fehlerbedingungen mehr vorliegen
123 printf("OUTPUT LVP OK\n");
124 sys_data.s.values.lvpState = OUTPUTS_LVP_OK;
125 HAL_GPIO_WritePin(DISCHARGE_ENABLE_GPIO_Port, DISCHARGE_ENABLE_Pin, OUTPUTS_DISCHARGE_ALLOWED);
126 }
127 }
128 }
129 else if (sys_data.s.parameter.lvpMode == OUTPUTS_LVP_MODE_MANUAL_ON)
130 {
131 HAL_GPIO_WritePin(DISCHARGE_ENABLE_GPIO_Port, DISCHARGE_ENABLE_Pin, OUTPUTS_DISCHARGE_ALLOWED);
132 }
133 else if (sys_data.s.parameter.lvpMode == OUTPUTS_LVP_MODE_MANUAL_OFF)
134 {
135 HAL_GPIO_WritePin(DISCHARGE_ENABLE_GPIO_Port, DISCHARGE_ENABLE_Pin, OUTPUTS_DISCHARGE_NOT_ALLOWED);
136 }
137 else HAL_GPIO_WritePin(DISCHARGE_ENABLE_GPIO_Port, DISCHARGE_ENABLE_Pin, OUTPUTS_DISCHARGE_NOT_ALLOWED);
138
139 lastMode = sys_data.s.parameter.lvpMode;
140}
141
142/*
143* @brief Prüfen ob OVP Signal abgeschaltet werden muss
144* OVP Signal kommt vom BMS und schaltet die Ladequellen ab. Wird hier auch abgeschaltet wenn der Ladestrom zu hoch ist,
145* oder wenn die Geräte Temperatur zu hoch oder zu niedrig ist.
146* @param kein
147* @retval kein
148*/
149void OUTPUTS_CheckOVP(void)
150{
151 static uint16_t lastMode;
152
153 if (sys_data.s.parameter.ovpMode == OUTPUTS_OVP_MODE_AUTO)
154 {
155 if (lastMode != OUTPUTS_OVP_MODE_AUTO)
156 {
157 sys_data.s.values.ovpState = OUTPUTS_OVP_UNKNOWN;
158 }
159
160 if ((sys_data.s.values.ovpState == OUTPUTS_OVP_OK) || (sys_data.s.values.ovpState == OUTPUTS_OVP_UNKNOWN))
161 {
162 if(sys_data.s.values.batteryVoltage > sys_data.s.parameter.ovpStart)
163 {
164 printf("OUTPUTS_OVP_BATTERY_OVERVOLTAGE\n");
165 sys_data.s.values.ovpState = OUTPUTS_OVP_BATTERY_OVERVOLTAGE;
166 HAL_GPIO_WritePin(CHARGE_ENABLE_GPIO_Port, CHARGE_ENABLE_Pin, OUTPUTS_CHARGE_NOT_ALLOWED);
167 }
168 else if(sys_data.s.values.batteryCurrent > ((int32_t) sys_data.s.parameter.chargeCurrentLimit * 1000))
169 {
170 printf("OUTPUTS_OVP_OVERCURRENT\n");
171 sys_data.s.values.ovpState = OUTPUTS_OVP_OVERCURRENT;
172 HAL_GPIO_WritePin(CHARGE_ENABLE_GPIO_Port, CHARGE_ENABLE_Pin, OUTPUTS_CHARGE_NOT_ALLOWED);
173 }
174 else if(sys_data.s.values.shuntTemperature > sys_data.s.parameter.chargeStopHighTemperatureStart)
175 {
176 printf("OUTPUTS_OVP_SHUNT_OVERTEMPERATURE\n");
177 sys_data.s.values.ovpState = OUTPUTS_OVP_SHUNT_OVERTEMPERATURE;
178 HAL_GPIO_WritePin(CHARGE_ENABLE_GPIO_Port, CHARGE_ENABLE_Pin, OUTPUTS_CHARGE_NOT_ALLOWED);
179 }
180 else if(sys_data.s.values.chipTemperature > sys_data.s.parameter.chargeStopHighTemperatureStart)
181 {
182 printf("OUTPUTS_OVP_CHIP_OVERTEMPERATURE\n");
183 sys_data.s.values.ovpState = OUTPUTS_OVP_CHIP_OVERTEMPERATURE;
184 HAL_GPIO_WritePin(CHARGE_ENABLE_GPIO_Port, CHARGE_ENABLE_Pin, OUTPUTS_CHARGE_NOT_ALLOWED);
185 }
186 else if(sys_data.s.values.shuntTemperature < sys_data.s.parameter.chargeStopLowTemperatureStart)
187 {
188 printf("OUTPUTS_OVP_SHUNT_UNDERTEMPERATURE\n");
189 sys_data.s.values.ovpState = OUTPUTS_OVP_SHUNT_UNDERTEMPERATURE;
190 HAL_GPIO_WritePin(CHARGE_ENABLE_GPIO_Port, CHARGE_ENABLE_Pin, OUTPUTS_CHARGE_NOT_ALLOWED);
191 }
192 else if(sys_data.s.values.chipTemperature < sys_data.s.parameter.chargeStopLowTemperatureStart)
193 {
194 printf("OUTPUTS_OVP_CHIP_UNDETEMPERATURE\n");
195 sys_data.s.values.ovpState = OUTPUTS_OVP_CHIP_UNDERTEMPERATURE;
196 HAL_GPIO_WritePin(CHARGE_ENABLE_GPIO_Port, CHARGE_ENABLE_Pin, OUTPUTS_CHARGE_NOT_ALLOWED);
197 }
198 }
199
200 if ((sys_data.s.values.ovpState != OUTPUTS_OVP_OK) &&
201 (sys_data.s.values.batteryVoltage < sys_data.s.parameter.ovpStop) &&
202 (sys_data.s.values.batteryCurrent < ( (int32_t) sys_data.s.parameter.chargeCurrentLimit*1000)) &&
203 (sys_data.s.values.shuntTemperature < sys_data.s.parameter.chargeStopHighTemperatureStop) &&
204 (sys_data.s.values.chipTemperature < sys_data.s.parameter.chargeStopHighTemperatureStop) &&
205 (sys_data.s.values.shuntTemperature > sys_data.s.parameter.chargeStopLowTemperatureStop) &&
206 (sys_data.s.values.chipTemperature > sys_data.s.parameter.chargeStopLowTemperatureStop))
207 {
208 //Abschaltkriterien für OVP liegen nicht mehr vor
209 //Wenn Abschaltung aufgrund zu hohem Lade/Lastrom erfolgt ist, dann muss Rücksetzen durch Reset Button erfolgen
210 //Andere Fehler, automatisches zurücksetzen, wenn keine Fehlerbedingungen mehr vorliegen
211 if ((sys_data.s.values.ovpState != OUTPUTS_OVP_OVERCURRENT) && (sys_data.s.values.ovpState != OUTPUTS_OVP_SHORT_PROTECTION) )
212 {
213 printf("OUTPUT OVP OK\n");
214 sys_data.s.values.ovpState = OUTPUTS_OVP_OK;
215 HAL_GPIO_WritePin(CHARGE_ENABLE_GPIO_Port, CHARGE_ENABLE_Pin, OUTPUTS_CHARGE_ALLOWED);
216 }
217 }
218 }
219 else if (sys_data.s.parameter.ovpMode == OUTPUTS_OVP_MODE_MANUAL_ON)
220 {
221 HAL_GPIO_WritePin(CHARGE_ENABLE_GPIO_Port, CHARGE_ENABLE_Pin, OUTPUTS_CHARGE_ALLOWED);
222 }
223 else if (sys_data.s.parameter.ovpMode == OUTPUTS_OVP_MODE_MANUAL_OFF)
224 {
225 HAL_GPIO_WritePin(CHARGE_ENABLE_GPIO_Port, CHARGE_ENABLE_Pin, OUTPUTS_CHARGE_NOT_ALLOWED);
226 }
227 else HAL_GPIO_WritePin(CHARGE_ENABLE_GPIO_Port, CHARGE_ENABLE_Pin, OUTPUTS_CHARGE_NOT_ALLOWED);
228
229 lastMode = sys_data.s.parameter.ovpMode;
230}
231
232
233
234#define LVP_DETECTION_LEVEL 6000 //< 6 V
235#define CHARGE_DETECT_HYSTERESE 10
236
237void AuxModeHeaterExec(void)
238{
239 static int outputState=0;
240
241 int offv = sys_data.s.parameter.auxOutputSetpointOn - CHARGE_DETECT_HYSTERESE;
242 int onv = sys_data.s.parameter.auxOutputSetpointOn + CHARGE_DETECT_HYSTERESE;
243
244 if ((sys_data.s.values.shuntVoltage > onv) && (sys_data.s.values.ovp_sense < LVP_DETECTION_LEVEL) && (outputState == 0))
245 {
246 printf("Heater on\r\n");
247 outputState = 1;
248 if (sys_data.s.parameter.auxOutputInverted == 0)
249 {
250 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_SET);
251 }
252 else
253 {
254 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_RESET);
255 }
256
257 }
258
259 //Ausschalten
260 //Wenn Spannung am Shunt < setpoint (ladegeräteerkennung 14,8V?) und Entladung
261 //Oder wenn OVP wieder da ist
262 //sys_data.s.values.batteryCurrent < sys_data.s.parameter.auxOutputSetpointOff
263
264 if ((sys_data.s.values.shuntVoltage < offv ) || (sys_data.s.values.ovp_sense > LVP_DETECTION_LEVEL))
265 {
266 if (outputState == 1)
267 {
268 printf("Heater off\r\n");
269 outputState = 0;
270 if (sys_data.s.parameter.auxOutputInverted == 0)
271 {
272 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_RESET);
273 }
274 else
275 {
276 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_SET);
277 }
278 }
279 }
280}
281
282void AuxModeSOCExec(void)
283{
284 static int outputState=0;
285
286
287 if ((sys_data.s.values.soc > (sys_data.s.parameter.auxOutputSetpointOn*1000)) && (outputState == 0))
288 {
289 printf("AUX on (SOC Mode)\r\n");
290 outputState = 1;
291 if (sys_data.s.parameter.auxOutputInverted == 0)
292 {
293 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_SET);
294 }
295 else
296 {
297 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_RESET);
298 }
299
300 }
301
302
303 if ((sys_data.s.values.soc < (sys_data.s.parameter.auxOutputSetpointOff*1000)) && (outputState == 1))
304 {
305 printf("AUX off (SOC Mode)\r\n");
306 outputState = 0;
307 if (sys_data.s.parameter.auxOutputInverted == 0)
308 {
309 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_RESET);
310 }
311 else
312 {
313 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_SET);
314 }
315 }
316
317
318}
319
320
321 int16_t loadCurrentLimit; // 30 maximaler Laststrom in A wenn der Strom grer ist als der eingestelle Wert dann wird die Laststrom Protection aktiv, darf nicht unsigned sein, da Entladestrom mit Minus angegeben [A] Default -500 A
322 int16_t chargeCurrentLimit; // 31 maximaler Ladestrom in A wenn der Strom grer ist als der eingestelle Wert dann wird die Ladestrom Protection aktiv [A] Default:500A
323
324
325 int16_t chargeStopHighTemperatureStart; // 32 Abschalttemperatur Ladung wegen zu hoher Temperatur [C * 100]
326 int16_t chargeStopHighTemperatureStop; // 33 Wiedereinschalttemperatur [C * 100]
327
328 int16_t chargeStopLowTemperatureStart; // 34 Abschalttemperatur Ladung wegen zu niedriger Temperatur [C * 100]
329 int16_t chargeStopLowTemperatureStop; // 35 Wiedereinschalttemperatur [C * 100]
330
331 int16_t dischargeStopHighTemperatureStart; // 36 Abschalttemperatur Entladung wegen zu hoher Temperatur [C * 100]
332 int16_t dischargeStopHighTemperatureStop; // 37 Wiedereinschalttemperatur[C * 100]
333
334 int16_t dischargeStopLowTemperatureStart; // 38 Abschalttemperatur EntLadung wegen zu niedriger Temperatur
335 int16_t dischargeStopLowTemperatureStop; // 39 Wiedereinschalttemperatur
336
337
338
339void AuxModeAlarmExec(void)
340{
341 static int outputState=0;
342
343
344 if (
345 (sys_data.s.values.shuntTemperature > (chargeStopHighTemperatureStart - 500)) ||
346 (sys_data.s.values.chipTemperature > (chargeStopHighTemperatureStart - 500)) ||
347 (sys_data.s.values.shuntTemperature < (chargeStopLowTemperatureStart + 500)) ||
348 (sys_data.s.values.chipTemperature < (chargeStopLowTemperatureStart + 500)) ||
349 (sys_data.s.values.shuntTemperature > (dischargeStopHighTemperatureStart - 500)) ||
350 (sys_data.s.values.chipTemperature > (dischargeStopHighTemperatureStart - 500)) ||
351 (sys_data.s.values.shuntTemperature < (dischargeStopLowTemperatureStart + 500)) ||
352 (sys_data.s.values.chipTemperature < (dischargeStopLowTemperatureStart + 500)) ||
353 (sys_data.s.values.batteryCurrent > ((chargeCurrentLimit*1000LL) - 10000)) ||
354 (sys_data.s.values.batteryCurrent < ((loadCurrentLimit*1000LL) + 10000))
355
356 )
357 {
358 if ( outputState == 0)
359 {
360 printf("AUX on (Alarm Mode)\r\n");
361 outputState = 1;
362 if (sys_data.s.parameter.auxOutputInverted == 0)
363 {
364 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_SET);
365 }
366 else
367 {
368 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_RESET);
369 }
370 }
371 }
372 else // Alles OK
373 {
374 if ( outputState == 0)
375 {
376 printf("AUX off (Alarm Mode)\r\n");
377 outputState = 0;
378 if (sys_data.s.parameter.auxOutputInverted == 0)
379 {
380 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_RESET);
381 }
382 else
383 {
384 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_SET);
385 }
386 }
387 }
388}
389
390
391void OUTPUTS_CheckAUX(void)
392{
393
394 switch (sys_data.s.parameter.auxOutputMode)
395 {
396 case AUX_MODE_OFF:
397 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_RESET);
398 break;
399
400 case AUX_MODE_HEATER:
401 AuxModeHeaterExec();
402 break;
403
404 case AUX_MODE_SOC:
405 AuxModeSOCExec();
406 break;
407
408 case AUX_MODE_ALARM:
409 AuxModeAlarmExec();
410 break;
411
412
413 default:
414 HAL_GPIO_WritePin(AUX_EN_GPIO_Port, AUX_EN_Pin, GPIO_PIN_RESET);
415 break;
416
417
418 }
419
420
421}
422
423/*************************** End of file ****************************/
Note: See TracBrowser for help on using the repository browser.