Teemon Двумя вещами:
а) SysCom
б) Нормально написанным конечным автоматом для диммера.
Ща портировал на CDS v3.5, и при опросе 9 модулей IO всё пашет. Пока ещё тестирую.
Про планировщик, про прочее - позже будут посты. Сильно позже.
Да, запросы составляю вручную. Код примерно такой злой:
Код:
IF (bPortR1Open = TRUE) THEN
CASE iMBReqStateR1 OF
iReqR1W2Msk: //ОПРОС МОДУЛЯ W1 - Маска Входов
fbMbReqW2Msk(
bEnable:= TRUE,
hPort:= hPortR1,
pCmdBuffer:= ADR(pBuffReqReadDIMaskW2),
pCmdBufferLen:= SIZEOF(pBuffReqReadDIMaskW2),
pRcvBuffer:= ADR(bfRecieveBuffer),
pRcvBytesNeed:= wBuffAnswReadDIMaskW2,
bCheckCRC:= TRUE,
);
IF (fbMbReqW2Msk.bComplete = TRUE) THEN //Парсим данные в DWORD маски входов, если запрос завершился успешно
iMBReqStateR1 := iReqR1W2Cnt; //Идём на следующий шаг
iomW2DIMask := BYTE_TO_DWORD(bfRecieveBuffer[6]) //Входы 1-8
OR SHL(BYTE_TO_DWORD(bfRecieveBuffer[5]), 8*1) //Входы 9-16
OR SHL(BYTE_TO_DWORD(bfRecieveBuffer[4]), 8*2) //Входы 17-24
OR SHL(BYTE_TO_DWORD(bfRecieveBuffer[3]), 8*3); //Входы 25-32
END_IF
... ... ... ... ...
IF (bPortR2Open = TRUE) THEN
CASE iMBReqStateR2 OF
iReqR2W5Out: //ОПРОС МОДУЛЯ W5 - Маска выходов !!
bfSendBuffer[0] := 20; //Адрес
bfSendBuffer[1] := 16#10; //Команда
bfSendBuffer[2] := 16#00; //Старший (начальный адрес регистра)
bfSendBuffer[3] := 16#61; //Младший (начальный адрес регистра)
bfSendBuffer[4] := 16#00; //Старший (число регистров)
bfSendBuffer[5] := 16#02; //Младший (число регистров)
bfSendBuffer[6] := 4; //Число байт данных (далее)
bfSendBuffer[7] := DWORD_TO_BYTE(SHR(wBitMask32W5, 8*3)); //16#FF; //Выходы 25-32
bfSendBuffer[8] := DWORD_TO_BYTE(SHR(wBitMask32W5, 8*2)); //16#FF; //Выходы 17-24
bfSendBuffer[9] := DWORD_TO_BYTE(SHR(wBitMask32W5, 8*1));// 16#FF; //Выходы 9-16
bfSendBuffer[10]:= DWORD_TO_BYTE(SHR(wBitMask32W5, 8*0));// 16#FF; //Выходы 1-8
CSMBAddBuffCRC(ADR(bfSendBuffer), SIZEOF(bfSendBuffer), 11);
fbMbReqW5(
bEnable:= TRUE,
hPort:= hPortR2,
pCmdBuffer:= ADR(bfSendBuffer),
pCmdBufferLen:= 13,
pRcvBuffer:= ADR(bfRecieveBuffer),
pRcvBytesNeed:= wBuffAnswWriteDOMaskW5,
bCheckCRC:= TRUE,
);
IF (fbMbReqW5.bComplete = TRUE) THEN
iMBReqStateR2 := iReqR2W6Out;
END_IF