Le DB utilizzate sono "ohDataSet", "Configurator" e "System". Già dai nomi possiamo capire lo scopo delle DB. ohDataSet è quella per la funzione LCC_ConfigDevice mentre Configurator sarà la DB utilizzata per definire le varie configurazioni delle nostre CPU, System per appoggiare gli stati della procedura. Descriviamo le strutture dati utilizzate affinchè il codice risulti più chiaro.
La DB "Configurator":
contiene la struttura dati UDT_SystemCfg che è composta di tre array di strutture dati.

vediamo ora nel dettaglio le strutture dati interne.
UDT_SlotPlc
|
|
In cui a parte l'elemento Name di tipo String(8) che ho aggiunto, ne vedremo l'utilizzo più avanti, gli elementi NumMod e BaseUnitType sono elementi necessari per il corretto funzionamento della FB LCC_ConfigDevice. Infatti sono gli stessi elementi del tipo di dato "LCC_typeSlotET200SP" della libreria LCC. NumMod : indica in quale posizione del rack della CPU si trova il modulo; BaseUnitType : consente di definire se la base è di tipo a separazione di potenziale o meno. Se valore 0 allora sarà considerato il tipo di base configurato, se valore 1 ci sarà una base che apre un nuovo potenziale. |
UDT_Device
|
|
Questa struttura dati contiene gli elementi necessari per la configurazione dei dispositivi di IO, cioè quei dispositivi che sono connessi al sistema via Profinet od altro bus di campo. Nel mio caso il valore iniziale "TASWASLU" è una stringa per identificare se esiste il dispositivo. Vero che possiamo inserire fino a 512 dispositivi di IO ma sicuramente, come è nel mio caso, saranno configurati in un numero inferiore. L'elemento più importante è "ValHwDevice" perchè è il numero che TIA portal ha assegnato al dispositivo quando lo abbiamo inserito nella configurazione hardware. |
UDT_ET200S
|
|
Questa struttura dati è inserita in vista della configurazione dei nodi di periferia ET200SP. E' da notare che questa struttura dati contiene i tipi di dati della libreria LCC, ovvero i tipi dati: - "LCC_typeHeader" - "LCC_SlotET200SP" |
Le strutture presentate sono quelle utilizzate per configurare il sistema, quelle che saranno modificate in fase di configurazione del PLC. La FB LCC_ConfigDevice però richiede un'altro tipo di dataset per il suo corretto funzionamento. E' il tipo di dato che troviamo nella Db "ohDataSet".

sarà questa struttura dati che passata alla FB LCC_ConfigDevice ci permetterà di configurare la nostra CPU. Infatti il richiamo della FB è:
"LCC_ConfigDevice_DB"(hwID := 33,
statusID => "ohDataset".ohS71500StatusID,
status => "ohDataset".ohS71500Status,
dataRec := "ohDataset".ohS71500);
dove la struttura dati "ohS71500" è stata popolata nelle righe precedenti andando a scorrere la DB "Configurator". Come è valorizzata la struttura dati della DB "Configurator":
![]() |
|
in cui i moduli dalla posizione 9 fino alla 66 saranno tutti non definiti, come è d'altronde nella configurazione hardware della CPU. Quindi se torniamo all'analisi del codice il primo ciclo FOR:
FOR #index := 1 TO 66 DO
// check how many module configured
IF "Configurator".Config.PLC_IO_Configuration.RackPlc[#index].Name <> '' THEN
#Cnt := #Cnt + 1;
END_IF;
//reset all values "ohDataset".ohS71500.slots structure data
"ohDataset".ohS71500.slots[#index].NumSlot := 0;
"ohDataset".ohS71500.slots[#index].BaseTypeSlot := 0;
END_FOR;
conta il numero di moduli che dovranno essere definiti. Il numero dei moduli ci tornerà utile per determinare la lunghezza dei blocco dati che la funzione "LCC_ConfigDevice" elaborerà. L'azzeramento della struttura dati "ohS71500" è per avere l'area pulita.
Il codice:
//set the header's value
l'header ha una lunghezza di 4 byte, i moduli occupano 2 byte ciascuno
"ohDataset".ohS71500.header.blockLength := 4 + INT_TO_USINT(#Cnt) * 2;
numero del data set, deve essere 196 "ohDataset".ohS71500.header.blockID := 196;
2 perchè è una CPU 1500SP, se fosse una CPU1500 andrà impostato a 4 "ohDataset".ohS71500.header.type := 2; //1500SP CPU
deve essere 0 "ohDataset".ohS71500.header.typeSub := 0;
prima della chiamata della funzione andiamo ad impostare la parte di configurazione dei moduli, con il secondo ciclo FOR:
//set the plc rack configuration accordingly to the DB
//fill the structure data with real module installed
FOR #index := 1 TO 66 DO
"ohDataset".ohS71500.slots[#index].NumSlot := "Configurator".Config.PLC_IO_Configuration.RackPlc[#index].NumMod;
"ohDataset".ohS71500.slots[#index].BaseTypeSlot := "Configurator".Config.PLC_IO_Configuration.RackPlc[#index].BaseUnitType;
END_FOR;
Il 66 potrebbe essere sostituito con la variabile #Cnt, funziona ugualmente ma dato che l'area è stata pulita in precedenza lo copio tutto. Quindi la chiamata della funzione LCC con il data set 196 informa la CPU della posizione dei moduli configurati in configurazione hardware.
//reset var status
"ohDataset".ohS71500StatusID := 0;
"ohDataset".ohS71500Status := 0;
//call block library for set up the configuration
"LCC_ConfigDevice_DB"(hwID := 33,
statusID => "ohDataset".ohS71500StatusID,
status => "ohDataset".ohS71500Status,
dataRec := "ohDataset".ohS71500);
IF ("ohDataset".ohS71500Status = 0) THEN
"System".Sts.LccConfigOk := TRUE;
END_IF;
Abbiamo quindi passato alla CPU come è configurata. La figura che segue sarà esplicativa.

Il modulo che in configurazione hardware avevamo messo in posizione 5 nella CPU reale si trova invece in posizione 4. Il modulo che è in posizione 4 nella configurazione hardware nella CPU reale non c'è. Se abbiamo fatto tutte le cose corrette il risultato è la CPU in RUN e senza errori hardware.
