Указатель на локальные данные FB (pointer to local data)?
Указатель на локальные данные FB (pointer to local data)?
Внутри FB вызываю SFC15 для которой необходим параметр RECORD.
Если подставить что то типа P#DB30.DBX0.0 BYTE 8, то всё работает.
Но мне нужно сформировать такой же указатель на локальные (temp) расположеные внутри самой FB. Попытка подставить что то типа p##LW0.DBX0.0 BYTE 8 не проходит.
Возможна ли вообще такой указатель, и если да то как правильно его написать?
Под temp переменными находятся WORD к которым происходит обращение и формирование внутри FB
Если подставить что то типа P#DB30.DBX0.0 BYTE 8, то всё работает.
Но мне нужно сформировать такой же указатель на локальные (temp) расположеные внутри самой FB. Попытка подставить что то типа p##LW0.DBX0.0 BYTE 8 не проходит.
Возможна ли вообще такой указатель, и если да то как правильно его написать?
Под temp переменными находятся WORD к которым происходит обращение и формирование внутри FB
ПРИМЕРНО ТАК
Code: Select all
FUNCTION_BLOCK FB 1
TITLE =
AUTHOR : Alex
FAMILY :
NAME :
VERSION : 0.1
VAR_INPUT
SL_LIST : BLOCK_DB ;
END_VAR
VAR_IN_OUT
Ret_Val_R_W : INT ;
Time_Delay_Interrupt : WORD ;
END_VAR
VAR
read_byte1 : BYTE ;
read_byte2 : BYTE ;
read_word : WORD ;
read_dword : DWORD ;
write_byte1 : BYTE ;
write_byte2 : BYTE ;
write_word : WORD ;
write_dword : DWORD ;
INIT_DBNR : WORD ;
tmp_ret_val : WORD ;
SL_DBNR : WORD ;
Init_Index : BYTE ;
END_VAR
BEGIN
NETWORK
TITLE =
CALL SFC 14 (
LADDR := DBW 6,
RET_VAL := #Ret_Val_R_W,
RECORD := P#DIX 6.0 BYTE 8);
CALL SFC 15 (
LADDR := DBW 6,
RECORD := P#DIX 14.0 BYTE 8,
RET_VAL := #Ret_Val_R_W);
К сожалению радость оказалась преждевременной :(
Синтаксис действительно понимает, но данные в temp переменных не правильные какие то.
Для проверки использую точно такую же FB, но с прямым указанием DB.
А с использованием экземплярного DB и его локальных переменных получаю какую то чушь: если SFC15 хотя бы RET VAL = 0, то SFC 14 выдает RET VAL = -31965 !?
И локальные переменные содержат какую то чушь.
Подскажите, в чём может быть проблема?
Синтаксис действительно понимает, но данные в temp переменных не правильные какие то.
Для проверки использую точно такую же FB, но с прямым указанием DB.
А с использованием экземплярного DB и его локальных переменных получаю какую то чушь: если SFC15 хотя бы RET VAL = 0, то SFC 14 выдает RET VAL = -31965 !?
И локальные переменные содержат какую то чушь.
Code: Select all
VAR_INPUT
Address : WORD ; //Profibus адрес устройства
Parameter_number : WORD ; //Номер параметра 0000-3900
Index : WORD ; //Индекс в параметре 0-255
END_VAR
VAR_OUTPUT
Parameter_value : DWORD ; //Принятое значение параметра
END_VAR
VAR_TEMP
wr_pkw_word_1_Address : WORD ; //Адрес:0-10 PNU адрес (0-7CF), 11=0, 12-15 AK = 0001 (чтение параметра). Запрос.
wr_pkw_word_2_Index : WORD ; //Индекс:0-6 спецефичные для СМ411,7-страница, 8-15 индекс в адресе. Запрос.
wr_pkw_word_3_Hi : WORD ; //Значение параметра Hi. Запрос.
wr_pkw_word_4_Low : WORD ; //Значение параметра Low. Запрос.
pzd_word_1_cw_setpoint : WORD ; //PZD1. Котрольное слово + значение частоты. Копия управление в режиме РРО3
pzd_word_2_sw_act_value : WORD ; //PZD2. Слово сотояния + текущее значение частоты. Копия управление в режиме РРО3
rd_pkw_word_1_Address1 : WORD ; //Адрес:0-10 PNU адрес (0-7CF), 11=0, 12-15 AK = 0001 (чтение параметра). Чтение.
rd_pkw_word_2_Index1 : WORD ; //Индекс: 0-6 спецефичные для СМ411,7-страница, 8-15 индекс в адресе. Чтение.
rd_pkw_word_3_Hi1 : WORD ; //Значение параметра Hi. Чтение.
rd_pkw_word_4_Low1 : WORD ; //Значение параметра Low. Чтение.
ret_val_1 : INT ;
ret_val_2 : INT ;
pkw_WAIT_1 : BOOL ; //Бит ожидания окончания работы с PKW
END_VAR
BEGIN
NETWORK
TITLE =Формирование индекса и адреса запроса PKW
L #Index;
SLW 8; // сдвиг влево на 8 битов
T #wr_pkw_word_2_Index; // сохранение индекса
L #Parameter_number; // номер параметра, диапазон 0-3900, в 16-ом виде!
L W#16#7D0; // для номеров больше 2000 надо отнять 2000 и установить бит номеров больше 2000
>=I ;
JCN v199; // номер меньше 2000
-I ; // иначе вычитаем из номера 2000
S L 3.7; // устанавливаем бит номеров больше 2000
JU v200; // номер больше 2000
v199: L #Parameter_number;
v200: OW W#16#1000; // установить флаг запроса
T #wr_pkw_word_1_Address;
L 0;
T #wr_pkw_word_3_Hi;
T #wr_pkw_word_4_Low;
NETWORK
TITLE =Запрос PKW
CALL "DPWR_DAT" (
LADDR := #Address,
RECORD := P#DIX 0.0 BYTE 8,
RET_VAL := #ret_val_1);
NOP 0;
NETWORK
TITLE =
A #pkw_WAIT_1;
JC rd1;
S #pkw_WAIT_1;
NETWORK
TITLE =Чтение PKW
rd1: CALL "DPRD_DAT" (
LADDR := #Address,
RET_VAL := #ret_val_2,
RECORD := P#DIX 12.0 BYTE 8);
NOP 0;
NETWORK
TITLE =Проверка полученого ответа на запрос
//Сравниваются адреса запроса и ответа на их совпадение.
L #rd_pkw_word_1_Address1; // чтение адреса ответа
AW W#16#FFF; // накладываем маску
L #wr_pkw_word_1_Address; // чтение адреса запроса
AW W#16#FFF; // накладываем маску
==I ; // проверяем соответствие адресов запроса и ответа, иначе это ответ на другой запрос
JCN ex1; // ждём ответа на данный запрос
R #pkw_WAIT_1; // сброс флага ожидания ответа
ex1: NOP 0;
L #wr_pkw_word_1_Address;
L #wr_pkw_word_2_Index;
L #wr_pkw_word_3_Hi;
L #wr_pkw_word_4_Low;
L #pzd_word_1_cw_setpoint;
L #pzd_word_2_sw_act_value;
L #rd_pkw_word_1_Address1;
L #rd_pkw_word_2_Index1;
L #rd_pkw_word_3_Hi1;
L #rd_pkw_word_4_Low1;
T #Parameter_value;
L #ret_val_2;
END_FUNCTION_BLOCK
Re: Указатель на локальные данные FB (pointer to local data)
В принципе, можно использовать локальные данные при вызове другого блока. Для этого есть тип данных V. Конешно от p##VW0.DBX0.0 BYTE 8 симатика вытошнит, но можно создать локальную переменную типа ANY в которую ручками записать нужные цифры. Можно написать P#L 0.0 BYTE 8, но при вызове другого блока симатик втупую передаст этот указатель и другой блок будет искать эти данные в своем локальном стеке (вот не знаю как SFC, а FC и FB точно) и наверно не найдет. Поэтому указатель P#L 0.0 BYTE 8 можно использовать только внутри текущего блока, а если есть желание передать указатель в вызываемый блок, то его нужно формировать ручками т.к. P#V 0.0 BYTE 8 симатик не понимает.Terand wrote:Внутри FB вызываю SFC15 для которой необходим параметр RECORD.
Если подставить что то типа P#DB30.DBX0.0 BYTE 8, то всё работает.
Но мне нужно сформировать такой же указатель на локальные (temp) расположеные внутри самой FB. Попытка подставить что то типа p##LW0.DBX0.0 BYTE 8 не проходит.
Возможна ли вообще такой указатель, и если да то как правильно его написать?
Под temp переменными находятся WORD к которым происходит обращение и формирование внутри FB
-
- Posts: 109
- Joined: Thu Oct 19, 2006 7:00 am
- Location: Russia
В STL обеспечивается полный доступ ко всем ресурсам, формированию указателей и т.д.
А, например, релейная логика (имею ввиду булевы функции) гораздо лучше читается в FBD или LAD.
По мне, если не работать с массивами (без которых можно обойтись чаще всего), никаких преимуществ SCL не дает..Наиболее удобным считаю сочетание диаграмм и STL
А, например, релейная логика (имею ввиду булевы функции) гораздо лучше читается в FBD или LAD.
По мне, если не работать с массивами (без которых можно обойтись чаще всего), никаких преимуществ SCL не дает..Наиболее удобным считаю сочетание диаграмм и STL