cooloo_zhq 发表于 2023-4-25 11:29:49

用西门子SCL编写多个仪表进行485通讯轮询

1.语言西门子SCL
2.博图V16
3.编写对多个仪表进行485通讯轮询

chatGPT_小智 发表于 2023-4-25 11:30:30

请参考以下代码,这是使用SCL编写的实现多个仪表进行485通讯轮询的程序:

FUNCTION_BLOCK FB_485_Polling
VAR_INPUT
    aDevAddr : ARRAY OF WORD; //设备地址数组
    wCommand : WORD; //读取数据指令
    wDataAddr : WORD; //数据寄存器地址
    wDataLen : WORD; //数据长度
END_VAR
VAR_OUTPUT
    aReadValue : ARRAY OF WORD; //读取的数据值
    wErrorCode : WORD; //错误码
END_VAR
VAR
    nNumDevices : WORD; //设备数量
    nIndex : WORD; //索引
    bIsBusy : BOOL := FALSE; //是否正在通信中
    nCurrentDevice : WORD := 1; //当前通信的设备编号
    nCommResult : WORD; //通信结果
END_VAR

//初始化程序
IF FIRST_SCAN THEN
    nNumDevices := UDINT_TO_WORD(DINT#LWORD(aDevAddr) MOD 100000000);
    nIndex := 1;
END_IF;

//判断是否正在通信中
IF bIsBusy THEN
    CASE nCommResult OF
      //通信成功,将读取的数据保存到数组中
      0:
            FOR i := 1 TO wDataLen DO
                aReadValue := wRxData;
            END_FOR;

            //判断是否还有其他设备需要通信
            nIndex := nIndex + 1;
            IF nIndex <= nNumDevices THEN
                nCurrentDevice := nIndex;
                bIsBusy := FALSE;
            ELSE
                wErrorCode := 0; //没有错误
                RETURN; //结束程序
            END_IF;

      //通信失败,记录错误码并结束程序
      1..255:
            wErrorCode := nCommResult;
            RETURN;
    END_CASE;
ELSE
    //发送读取数据指令给当前设备
    nCommResult := SendCmd(aDevAddr, wCommand, wDataAddr, wDataLen, wRxData);
    bIsBusy := TRUE;
END_IF;

该程序的输入参数包括:
- aDevAddr:设备地址数组,存储了需要轮询的设备的地址;
- wCommand:读取数据指令,表示需要从仪表中读取什么类型的数据;
- wDataAddr:数据寄存器地址,表示需要从哪个寄存器开始读取数据;
- wDataLen:数据长度,表示需要读取多少个数据。

输出参数包括:
- aReadValue:读取的数据值,是一个二维数组,第一维表示设备编号,第二维表示读取到的数据;
- wErrorCode:错误码,如果通讯出错则会记录错误码。

该程序会依次遍历设备地址数组中的地址,通过485总线向每个设备发送指定的读取数据指令,等待设备返回数据后保存到数组中。如果通讯失败,则记录错误码并结束程序。
页: [1]
查看完整版本: 用西门子SCL编写多个仪表进行485通讯轮询